LSP
LSP copied to clipboard
Click the header line in references panel to goto definition
In the output panel of references of a symbol, double-clicking on a line of reference jumps to the corresponding location of the reference. I have a request that if we double-click on the first line, let SublimeText jump to the definition of that symbol.

Hello,
Currently LSP exposes a couple of ways to go to definition. (through keybinding and context menu) I do not see a huge benefit in adding one new way of doing it.
The issue with your suggestion is that it is not obvious that clicking the first line in the reference panel would go to definition of that symbol.
Why does the current way of going to definition doesn't work for your workflow?
Have you considered mapping ctrl+click to go to definition?
https://lsp.sublimetext.io/customization/#mouse-map-configuration
I think, in the output panel, clicking on some rows will jump to the corresponding reference of a symbol, if we can also jump to the definition of that symbol by the same way, it will be smoother. @predragnikolic
I think, in the output panel, clicking on some rows will jump to the corresponding reference of a symbol, if we can also jump to the definition of that symbol by the same way, it will be smoother. @predragnikolic
VSC does the same thing.
I wouldn't use it personally, because I use the "show_references_in_quick_panel" option, but I don't think the idea is too bad.
Here is a possible implementation - it doesn't work correctly in all cases, because it uses Sublime's symbol_locations() to lookup the symbol's definition. So in case there are multiple symbols with the same name and multiple locations, for example from different classes, then it just picks the first one, which might not be the correct one. If this feature should be added properly, a better implementation could store the original symbol location (e.g. in panel.settings()) and then use that to run an additional textDocument/definition request when you double click the header line in the references panel.
diff --git a/Syntaxes/References.sublime-syntax b/Syntaxes/References.sublime-syntax
index 4c54678..7819317 100644
--- a/Syntaxes/References.sublime-syntax
+++ b/Syntaxes/References.sublime-syntax
@@ -7,9 +7,16 @@ scope: output.lsp.references
contexts:
main:
+ - include: references-header
- include: references-preamble
- include: references-body
+ references-header:
+ - match: ^\d+\sreferences\sfor\s\'([^\s']+)\'$
+ scope: meta.reference.header.lsp
+ captures:
+ 1: markup.underline.link.lsp
+
references-preamble:
- match: ^(\S.*)(:)$
scope: meta.reference.preamble.lsp
diff --git a/boot.py b/boot.py
index 3b59c43..681f019 100644
--- a/boot.py
+++ b/boot.py
@@ -234,6 +234,18 @@ class Listener(sublime_plugin.EventListener):
tup[1](None)
break
+ def on_post_text_command(self, view: sublime.View, command_name: str, args: Optional[Dict[str, Any]]) -> None:
+ if command_name == "drag_select" and args is not None and args.get("by") == "words":
+ pt = view.sel()[0].a
+ if view.match_selector(pt, "output.lsp.references meta.reference.header markup.underline.link"):
+ window = view.window()
+ if window:
+ symbol_name = view.substr(view.word(pt))
+ locations = window.symbol_locations(symbol_name, sublime.SYMBOL_SOURCE_ANY, sublime.SYMBOL_TYPE_DEFINITION)
+ if locations:
+ file = "{}:{}:{}".format(locations[0].path, locations[0].row, locations[0].col)
+ window.open_file(file, sublime.ENCODED_POSITION)
+
def on_post_window_command(self, window: sublime.Window, command_name: str, args: Optional[Dict[str, Any]]) -> None:
if command_name in ("next_result", "prev_result"):
view = window.active_view()
diff --git a/plugin/core/panels.py b/plugin/core/panels.py
index 242a727..c99a1b5 100644
--- a/plugin/core/panels.py
+++ b/plugin/core/panels.py
@@ -104,7 +104,7 @@ def create_panel(window: sublime.Window, name: str, result_file_regex: str, resu
panel.assign_syntax(syntax)
# Call create_output_panel a second time after assigning the above
# settings, so that it'll be picked up as a result buffer
- # see: Packages/Default/exec.py#L228-L230
+ # see: Packages/Default/exec.py#L207-L209
panel = window.create_output_panel(name)
# All our panels are read-only
panel.set_read_only(True)
diff --git a/plugin/references.py b/plugin/references.py
index 1948d43..96ccec8 100644
--- a/plugin/references.py
+++ b/plugin/references.py
@@ -99,7 +99,7 @@ class LspSymbolReferencesCommand(LspTextCommand):
})
# highlight all word occurrences
regions = panel.find_all(r"\b{}\b".format(word))
- panel.add_regions('ReferenceHighlight', regions, 'comment', flags=sublime.DRAW_OUTLINED)
+ panel.add_regions('ReferenceHighlight', regions[1:], 'comment', flags=sublime.DRAW_OUTLINED)
def _get_relative_path(base_dir: Optional[str], file_path: str) -> str:
I don't think it is necessary to double click the mouse to control the jump to the definition, we can also set up a phantom and put a hyperlink in the phantom to navigate. Of course, double-click is best if it doesn't affect other plugins.
Just as the PackageDev plugin does in a settings view.

Yes, that could be an alternative. I just wanted to demonstrate that it is possible with a relatively small amount of code, and that it would be easy to make the link more obvious even with just the color scheme. Perhaps the phantom is better, it is probably a matter of preference.