diff options
-rw-r--r-- | Cargo.lock | 8 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 30 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/main.rs | 10 | ||||
-rw-r--r-- | crates/test_utils/src/lib.rs | 22 |
7 files changed, 50 insertions, 33 deletions
diff --git a/Cargo.lock b/Cargo.lock index 3a6f0cc82..73e31f966 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1092,7 +1092,7 @@ dependencies = [ | |||
1092 | "ra_hir 0.1.0", | 1092 | "ra_hir 0.1.0", |
1093 | "ra_ide_api 0.1.0", | 1093 | "ra_ide_api 0.1.0", |
1094 | "ra_project_model 0.1.0", | 1094 | "ra_project_model 0.1.0", |
1095 | "ra_vfs 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1095 | "ra_vfs 0.2.6", |
1096 | "ra_vfs_glob 0.1.0", | 1096 | "ra_vfs_glob 0.1.0", |
1097 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1097 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1098 | ] | 1098 | ] |
@@ -1198,7 +1198,7 @@ dependencies = [ | |||
1198 | "ra_project_model 0.1.0", | 1198 | "ra_project_model 0.1.0", |
1199 | "ra_syntax 0.1.0", | 1199 | "ra_syntax 0.1.0", |
1200 | "ra_text_edit 0.1.0", | 1200 | "ra_text_edit 0.1.0", |
1201 | "ra_vfs 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1201 | "ra_vfs 0.2.6", |
1202 | "ra_vfs_glob 0.1.0", | 1202 | "ra_vfs_glob 0.1.0", |
1203 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1203 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1204 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1204 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1308,7 +1308,6 @@ dependencies = [ | |||
1308 | [[package]] | 1308 | [[package]] |
1309 | name = "ra_vfs" | 1309 | name = "ra_vfs" |
1310 | version = "0.2.6" | 1310 | version = "0.2.6" |
1311 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1312 | dependencies = [ | 1311 | dependencies = [ |
1313 | "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", | 1312 | "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", |
1314 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1313 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1324,7 +1323,7 @@ name = "ra_vfs_glob" | |||
1324 | version = "0.1.0" | 1323 | version = "0.1.0" |
1325 | dependencies = [ | 1324 | dependencies = [ |
1326 | "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", | 1325 | "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", |
1327 | "ra_vfs 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1326 | "ra_vfs 0.2.6", |
1328 | ] | 1327 | ] |
1329 | 1328 | ||
1330 | [[package]] | 1329 | [[package]] |
@@ -2135,7 +2134,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
2135 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" | 2134 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" |
2136 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" | 2135 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" |
2137 | "checksum ra_rustc_lexer 0.1.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6baccda91574dfadd7f8a0bc8f9f110f874b6b484289b2536d3dbf4f0d5d97bb" | 2136 | "checksum ra_rustc_lexer 0.1.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6baccda91574dfadd7f8a0bc8f9f110f874b6b484289b2536d3dbf4f0d5d97bb" |
2138 | "checksum ra_vfs 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "865bb9e0f71916f7c7527af4843a2a67d1b0789f7c91c512a6b4ded69af98249" | ||
2139 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" | 2137 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" |
2140 | "checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" | 2138 | "checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" |
2141 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" | 2139 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" |
diff --git a/Cargo.toml b/Cargo.toml index e44c9570f..849a6b90c 100644 --- a/Cargo.toml +++ b/Cargo.toml | |||
@@ -6,3 +6,4 @@ incremental = true | |||
6 | debug = 1 # only line info | 6 | debug = 1 # only line info |
7 | 7 | ||
8 | [patch.'crates-io'] | 8 | [patch.'crates-io'] |
9 | ra_vfs = { path = "../ra_vfs" } | ||
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index bbe140b7a..bd1ffd8f5 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -11,6 +11,7 @@ use ra_ide_api::{ | |||
11 | }; | 11 | }; |
12 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; | 12 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; |
13 | use ra_text_edit::{AtomTextEdit, TextEdit}; | 13 | use ra_text_edit::{AtomTextEdit, TextEdit}; |
14 | use ra_vfs::LineEndings; | ||
14 | 15 | ||
15 | use crate::{req, world::WorldSnapshot, Result}; | 16 | use crate::{req, world::WorldSnapshot, Result}; |
16 | 17 | ||
@@ -88,10 +89,10 @@ impl Conv for Severity { | |||
88 | } | 89 | } |
89 | } | 90 | } |
90 | 91 | ||
91 | impl ConvWith<&'_ LineIndex> for CompletionItem { | 92 | impl ConvWith<(&'_ LineIndex, LineEndings)> for CompletionItem { |
92 | type Output = ::lsp_types::CompletionItem; | 93 | type Output = ::lsp_types::CompletionItem; |
93 | 94 | ||
94 | fn conv_with(self, ctx: &LineIndex) -> ::lsp_types::CompletionItem { | 95 | fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> ::lsp_types::CompletionItem { |
95 | let mut additional_text_edits = Vec::new(); | 96 | let mut additional_text_edits = Vec::new(); |
96 | let mut text_edit = None; | 97 | let mut text_edit = None; |
97 | // LSP does not allow arbitrary edits in completion, so we have to do a | 98 | // LSP does not allow arbitrary edits in completion, so we have to do a |
@@ -202,22 +203,27 @@ impl Conv for ra_ide_api::FunctionSignature { | |||
202 | } | 203 | } |
203 | } | 204 | } |
204 | 205 | ||
205 | impl ConvWith<&'_ LineIndex> for TextEdit { | 206 | impl ConvWith<(&'_ LineIndex, LineEndings)> for TextEdit { |
206 | type Output = Vec<lsp_types::TextEdit>; | 207 | type Output = Vec<lsp_types::TextEdit>; |
207 | 208 | ||
208 | fn conv_with(self, line_index: &LineIndex) -> Vec<lsp_types::TextEdit> { | 209 | fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> Vec<lsp_types::TextEdit> { |
209 | self.as_atoms().iter().map_conv_with(line_index).collect() | 210 | self.as_atoms().iter().map_conv_with(ctx).collect() |
210 | } | 211 | } |
211 | } | 212 | } |
212 | 213 | ||
213 | impl ConvWith<&'_ LineIndex> for &'_ AtomTextEdit { | 214 | impl ConvWith<(&'_ LineIndex, LineEndings)> for &'_ AtomTextEdit { |
214 | type Output = lsp_types::TextEdit; | 215 | type Output = lsp_types::TextEdit; |
215 | 216 | ||
216 | fn conv_with(self, line_index: &LineIndex) -> lsp_types::TextEdit { | 217 | fn conv_with( |
217 | lsp_types::TextEdit { | 218 | self, |
218 | range: self.delete.conv_with(line_index), | 219 | (line_index, line_endings): (&LineIndex, LineEndings), |
219 | new_text: self.insert.clone(), | 220 | ) -> lsp_types::TextEdit { |
221 | eprintln!("line_endings = {:?}", line_endings); | ||
222 | let mut new_text = self.insert.clone(); | ||
223 | if line_endings == LineEndings::Dos { | ||
224 | new_text = new_text.replace('\n', "\r\n"); | ||
220 | } | 225 | } |
226 | lsp_types::TextEdit { range: self.delete.conv_with(line_index), new_text } | ||
221 | } | 227 | } |
222 | } | 228 | } |
223 | 229 | ||
@@ -352,7 +358,9 @@ impl TryConvWith for SourceFileEdit { | |||
352 | version: None, | 358 | version: None, |
353 | }; | 359 | }; |
354 | let line_index = world.analysis().file_line_index(self.file_id)?; | 360 | let line_index = world.analysis().file_line_index(self.file_id)?; |
355 | let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect(); | 361 | let line_endings = world.file_line_endings(self.file_id); |
362 | let edits = | ||
363 | self.edit.as_atoms().iter().map_conv_with((&line_index, line_endings)).collect(); | ||
356 | Ok(TextDocumentEdit { text_document, edits }) | 364 | Ok(TextDocumentEdit { text_document, edits }) |
357 | } | 365 | } |
358 | } | 366 | } |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index b465707f8..3a559e845 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -138,6 +138,7 @@ pub fn handle_on_type_formatting( | |||
138 | let _p = profile("handle_on_type_formatting"); | 138 | let _p = profile("handle_on_type_formatting"); |
139 | let mut position = params.text_document_position.try_conv_with(&world)?; | 139 | let mut position = params.text_document_position.try_conv_with(&world)?; |
140 | let line_index = world.analysis().file_line_index(position.file_id)?; | 140 | let line_index = world.analysis().file_line_index(position.file_id)?; |
141 | let line_endings = world.file_line_endings(position.file_id); | ||
141 | 142 | ||
142 | // in `ra_ide_api`, the `on_type` invariant is that | 143 | // in `ra_ide_api`, the `on_type` invariant is that |
143 | // `text.char_at(position) == typed_char`. | 144 | // `text.char_at(position) == typed_char`. |
@@ -156,7 +157,7 @@ pub fn handle_on_type_formatting( | |||
156 | // This should be a single-file edit | 157 | // This should be a single-file edit |
157 | let edit = edit.source_file_edits.pop().unwrap(); | 158 | let edit = edit.source_file_edits.pop().unwrap(); |
158 | 159 | ||
159 | let change: Vec<TextEdit> = edit.edit.conv_with(&line_index); | 160 | let change: Vec<TextEdit> = edit.edit.conv_with((&line_index, line_endings)); |
160 | Ok(Some(change)) | 161 | Ok(Some(change)) |
161 | } | 162 | } |
162 | 163 | ||
@@ -370,8 +371,9 @@ pub fn handle_completion( | |||
370 | Some(items) => items, | 371 | Some(items) => items, |
371 | }; | 372 | }; |
372 | let line_index = world.analysis().file_line_index(position.file_id)?; | 373 | let line_index = world.analysis().file_line_index(position.file_id)?; |
374 | let line_endings = world.file_line_endings(position.file_id); | ||
373 | let items: Vec<CompletionItem> = | 375 | let items: Vec<CompletionItem> = |
374 | items.into_iter().map(|item| item.conv_with(&line_index)).collect(); | 376 | items.into_iter().map(|item| item.conv_with((&line_index, line_endings))).collect(); |
375 | 377 | ||
376 | Ok(Some(items.into())) | 378 | Ok(Some(items.into())) |
377 | } | 379 | } |
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 9990ef62e..10f96812f 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -9,7 +9,7 @@ use parking_lot::RwLock; | |||
9 | use ra_ide_api::{ | 9 | use ra_ide_api::{ |
10 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, | 10 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, |
11 | }; | 11 | }; |
12 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; | 12 | use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; |
13 | use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; | 13 | use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; |
14 | use relative_path::RelativePathBuf; | 14 | use relative_path::RelativePathBuf; |
15 | 15 | ||
@@ -210,6 +210,10 @@ impl WorldSnapshot { | |||
210 | Ok(url) | 210 | Ok(url) |
211 | } | 211 | } |
212 | 212 | ||
213 | pub fn file_line_endings(&self, id: FileId) -> LineEndings { | ||
214 | self.vfs.read().file_line_endings(VfsFile(id.0)) | ||
215 | } | ||
216 | |||
213 | pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { | 217 | pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { |
214 | let base = self.vfs.read().root2path(VfsRoot(root.0)); | 218 | let base = self.vfs.read().root2path(VfsRoot(root.0)); |
215 | let path = path.to_path(base); | 219 | let path = path.to_path(base); |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index ec075a2fd..152681062 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs | |||
@@ -208,7 +208,7 @@ pub use std::collections::HashMap; | |||
208 | "range": { | 208 | "range": { |
209 | "end": { | 209 | "end": { |
210 | "character": 0, | 210 | "character": 0, |
211 | "line": 6 | 211 | "line": 7 |
212 | }, | 212 | }, |
213 | "start": { | 213 | "start": { |
214 | "character": 0, | 214 | "character": 0, |
@@ -418,15 +418,15 @@ fn main() {{}} | |||
418 | #[test] | 418 | #[test] |
419 | fn preserves_dos_line_endings() { | 419 | fn preserves_dos_line_endings() { |
420 | let server = Project::with_fixture( | 420 | let server = Project::with_fixture( |
421 | &r#" | 421 | &" |
422 | //- Cargo.toml | 422 | //- Cargo.toml |
423 | [package] | 423 | [package] |
424 | name = "foo" | 424 | name = \"foo\" |
425 | version = "0.0.0" | 425 | version = \"0.0.0\" |
426 | 426 | ||
427 | //- src/main.rs | 427 | //- src/main.rs |
428 | /// Some Docs\r\nfn main() {} | 428 | /// Some Docs\r\nfn main() {} |
429 | "#, | 429 | ", |
430 | ) | 430 | ) |
431 | .server(); | 431 | .server(); |
432 | 432 | ||
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index ea99ac062..816d01f09 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -134,21 +134,25 @@ pub fn parse_fixture(fixture: &str) -> Vec<FixtureEntry> { | |||
134 | } | 134 | } |
135 | }; | 135 | }; |
136 | }; | 136 | }; |
137 | |||
137 | let margin = fixture | 138 | let margin = fixture |
138 | .lines() | 139 | .lines() |
139 | .filter(|it| it.trim_start().starts_with("//-")) | 140 | .filter(|it| it.trim_start().starts_with("//-")) |
140 | .map(|it| it.len() - it.trim_start().len()) | 141 | .map(|it| it.len() - it.trim_start().len()) |
141 | .next() | 142 | .next() |
142 | .expect("empty fixture"); | 143 | .expect("empty fixture"); |
143 | let lines = fixture.lines().filter_map(|line| { | 144 | |
144 | if line.len() >= margin { | 145 | let lines = fixture |
145 | assert!(line[..margin].trim().is_empty()); | 146 | .split('\n') // don't use `.lines` to not drop `\r\n` |
146 | Some(&line[margin..]) | 147 | .filter_map(|line| { |
147 | } else { | 148 | if line.len() >= margin { |
148 | assert!(line.trim().is_empty()); | 149 | assert!(line[..margin].trim().is_empty()); |
149 | None | 150 | Some(&line[margin..]) |
150 | } | 151 | } else { |
151 | }); | 152 | assert!(line.trim().is_empty()); |
153 | None | ||
154 | } | ||
155 | }); | ||
152 | 156 | ||
153 | for line in lines { | 157 | for line in lines { |
154 | if line.starts_with("//-") { | 158 | if line.starts_with("//-") { |