From 6ea4184fd107e5cc155b95a3cf058200c38d544d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 20 Aug 2019 18:53:59 +0300 Subject: translate \n -> \r\n on the way out --- crates/ra_lsp_server/src/conv.rs | 30 ++++++++++++++++---------- crates/ra_lsp_server/src/main_loop/handlers.rs | 6 ++++-- crates/ra_lsp_server/src/world.rs | 6 +++++- crates/ra_lsp_server/tests/heavy_tests/main.rs | 10 ++++----- 4 files changed, 33 insertions(+), 19 deletions(-) (limited to 'crates/ra_lsp_server') 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::{ }; use ra_syntax::{SyntaxKind, TextRange, TextUnit}; use ra_text_edit::{AtomTextEdit, TextEdit}; +use ra_vfs::LineEndings; use crate::{req, world::WorldSnapshot, Result}; @@ -88,10 +89,10 @@ impl Conv for Severity { } } -impl ConvWith<&'_ LineIndex> for CompletionItem { +impl ConvWith<(&'_ LineIndex, LineEndings)> for CompletionItem { type Output = ::lsp_types::CompletionItem; - fn conv_with(self, ctx: &LineIndex) -> ::lsp_types::CompletionItem { + fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> ::lsp_types::CompletionItem { let mut additional_text_edits = Vec::new(); let mut text_edit = None; // 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 { } } -impl ConvWith<&'_ LineIndex> for TextEdit { +impl ConvWith<(&'_ LineIndex, LineEndings)> for TextEdit { type Output = Vec; - fn conv_with(self, line_index: &LineIndex) -> Vec { - self.as_atoms().iter().map_conv_with(line_index).collect() + fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> Vec { + self.as_atoms().iter().map_conv_with(ctx).collect() } } -impl ConvWith<&'_ LineIndex> for &'_ AtomTextEdit { +impl ConvWith<(&'_ LineIndex, LineEndings)> for &'_ AtomTextEdit { type Output = lsp_types::TextEdit; - fn conv_with(self, line_index: &LineIndex) -> lsp_types::TextEdit { - lsp_types::TextEdit { - range: self.delete.conv_with(line_index), - new_text: self.insert.clone(), + fn conv_with( + self, + (line_index, line_endings): (&LineIndex, LineEndings), + ) -> lsp_types::TextEdit { + eprintln!("line_endings = {:?}", line_endings); + let mut new_text = self.insert.clone(); + if line_endings == LineEndings::Dos { + new_text = new_text.replace('\n', "\r\n"); } + lsp_types::TextEdit { range: self.delete.conv_with(line_index), new_text } } } @@ -352,7 +358,9 @@ impl TryConvWith for SourceFileEdit { version: None, }; let line_index = world.analysis().file_line_index(self.file_id)?; - let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect(); + let line_endings = world.file_line_endings(self.file_id); + let edits = + self.edit.as_atoms().iter().map_conv_with((&line_index, line_endings)).collect(); Ok(TextDocumentEdit { text_document, edits }) } } 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( let _p = profile("handle_on_type_formatting"); let mut position = params.text_document_position.try_conv_with(&world)?; let line_index = world.analysis().file_line_index(position.file_id)?; + let line_endings = world.file_line_endings(position.file_id); // in `ra_ide_api`, the `on_type` invariant is that // `text.char_at(position) == typed_char`. @@ -156,7 +157,7 @@ pub fn handle_on_type_formatting( // This should be a single-file edit let edit = edit.source_file_edits.pop().unwrap(); - let change: Vec = edit.edit.conv_with(&line_index); + let change: Vec = edit.edit.conv_with((&line_index, line_endings)); Ok(Some(change)) } @@ -370,8 +371,9 @@ pub fn handle_completion( Some(items) => items, }; let line_index = world.analysis().file_line_index(position.file_id)?; + let line_endings = world.file_line_endings(position.file_id); let items: Vec = - items.into_iter().map(|item| item.conv_with(&line_index)).collect(); + items.into_iter().map(|item| item.conv_with((&line_index, line_endings))).collect(); Ok(Some(items.into())) } 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; use ra_ide_api::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, }; -use ra_vfs::{RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; +use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; use relative_path::RelativePathBuf; @@ -210,6 +210,10 @@ impl WorldSnapshot { Ok(url) } + pub fn file_line_endings(&self, id: FileId) -> LineEndings { + self.vfs.read().file_line_endings(VfsFile(id.0)) + } + pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result { let base = self.vfs.read().root2path(VfsRoot(root.0)); 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; "range": { "end": { "character": 0, - "line": 6 + "line": 7 }, "start": { "character": 0, @@ -418,15 +418,15 @@ fn main() {{}} #[test] fn preserves_dos_line_endings() { let server = Project::with_fixture( - &r#" + &" //- Cargo.toml [package] -name = "foo" -version = "0.0.0" +name = \"foo\" +version = \"0.0.0\" //- src/main.rs /// Some Docs\r\nfn main() {} -"#, +", ) .server(); -- cgit v1.2.3