on master help sign in
feat: highlight / select symbol under cursor using LSP textDocument/documentHighlight (#2738)

* feat: highlight symbol under cursor using LSP textDocument/documentHighlight * fix: please clippy * fix: shorter description and code style

commit096abdd19bb422cba607d43d05b195b37a7f95e9 authorlazytanuki <43273245+lazytanuki@users.noreply.github.com> dateMon 27 Jun 2022, 13:19 (4 years ago) parentfde9e03
4 files changed+65
helix-lsp/src/client.rs+20 helix-term/src/commands.rs+1 helix-term/src/commands/lsp.rs+43 helix-term/src/keymap/default.rs+1
helix-lsp/src/client.rs+20
@@ -759,6 +759,26 @@ impl Client {
759759 Ok(response.unwrap_or_default())
760760 }
761761
762+ pub fn text_document_document_highlight(
763+ &self,
764+ text_document: lsp::TextDocumentIdentifier,
765+ position: lsp::Position,
766+ work_done_token: Option<lsp::ProgressToken>,
767+ ) -> impl Future<Output = Result<Value>> {
768+ let params = lsp::DocumentHighlightParams {
769+ text_document_position_params: lsp::TextDocumentPositionParams {
770+ text_document,
771+ position,
772+ },
773+ work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },
774+ partial_result_params: lsp::PartialResultParams {
775+ partial_result_token: None,
776+ },
777+ };
778+
779+ self.call::<lsp::request::DocumentHighlightRequest>(params)
780+ }
781+
762782 fn goto_request<
763783 T: lsp::request::Request<
764784 Params = lsp::GotoDefinitionParams,
helix-term/src/commands.rs+1
@@ -263,6 +263,7 @@ impl MappableCommand {
263263 code_action, "Perform code action",
264264 buffer_picker, "Open buffer picker",
265265 symbol_picker, "Open symbol picker",
266+ select_references_to_symbol_under_cursor, "Select symbol references",
266267 workspace_symbol_picker, "Open workspace symbol picker",
267268 last_picker, "Open last picker",
268269 prepend_to_line, "Insert at start of line",
helix-term/src/commands/lsp.rs+43
@@ -655,6 +655,7 @@ pub fn signature_help(cx: &mut Context) {
655655 },
656656 );
657657}
658+
658659pub fn hover(cx: &mut Context) {
659660 let (view, doc) = current!(cx.editor);
660661 let language_server = language_server!(cx.editor, doc);
@@ -704,6 +705,7 @@ pub fn hover(cx: &mut Context) {
704705 },
705706 );
706707}
708+
707709pub fn rename_symbol(cx: &mut Context) {
708710 ui::prompt(
709711 cx,
@@ -729,3 +731,44 @@ pub fn rename_symbol(cx: &mut Context) {
729731 },
730732 );
731733}
734+
735+pub fn select_references_to_symbol_under_cursor(cx: &mut Context) {
736+ let (view, doc) = current!(cx.editor);
737+ let language_server = language_server!(cx.editor, doc);
738+ let offset_encoding = language_server.offset_encoding();
739+
740+ let pos = doc.position(view.id, offset_encoding);
741+
742+ let future = language_server.text_document_document_highlight(doc.identifier(), pos, None);
743+
744+ cx.callback(
745+ future,
746+ move |editor, _compositor, response: Option<Vec<lsp::DocumentHighlight>>| {
747+ let document_highlights = match response {
748+ Some(highlights) if !highlights.is_empty() => highlights,
749+ _ => return,
750+ };
751+ let (view, doc) = current!(editor);
752+ let language_server = language_server!(editor, doc);
753+ let offset_encoding = language_server.offset_encoding();
754+ let text = doc.text();
755+ let pos = doc.selection(view.id).primary().head;
756+
757+ // We must find the range that contains our primary cursor to prevent our primary cursor to move
758+ let mut primary_index = 0;
759+ let ranges = document_highlights
760+ .iter()
761+ .filter_map(|highlight| lsp_range_to_range(text, highlight.range, offset_encoding))
762+ .enumerate()
763+ .map(|(i, range)| {
764+ if range.contains(pos) {
765+ primary_index = i;
766+ }
767+ range
768+ })
769+ .collect();
770+ let selection = Selection::new(ranges, primary_index);
771+ doc.set_selection(view.id, selection);
772+ },
773+ );
774+}
helix-term/src/keymap/default.rs+1
@@ -259,6 +259,7 @@ pub fn default() -> HashMap<Mode, Keymap> {
259259 "/" => global_search,
260260 "k" => hover,
261261 "r" => rename_symbol,
262+ "h" => select_references_to_symbol_under_cursor,
262263 "?" => command_palette,
263264 },
264265 "z" => { "View"