translate \n -> \r\n on the way out

This commit is contained in:
Aleksey Kladov 2019-08-20 18:53:59 +03:00
parent 80a6e61446
commit 6ea4184fd1
7 changed files with 50 additions and 33 deletions

View file

@ -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<lsp_types::TextEdit>;
fn conv_with(self, line_index: &LineIndex) -> Vec<lsp_types::TextEdit> {
self.as_atoms().iter().map_conv_with(line_index).collect()
fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> Vec<lsp_types::TextEdit> {
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 })
}
}

View file

@ -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<TextEdit> = edit.edit.conv_with(&line_index);
let change: Vec<TextEdit> = 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<CompletionItem> =
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()))
}

View file

@ -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<Url> {
let base = self.vfs.read().root2path(VfsRoot(root.0));
let path = path.to_path(base);