From 8696a5d136635625bcd3eed3c42d6e1defd399bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Sat, 3 Feb 2024 20:15:44 +0100 Subject: [PATCH] add commands for opening "find references" in bottom or quick panel (#2409) --- Default.sublime-commands | 14 +++++++++ LSP.sublime-settings | 2 +- Main.sublime-menu | 16 +++++----- docs/src/keyboard_shortcuts.md | 16 +++++----- plugin/references.py | 53 +++++++++++++++++++++++++--------- sublime-package.json | 2 +- 6 files changed, 72 insertions(+), 31 deletions(-) diff --git a/Default.sublime-commands b/Default.sublime-commands index 610d5cbab..75bb04d95 100644 --- a/Default.sublime-commands +++ b/Default.sublime-commands @@ -121,6 +121,20 @@ "caption": "LSP: Find References", "command": "lsp_symbol_references" }, + { + "caption": "LSP: Find References (Output Panel)", + "command": "lsp_symbol_references", + "args": { + "output_mode": "output_panel" + }, + }, + { + "caption": "LSP: Find References (Quick Panel)", + "command": "lsp_symbol_references", + "args": { + "output_mode": "quick_panel" + }, + }, { "caption": "LSP: Follow Link", "command": "lsp_open_link" diff --git a/LSP.sublime-settings b/LSP.sublime-settings index 4a84fd54f..b938ccdd7 100644 --- a/LSP.sublime-settings +++ b/LSP.sublime-settings @@ -162,7 +162,7 @@ // --- Other -------------------------------------------------------------------------- - // Show symbol references in Sublime's quick panel instead of the bottom panel. + // Show symbol references in Sublime's quick panel instead of the output panel. "show_references_in_quick_panel": true, // Show code lens: diff --git a/Main.sublime-menu b/Main.sublime-menu index 8aea68e8f..6eef29d01 100644 --- a/Main.sublime-menu +++ b/Main.sublime-menu @@ -255,20 +255,20 @@ "caption": "-" }, { - "caption": "Enable Language Server Globally…", - "command": "lsp_enable_language_server_globally", + "caption": "Enable Language Server Globally…", + "command": "lsp_enable_language_server_globally", }, { - "caption": "Disable Language Server Globally…", - "command": "lsp_disable_language_server_globally", + "caption": "Disable Language Server Globally…", + "command": "lsp_disable_language_server_globally", }, { - "caption": "Enable Language Server in Project…", - "command": "lsp_enable_language_server_in_project", + "caption": "Enable Language Server in Project…", + "command": "lsp_enable_language_server_in_project", }, { - "caption": "Disable Language Server in Project…", - "command": "lsp_disable_language_server_in_project", + "caption": "Disable Language Server in Project…", + "command": "lsp_disable_language_server_in_project", }, { "caption": "Troubleshoot Server Configuration…", diff --git a/docs/src/keyboard_shortcuts.md b/docs/src/keyboard_shortcuts.md index 41f0213ac..e277c542f 100644 --- a/docs/src/keyboard_shortcuts.md +++ b/docs/src/keyboard_shortcuts.md @@ -9,15 +9,15 @@ Refer to the [Customization section](customization.md#keyboard-shortcuts-key-bin | ------- | -------- | ------- | | Auto Complete | ctrl space (also on macOS) | `auto_complete` | Expand Selection | unbound | `lsp_expand_selection` -| Find References | shift f12 | `lsp_symbol_references` (supports optional args: `{"include_declaration": true/false}`) -| Fold | unbound | `lsp_fold` (supports optional args: `{"strict": true/false}` - to configure whether to fold only when the caret is contained within the folded region (`true`), or even when it is anywhere on the starting line (`false`)) -| Fold All | unbound | `lsp_fold_all` (supports optional args: `{"kind": "comment" | "imports" | "region"}`) +| Find References | shift f12 | `lsp_symbol_references`
Supports optional args: `{"include_declaration": true | false, "output_mode": "output_panel" | "quick_panel"}`.
Triggering from context menus while holding ctrl opens in "side by side" mode. Holding shift triggers opposite behavior relative to what `show_references_in_quick_panel` is set to. +| Fold | unbound | `lsp_fold`
Supports optional args: `{"strict": true/false}` - to configure whether to fold only when the caret is contained within the folded region (`true`), or even when it is anywhere on the starting line (`false`). +| Fold All | unbound | `lsp_fold_all`
Supports optional args: `{"kind": "comment" | "imports" | "region"}`. | Follow Link | unbound | `lsp_open_link` | Format File | unbound | `lsp_format_document` | Format Selection | unbound | `lsp_format_document_range` | Goto Declaration | unbound | `lsp_symbol_declaration` | Goto Definition | unbound
suggested: f12 | `lsp_symbol_definition` -| Goto Diagnostic | unbound
suggested: f8 | `lsp_goto_diagnostic` (with args: `{"uri": "$view_uri"}`) +| Goto Diagnostic | unbound
suggested: f8 | `lsp_goto_diagnostic`
With args: `{"uri": "$view_uri"}`. | Goto Diagnostic in Project | unbound
suggested: shift f8 | `lsp_goto_diagnostic` | Goto Implementation | unbound | `lsp_symbol_implementation` | Goto Symbol in Project | unbound
suggested: ctrl shift r | `lsp_workspace_symbols` @@ -31,12 +31,12 @@ Refer to the [Customization section](customization.md#keyboard-shortcuts-key-bin | Restart Server | unbound | `lsp_restart_server` | Run Code Action | unbound | `lsp_code_actions` | Run Code Lens | unbound | `lsp_code_lens` -| Run Refactor Action | unbound | `lsp_code_actions` (with args: `{"only_kinds": ["refactor"]}`) -| Run Source Action | unbound | `lsp_code_actions` (with args: `{"only_kinds": ["source"]}`) -| Save All | unbound | `lsp_save_all` (supports optional args `{"only_files": true}` - to ignore buffers which have no associated file on disk) +| Run Refactor Action | unbound | `lsp_code_actions`
With args: `{"only_kinds": ["refactor"]}`. +| Run Source Action | unbound | `lsp_code_actions`
With args: `{"only_kinds": ["source"]}`. +| Save All | unbound | `lsp_save_all`
Supports optional args `{"only_files": true}` - to ignore buffers which have no associated file on disk. | Show Call Hierarchy | unbound | `lsp_call_hierarchy` | Show Type Hierarchy | unbound | `lsp_type_hierarchy` | Signature Help | ctrl alt space | `lsp_signature_help_show` | Toggle Diagnostics Panel | ctrl alt m | `lsp_show_diagnostics_panel` -| Toggle Inlay Hints | unbound | `lsp_toggle_inlay_hints` (supports optional args: `{"enable": true/false}`) +| Toggle Inlay Hints | unbound | `lsp_toggle_inlay_hints`
Supports optional args: `{"enable": true/false}`. | Toggle Log Panel | unbound | `lsp_toggle_server_panel` diff --git a/plugin/references.py b/plugin/references.py index df6073c79..03f106deb 100644 --- a/plugin/references.py +++ b/plugin/references.py @@ -7,7 +7,7 @@ from .core.sessions import Session from .core.settings import userprefs from .core.types import ClientConfig -from .core.typing import Dict, List, Optional, Tuple +from .core.typing import Dict, List, Literal, Optional, Tuple from .core.views import get_line from .core.views import get_symbol_kind_from_scope from .core.views import get_uri_and_position_from_location @@ -20,6 +20,9 @@ import sublime +OutputMode = Literal['output_panel', 'quick_panel'] + + class LspSymbolReferencesCommand(LspTextCommand): capability = 'referencesProvider' @@ -32,7 +35,8 @@ def is_enabled( force_group: bool = True, fallback: bool = False, group: int = -1, - include_declaration: bool = False + include_declaration: bool = False, + output_mode: Optional[OutputMode] = None, ) -> bool: return fallback or super().is_enabled(event, point) @@ -44,10 +48,18 @@ def is_visible( force_group: bool = True, fallback: bool = False, group: int = -1, - include_declaration: bool = False + include_declaration: bool = False, + output_mode: Optional[OutputMode] = None, ) -> bool: + # We include "output panel" and "quick panel" variants of `LSP: Find References` in the Command Palette + # but we only show the one that is not the same as the default one (per the `show_references_in_quick_panel` + # setting). + if output_mode == 'output_panel' and not userprefs().show_references_in_quick_panel or \ + output_mode == 'quick_panel' and userprefs().show_references_in_quick_panel: + return False if self.applies_to_context_menu(event): - return self.is_enabled(event, point, side_by_side, fallback) + return self.is_enabled( + event, point, side_by_side, force_group, fallback, group, include_declaration, output_mode) return True def run( @@ -59,7 +71,8 @@ def run( force_group: bool = True, fallback: bool = False, group: int = -1, - include_declaration: bool = False + include_declaration: bool = False, + output_mode: Optional[OutputMode] = None, ) -> None: session = self.best_session(self.capability) file_path = self.view.file_name() @@ -85,6 +98,8 @@ def run( force_group, fallback, group, + output_mode, + event, word_range.begin() ) ) @@ -99,11 +114,13 @@ def _handle_response_async( force_group: bool, fallback: bool, group: int, + output_mode: Optional[OutputMode], + event: Optional[dict], position: int, response: Optional[List[Location]] ) -> None: sublime.set_timeout(lambda: self._handle_response( - word, session, side_by_side, force_group, fallback, group, position, response)) + word, session, side_by_side, force_group, fallback, group, output_mode, event, position, response)) def _handle_response( self, @@ -113,17 +130,27 @@ def _handle_response( force_group: bool, fallback: bool, group: int, + output_mode: Optional[OutputMode], + event: Optional[dict], position: int, response: Optional[List[Location]] ) -> None: - if response: - if userprefs().show_references_in_quick_panel: - self._show_references_in_quick_panel( - word, session, response, side_by_side, force_group, group, position) - else: - self._show_references_in_output_panel(word, session, response) - else: + if not response: self._handle_no_results(fallback, side_by_side) + return + modifier_keys = (event or {}).get('modifier_keys', {}) + if output_mode is None: + show_in_quick_panel = userprefs().show_references_in_quick_panel + if modifier_keys.get('shift'): + show_in_quick_panel = not show_in_quick_panel + else: + show_in_quick_panel = output_mode == 'quick_panel' + if show_in_quick_panel: + if modifier_keys.get('primary'): + side_by_side = True + self._show_references_in_quick_panel(word, session, response, side_by_side, force_group, group, position) + else: + self._show_references_in_output_panel(word, session, response) def _handle_no_results(self, fallback: bool = False, side_by_side: bool = False) -> None: window = self.view.window() diff --git a/sublime-package.json b/sublime-package.json index 632870d7f..40b959870 100644 --- a/sublime-package.json +++ b/sublime-package.json @@ -664,7 +664,7 @@ "show_references_in_quick_panel": { "type": "boolean", "default": true, - "markdownDescription": "Show symbol references in Sublime's quick panel instead of the bottom panel." + "markdownDescription": "Show symbol references in Sublime's quick panel instead of the output panel." }, "popup_max_characters_width": { "type": "integer",