From 2b956fd3a83313cee37ff179eae843bc88dd572a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 9 Oct 2018 16:00:20 +0300 Subject: Add on-enter handler Now, typing doc comments is much more pleasant --- crates/ra_lsp_server/src/conv.rs | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'crates/ra_lsp_server/src/conv.rs') diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 759e5e914..08a656569 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -190,9 +190,13 @@ impl TryConvWith for SourceChange { None => None, Some(pos) => { let line_index = world.analysis().file_line_index(pos.file_id); + let edits = self.source_file_edits.iter().find(|it| it.file_id == pos.file_id) + .map(|it| it.edits.as_slice()).unwrap_or(&[]); + let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); + let position = Position::new(line_col.line as u64, u32::from(line_col.col) as u64); Some(TextDocumentPositionParams { text_document: TextDocumentIdentifier::new(pos.file_id.try_conv_with(world)?), - position: pos.offset.conv_with(&line_index), + position, }) } }; @@ -207,6 +211,41 @@ impl TryConvWith for SourceChange { } } +// HACK: we should translate offset to line/column using linde_index *with edits applied*. +// A naive version of this function would be to apply `edits` to the original text, +// construct a new line index and use that, but it would be slow. +// +// Writing fast & correct version is issue #105, let's use a quick hack in the meantime +fn translate_offset_with_edit( + pre_edit_index: &LineIndex, + offset: TextUnit, + edits: &[AtomEdit], +) -> LineCol { + let fallback = pre_edit_index.line_col(offset); + let edit = match edits.first() { + None => return fallback, + Some(edit) => edit + }; + let end_offset = edit.delete.start() + TextUnit::of_str(&edit.insert); + if !(edit.delete.start() <= offset && offset <= end_offset) { + return fallback + } + let rel_offset = offset - edit.delete.start(); + let in_edit_line_col = LineIndex::new(&edit.insert).line_col(rel_offset); + let edit_line_col = pre_edit_index.line_col(edit.delete.start()); + if in_edit_line_col.line == 0 { + LineCol { + line: edit_line_col.line, + col: edit_line_col.col + in_edit_line_col.col, + } + } else { + LineCol { + line: edit_line_col.line + in_edit_line_col.line, + col: in_edit_line_col.col, + } + } +} + impl TryConvWith for SourceFileEdit { type Ctx = ServerWorld; type Output = TextDocumentEdit; -- cgit v1.2.3