@@ -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+}