aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/handlers/raw_string.rs2
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs42
-rw-r--r--crates/ra_assists/src/utils/insert_use.rs3
-rw-r--r--crates/ra_db/Cargo.toml2
-rw-r--r--crates/ra_hir/src/db.rs9
-rw-r--r--crates/ra_hir_expand/src/proc_macro.rs2
-rw-r--r--crates/ra_ide/src/folding_ranges.rs23
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tests.rs3
-rw-r--r--crates/ra_ide/test_data/highlighting.html5
-rw-r--r--crates/ra_ide_db/src/change.rs24
-rw-r--r--crates/ra_ide_db/src/defs.rs25
-rw-r--r--crates/rust-analyzer/src/handlers.rs5
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs40
-rw-r--r--crates/rust-analyzer/src/main_loop.rs14
14 files changed, 145 insertions, 54 deletions
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs
index 4e8a0c2db..4c797178f 100644
--- a/crates/ra_assists/src/handlers/raw_string.rs
+++ b/crates/ra_assists/src/handlers/raw_string.rs
@@ -173,7 +173,7 @@ fn test_required_hashes() {
173} 173}
174 174
175#[cfg(test)] 175#[cfg(test)]
176mod test { 176mod tests {
177 use test_utils::mark; 177 use test_utils::mark;
178 178
179 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 179 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
index 53496ede1..da0a860c5 100644
--- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -643,4 +643,46 @@ fn main() {
643 ", 643 ",
644 ); 644 );
645 } 645 }
646
647 #[test]
648 fn does_not_replace_pub_use() {
649 check_assist(
650 replace_qualified_name_with_use,
651 r"
652pub use std::fmt;
653
654impl std::io<|> for Foo {
655}
656 ",
657 r"
658use std::io;
659
660pub use std::fmt;
661
662impl io for Foo {
663}
664 ",
665 );
666 }
667
668 #[test]
669 fn does_not_replace_pub_crate_use() {
670 check_assist(
671 replace_qualified_name_with_use,
672 r"
673pub(crate) use std::fmt;
674
675impl std::io<|> for Foo {
676}
677 ",
678 r"
679use std::io;
680
681pub(crate) use std::fmt;
682
683impl io for Foo {
684}
685 ",
686 );
687 }
646} 688}
diff --git a/crates/ra_assists/src/utils/insert_use.rs b/crates/ra_assists/src/utils/insert_use.rs
index 617afe2e9..32780fceb 100644
--- a/crates/ra_assists/src/utils/insert_use.rs
+++ b/crates/ra_assists/src/utils/insert_use.rs
@@ -4,7 +4,7 @@
4 4
5use hir::{self, ModPath}; 5use hir::{self, ModPath};
6use ra_syntax::{ 6use ra_syntax::{
7 ast::{self, NameOwner}, 7 ast::{self, NameOwner, VisibilityOwner},
8 AstNode, Direction, SmolStr, 8 AstNode, Direction, SmolStr,
9 SyntaxKind::{PATH, PATH_SEGMENT}, 9 SyntaxKind::{PATH, PATH_SEGMENT},
10 SyntaxNode, T, 10 SyntaxNode, T,
@@ -378,6 +378,7 @@ fn best_action_for_target(
378 let best_action = container 378 let best_action = container
379 .children() 379 .children()
380 .filter_map(ast::Use::cast) 380 .filter_map(ast::Use::cast)
381 .filter(|u| u.visibility().is_none())
381 .filter_map(|it| it.use_tree()) 382 .filter_map(|it| it.use_tree())
382 .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target)) 383 .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target))
383 .fold(None, |best, a| match best { 384 .fold(None, |best, a| match best {
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
index 5f334d04f..fe73dc015 100644
--- a/crates/ra_db/Cargo.toml
+++ b/crates/ra_db/Cargo.toml
@@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
9doctest = false 9doctest = false
10 10
11[dependencies] 11[dependencies]
12salsa = "0.15.0" 12salsa = "0.15.2"
13rustc-hash = "1.1.0" 13rustc-hash = "1.1.0"
14 14
15ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index a2b9f3e35..07333c453 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -13,14 +13,7 @@ pub use hir_expand::db::{
13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery, 13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,
14 MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery, 14 MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery,
15}; 15};
16pub use hir_ty::db::{ 16pub use hir_ty::db::*;
17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery,
18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase,
19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, InferQueryQuery,
20 InherentImplsInCrateQuery, InternTypeParamIdQuery, ReturnTypeImplTraitsQuery, StructDatumQuery,
21 TraitDatumQuery, TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery,
22 ValueTyQuery,
23};
24 17
25#[test] 18#[test]
26fn hir_database_is_object_safe() { 19fn hir_database_is_object_safe() {
diff --git a/crates/ra_hir_expand/src/proc_macro.rs b/crates/ra_hir_expand/src/proc_macro.rs
index 04c026004..2c0ec41d2 100644
--- a/crates/ra_hir_expand/src/proc_macro.rs
+++ b/crates/ra_hir_expand/src/proc_macro.rs
@@ -101,7 +101,7 @@ fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> {
101} 101}
102 102
103#[cfg(test)] 103#[cfg(test)]
104mod test { 104mod tests {
105 use super::*; 105 use super::*;
106 use test_utils::assert_eq_text; 106 use test_utils::assert_eq_text;
107 107
diff --git a/crates/ra_ide/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs
index 903c34996..0fbc9babd 100644
--- a/crates/ra_ide/src/folding_ranges.rs
+++ b/crates/ra_ide/src/folding_ranges.rs
@@ -85,7 +85,8 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
85 COMMENT => Some(FoldKind::Comment), 85 COMMENT => Some(FoldKind::Comment),
86 USE => Some(FoldKind::Imports), 86 USE => Some(FoldKind::Imports),
87 ARG_LIST | PARAM_LIST => Some(FoldKind::ArgList), 87 ARG_LIST | PARAM_LIST => Some(FoldKind::ArgList),
88 RECORD_FIELD_LIST 88 ASSOC_ITEM_LIST
89 | RECORD_FIELD_LIST
89 | RECORD_PAT_FIELD_LIST 90 | RECORD_PAT_FIELD_LIST
90 | RECORD_EXPR_FIELD_LIST 91 | RECORD_EXPR_FIELD_LIST
91 | ITEM_LIST 92 | ITEM_LIST
@@ -337,6 +338,26 @@ fn main() <fold block>{
337 } 338 }
338 339
339 #[test] 340 #[test]
341 fn test_folds_structs() {
342 check(
343 r#"
344struct Foo <fold block>{
345}</fold>
346"#,
347 );
348 }
349
350 #[test]
351 fn test_folds_traits() {
352 check(
353 r#"
354trait Foo <fold block>{
355}</fold>
356"#,
357 );
358 }
359
360 #[test]
340 fn test_folds_macros() { 361 fn test_folds_macros() {
341 check( 362 check(
342 r#" 363 r#"
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index 87a6e2523..2deee404c 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -9,6 +9,9 @@ use crate::{mock_analysis::single_file, FileRange, TextRange};
9fn test_highlighting() { 9fn test_highlighting() {
10 check_highlighting( 10 check_highlighting(
11 r#" 11 r#"
12use inner::{self as inner_mod};
13mod inner {}
14
12#[derive(Clone, Debug)] 15#[derive(Clone, Debug)]
13struct Foo { 16struct Foo {
14 pub x: i32, 17 pub x: i32,
diff --git a/crates/ra_ide/test_data/highlighting.html b/crates/ra_ide/test_data/highlighting.html
index 345a2f023..23c25ad8c 100644
--- a/crates/ra_ide/test_data/highlighting.html
+++ b/crates/ra_ide/test_data/highlighting.html
@@ -35,7 +35,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
35 35
36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; } 36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
37</style> 37</style>
38<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span> 38<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span>
39<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span>
40
41<span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span>
39<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> 42<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span>
40 <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> 43 <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span>
41 <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> 44 <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span>
diff --git a/crates/ra_ide_db/src/change.rs b/crates/ra_ide_db/src/change.rs
index 32d9a8d1f..b13df8b85 100644
--- a/crates/ra_ide_db/src/change.rs
+++ b/crates/ra_ide_db/src/change.rs
@@ -190,11 +190,24 @@ impl RootDatabase {
190 let q: $q = Default::default(); 190 let q: $q = Default::default();
191 let name = format!("{:?} (deps)", q); 191 let name = format!("{:?} (deps)", q);
192 acc.push((name, before - after)); 192 acc.push((name, before - after));
193
194 let before = memory_usage().allocated;
195 $q.in_db(self).purge();
196 let after = memory_usage().allocated;
197 let q: $q = Default::default();
198 let name = format!("{:?} (purge)", q);
199 acc.push((name, before - after));
193 )*} 200 )*}
194 } 201 }
195 sweep_each_query![ 202 sweep_each_query![
196 // SourceDatabase 203 // SourceDatabase
197 ra_db::ParseQuery 204 ra_db::ParseQuery
205 ra_db::CrateGraphQuery
206
207 // SourceDatabaseExt
208 ra_db::FileTextQuery
209 ra_db::FileSourceRootQuery
210 ra_db::SourceRootQuery
198 ra_db::SourceRootCratesQuery 211 ra_db::SourceRootCratesQuery
199 212
200 // AstDatabase 213 // AstDatabase
@@ -242,15 +255,24 @@ impl RootDatabase {
242 hir::db::TraitImplsInCrateQuery 255 hir::db::TraitImplsInCrateQuery
243 hir::db::TraitImplsInDepsQuery 256 hir::db::TraitImplsInDepsQuery
244 hir::db::AssociatedTyDataQuery 257 hir::db::AssociatedTyDataQuery
258 hir::db::AssociatedTyDataQuery
245 hir::db::TraitDatumQuery 259 hir::db::TraitDatumQuery
246 hir::db::StructDatumQuery 260 hir::db::StructDatumQuery
247 hir::db::ImplDatumQuery 261 hir::db::ImplDatumQuery
262 hir::db::FnDefDatumQuery
263 hir::db::ReturnTypeImplTraitsQuery
264 hir::db::InternCallableDefQuery
265 hir::db::InternTypeParamIdQuery
266 hir::db::InternImplTraitIdQuery
267 hir::db::InternClosureQuery
248 hir::db::AssociatedTyValueQuery 268 hir::db::AssociatedTyValueQuery
249 hir::db::TraitSolveQuery 269 hir::db::TraitSolveQuery
250 hir::db::ReturnTypeImplTraitsQuery
251 270
252 // SymbolsDatabase 271 // SymbolsDatabase
253 crate::symbol_index::FileSymbolsQuery 272 crate::symbol_index::FileSymbolsQuery
273 crate::symbol_index::LibrarySymbolsQuery
274 crate::symbol_index::LocalRootsQuery
275 crate::symbol_index::LibraryRootsQuery
254 276
255 // LineIndexDatabase 277 // LineIndexDatabase
256 crate::LineIndexQuery 278 crate::LineIndexQuery
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 66c048714..b51000b03 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -12,7 +12,7 @@ use hir::{
12use ra_prof::profile; 12use ra_prof::profile;
13use ra_syntax::{ 13use ra_syntax::{
14 ast::{self, AstNode}, 14 ast::{self, AstNode},
15 match_ast, 15 match_ast, SyntaxNode,
16}; 16};
17 17
18use crate::RootDatabase; 18use crate::RootDatabase;
@@ -123,8 +123,27 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
123 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; 123 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?;
124 let path = use_tree.path()?; 124 let path = use_tree.path()?;
125 let path_segment = path.segment()?; 125 let path_segment = path.segment()?;
126 let name_ref = path_segment.name_ref()?; 126 let name_ref_class = path_segment
127 let name_ref_class = classify_name_ref(sema, &name_ref)?; 127 .name_ref()
128 // The rename might be from a `self` token, so fallback to the name higher
129 // in the use tree.
130 .or_else(||{
131 if path_segment.self_token().is_none() {
132 return None;
133 }
134
135 let use_tree = use_tree
136 .syntax()
137 .parent()
138 .as_ref()
139 // Skip over UseTreeList
140 .and_then(SyntaxNode::parent)
141 .and_then(ast::UseTree::cast)?;
142 let path = use_tree.path()?;
143 let path_segment = path.segment()?;
144 path_segment.name_ref()
145 })
146 .and_then(|name_ref| classify_name_ref(sema, &name_ref))?;
128 147
129 Some(NameClass::Definition(name_ref_class.definition())) 148 Some(NameClass::Definition(name_ref_class.definition()))
130 }, 149 },
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index e73b3a211..82f6de5da 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -709,11 +709,6 @@ pub(crate) fn handle_formatting(
709 } 709 }
710 }; 710 };
711 711
712 if let Ok(path) = params.text_document.uri.to_file_path() {
713 if let Some(parent) = path.parent() {
714 rustfmt.current_dir(parent);
715 }
716 }
717 let mut rustfmt = rustfmt.stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?; 712 let mut rustfmt = rustfmt.stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
718 713
719 rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?; 714 rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index d4cc9dd04..0bc3ff115 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -1,5 +1,5 @@
1//! Utilities for LSP-related boilerplate code. 1//! Utilities for LSP-related boilerplate code.
2use std::{borrow::Cow, error::Error, ops::Range}; 2use std::{error::Error, ops::Range};
3 3
4use lsp_server::Notification; 4use lsp_server::Notification;
5use ra_db::Canceled; 5use ra_db::Canceled;
@@ -84,8 +84,8 @@ impl GlobalState {
84pub(crate) fn apply_document_changes( 84pub(crate) fn apply_document_changes(
85 old_text: &mut String, 85 old_text: &mut String,
86 content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>, 86 content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>,
87 mut line_index: Cow<'_, LineIndex>,
88) { 87) {
88 let mut line_index = LineIndex::new(old_text);
89 // The changes we got must be applied sequentially, but can cross lines so we 89 // The changes we got must be applied sequentially, but can cross lines so we
90 // have to keep our line index updated. 90 // have to keep our line index updated.
91 // Some clients (e.g. Code) sort the ranges in reverse. As an optimization, we 91 // Some clients (e.g. Code) sort the ranges in reverse. As an optimization, we
@@ -110,7 +110,7 @@ pub(crate) fn apply_document_changes(
110 match change.range { 110 match change.range {
111 Some(range) => { 111 Some(range) => {
112 if !index_valid.covers(range.end.line) { 112 if !index_valid.covers(range.end.line) {
113 line_index = Cow::Owned(LineIndex::new(old_text)); 113 line_index = LineIndex::new(&old_text);
114 } 114 }
115 index_valid = IndexValid::UpToLineExclusive(range.start.line); 115 index_valid = IndexValid::UpToLineExclusive(range.start.line);
116 let range = from_proto::text_range(&line_index, range); 116 let range = from_proto::text_range(&line_index, range);
@@ -145,15 +145,10 @@ mod tests {
145 }; 145 };
146 } 146 }
147 147
148 fn run(text: &mut String, changes: Vec<TextDocumentContentChangeEvent>) {
149 let line_index = Cow::Owned(LineIndex::new(&text));
150 super::apply_document_changes(text, changes, line_index);
151 }
152
153 let mut text = String::new(); 148 let mut text = String::new();
154 run(&mut text, vec![]); 149 apply_document_changes(&mut text, vec![]);
155 assert_eq!(text, ""); 150 assert_eq!(text, "");
156 run( 151 apply_document_changes(
157 &mut text, 152 &mut text,
158 vec![TextDocumentContentChangeEvent { 153 vec![TextDocumentContentChangeEvent {
159 range: None, 154 range: None,
@@ -162,36 +157,39 @@ mod tests {
162 }], 157 }],
163 ); 158 );
164 assert_eq!(text, "the"); 159 assert_eq!(text, "the");
165 run(&mut text, c![0, 3; 0, 3 => " quick"]); 160 apply_document_changes(&mut text, c![0, 3; 0, 3 => " quick"]);
166 assert_eq!(text, "the quick"); 161 assert_eq!(text, "the quick");
167 run(&mut text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]); 162 apply_document_changes(&mut text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]);
168 assert_eq!(text, "quick foxes"); 163 assert_eq!(text, "quick foxes");
169 run(&mut text, c![0, 11; 0, 11 => "\ndream"]); 164 apply_document_changes(&mut text, c![0, 11; 0, 11 => "\ndream"]);
170 assert_eq!(text, "quick foxes\ndream"); 165 assert_eq!(text, "quick foxes\ndream");
171 run(&mut text, c![1, 0; 1, 0 => "have "]); 166 apply_document_changes(&mut text, c![1, 0; 1, 0 => "have "]);
172 assert_eq!(text, "quick foxes\nhave dream"); 167 assert_eq!(text, "quick foxes\nhave dream");
173 run(&mut text, c![0, 0; 0, 0 => "the ", 1, 4; 1, 4 => " quiet", 1, 16; 1, 16 => "s\n"]); 168 apply_document_changes(
169 &mut text,
170 c![0, 0; 0, 0 => "the ", 1, 4; 1, 4 => " quiet", 1, 16; 1, 16 => "s\n"],
171 );
174 assert_eq!(text, "the quick foxes\nhave quiet dreams\n"); 172 assert_eq!(text, "the quick foxes\nhave quiet dreams\n");
175 run(&mut text, c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"]); 173 apply_document_changes(&mut text, c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"]);
176 assert_eq!(text, "the quick foxes\n\nhave quiet dreams\n\n"); 174 assert_eq!(text, "the quick foxes\n\nhave quiet dreams\n\n");
177 run( 175 apply_document_changes(
178 &mut text, 176 &mut text,
179 c![1, 0; 1, 0 => "DREAM", 2, 0; 2, 0 => "they ", 3, 0; 3, 0 => "DON'T THEY?"], 177 c![1, 0; 1, 0 => "DREAM", 2, 0; 2, 0 => "they ", 3, 0; 3, 0 => "DON'T THEY?"],
180 ); 178 );
181 assert_eq!(text, "the quick foxes\nDREAM\nthey have quiet dreams\nDON'T THEY?\n"); 179 assert_eq!(text, "the quick foxes\nDREAM\nthey have quiet dreams\nDON'T THEY?\n");
182 run(&mut text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]); 180 apply_document_changes(&mut text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]);
183 assert_eq!(text, "the quick \nthey have quiet dreams\n"); 181 assert_eq!(text, "the quick \nthey have quiet dreams\n");
184 182
185 text = String::from("❤️"); 183 text = String::from("❤️");
186 run(&mut text, c![0, 0; 0, 0 => "a"]); 184 apply_document_changes(&mut text, c![0, 0; 0, 0 => "a"]);
187 assert_eq!(text, "a❤️"); 185 assert_eq!(text, "a❤️");
188 186
189 text = String::from("a\nb"); 187 text = String::from("a\nb");
190 run(&mut text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]); 188 apply_document_changes(&mut text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]);
191 assert_eq!(text, "adcb"); 189 assert_eq!(text, "adcb");
192 190
193 text = String::from("a\nb"); 191 text = String::from("a\nb");
194 run(&mut text, c![0, 1; 1, 0 => "ț\nc", 0, 2; 0, 2 => "c"]); 192 apply_document_changes(&mut text, c![0, 1; 1, 0 => "ț\nc", 0, 2; 0, 2 => "c"]);
195 assert_eq!(text, "ațc\ncb"); 193 assert_eq!(text, "ațc\ncb");
196 } 194 }
197} 195}
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 0ace4cb45..51626fcd5 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -1,14 +1,13 @@
1//! The main loop of `rust-analyzer` responsible for dispatching LSP 1//! The main loop of `rust-analyzer` responsible for dispatching LSP
2//! requests/replies and notifications back to the client. 2//! requests/replies and notifications back to the client.
3use std::{ 3use std::{
4 borrow::Cow,
5 env, fmt, panic, 4 env, fmt, panic,
6 time::{Duration, Instant}, 5 time::{Duration, Instant},
7}; 6};
8 7
9use crossbeam_channel::{select, Receiver}; 8use crossbeam_channel::{select, Receiver};
10use lsp_server::{Connection, Notification, Request, Response}; 9use lsp_server::{Connection, Notification, Request, Response};
11use lsp_types::{notification::Notification as _, DidChangeTextDocumentParams}; 10use lsp_types::notification::Notification as _;
12use ra_db::VfsPath; 11use ra_db::VfsPath;
13use ra_ide::{Canceled, FileId}; 12use ra_ide::{Canceled, FileId};
14use ra_prof::profile; 13use ra_prof::profile;
@@ -422,20 +421,15 @@ impl GlobalState {
422 })? 421 })?
423 .on::<lsp_types::notification::DidChangeTextDocument>(|this, params| { 422 .on::<lsp_types::notification::DidChangeTextDocument>(|this, params| {
424 if let Ok(path) = from_proto::vfs_path(&params.text_document.uri) { 423 if let Ok(path) = from_proto::vfs_path(&params.text_document.uri) {
425 let DidChangeTextDocumentParams { text_document, content_changes } = params; 424 let doc = this.mem_docs.get_mut(&path).unwrap();
426 let vfs = &mut this.vfs.write().0; 425 let vfs = &mut this.vfs.write().0;
427 let world = this.snapshot();
428 let file_id = vfs.file_id(&path).unwrap(); 426 let file_id = vfs.file_id(&path).unwrap();
429
430 // let file_id = vfs.file_id(&path).unwrap();
431 let mut text = String::from_utf8(vfs.file_contents(file_id).to_vec()).unwrap(); 427 let mut text = String::from_utf8(vfs.file_contents(file_id).to_vec()).unwrap();
432 let line_index = world.analysis.file_line_index(file_id)?; 428 apply_document_changes(&mut text, params.content_changes);
433 apply_document_changes(&mut text, content_changes, Cow::Borrowed(&line_index));
434 429
435 // The version passed in DidChangeTextDocument is the version after all edits are applied 430 // The version passed in DidChangeTextDocument is the version after all edits are applied
436 // so we should apply it before the vfs is notified. 431 // so we should apply it before the vfs is notified.
437 let doc = this.mem_docs.get_mut(&path).unwrap(); 432 doc.version = params.text_document.version;
438 doc.version = text_document.version;
439 433
440 vfs.set_file_contents(path.clone(), Some(text.into_bytes())); 434 vfs.set_file_contents(path.clone(), Some(text.into_bytes()));
441 } 435 }