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 +++++++++++++++++++++++++- crates/ra_lsp_server/src/main_loop/handlers.rs | 14 +++++++++ crates/ra_lsp_server/src/main_loop/mod.rs | 1 + crates/ra_lsp_server/src/req.rs | 8 +++++ 4 files changed, 63 insertions(+), 1 deletion(-) (limited to 'crates/ra_lsp_server/src') 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; diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 79a54183e..725036cc7 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -77,6 +77,20 @@ pub fn handle_join_lines( .try_conv_with(&world) } +pub fn handle_on_enter( + world: ServerWorld, + params: req::TextDocumentPositionParams, + _token: JobToken, +) -> Result> { + let file_id = params.text_document.try_conv_with(&world)?; + let line_index = world.analysis().file_line_index(file_id); + let offset = params.position.conv_with(&line_index); + match world.analysis().on_enter(file_id, offset) { + None => Ok(None), + Some(edit) => Ok(Some(edit.try_conv_with(&world)?)) + } +} + pub fn handle_on_type_formatting( world: ServerWorld, params: req::DocumentOnTypeFormattingParams, diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs index 47a9b202e..53c6f1dff 100644 --- a/crates/ra_lsp_server/src/main_loop/mod.rs +++ b/crates/ra_lsp_server/src/main_loop/mod.rs @@ -244,6 +244,7 @@ fn on_request( .on::(handlers::handle_extend_selection)? .on::(handlers::handle_find_matching_brace)? .on::(handlers::handle_join_lines)? + .on::(handlers::handle_on_enter)? .on::(handlers::handle_on_type_formatting)? .on::(handlers::handle_document_symbol)? .on::(handlers::handle_workspace_symbol)? diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs index 4af61dbbd..458c79ea9 100644 --- a/crates/ra_lsp_server/src/req.rs +++ b/crates/ra_lsp_server/src/req.rs @@ -119,6 +119,14 @@ pub struct JoinLinesParams { pub range: Range, } +pub enum OnEnter {} + +impl Request for OnEnter { + type Params = TextDocumentPositionParams; + type Result = Option; + const METHOD: &'static str = "m/onEnter"; +} + pub enum Runnables {} impl Request for Runnables { -- cgit v1.2.3