Repository: sublimelsp/LSP

Issue:
LSP Document Symbols downside compared to native one
**Describe the bug**
I've been running with `cmd+r` overridden to use Document Symbols from LSP. The functionality is better than native but it has one downside compared to native behavior. Namely, with native, I can trigger the shortcut and start typing immediately. The quick panel appears immediately (synchronously or at least with almost no latency). When using LSP's document symbol, the quick panel only opens after we receive server response so, being used to just start typing my query right away, my query ends up being inserted into the active view instead.

Ideally, the quick panel would open right away, even before the response comes, but I guess the API might not let us do that.

Alternatively, we could potentially work around that somehow by capturing user input when the command is triggered and before the quick panel is shown.


Discussion:
I have noticed this as well. It would be very helpful to capture the input so that it is not accidental entered into the active view. Would it be possible to open a panel with nothing in it, keep track of the input, and then close it and open the actual panel with that same input?
Capturing the input could probably be done by having a key binding assigning to `<char>` that does nothing when a certain view setting is set. Then we can set that setting on triggering `Document Symbols` and remove it once we get a reply (success or error).
Related: https://github.com/sublimehq/sublime_text/issues/3338

Resolving patch:
diff --git a/plugin/symbols.py b/plugin/symbols.py
--- a/plugin/symbols.py
+++ b/plugin/symbols.py
@@ -1,5 +1,6 @@
 from .core.protocol import Request, Range
 from .core.registry import LspTextCommand
+from .core.rpc import print_to_status_bar
 from .core.typing import Any, List, Optional, Tuple, Dict, Generator
 from .core.views import location_to_encoded_filename
 from .core.views import range_to_region
@@ -11,6 +12,9 @@
 import sublime_plugin
 
 
+SUPPRESS_INPUT_SETTING_KEY = 'lsp_suppress_input'
+
+
 def unpack_lsp_kind(kind: int) -> Tuple[int, str, str, str]:
     if 1 <= kind <= len(SYMBOL_KINDS):
         return SYMBOL_KINDS[kind - 1]
@@ -75,12 +79,16 @@ def __init__(self, view: sublime.View) -> None:
         self.is_first_selection = False
 
     def run(self, edit: sublime.Edit) -> None:
+        self.view.settings().set(SUPPRESS_INPUT_SETTING_KEY, True)
         session = self.best_session(self.capability)
         if session:
             session.send_request(
-                Request.documentSymbols({"textDocument": text_document_identifier(self.view)}), self.handle_response)
+                Request.documentSymbols({"textDocument": text_document_identifier(self.view)}),
+                lambda response: sublime.set_timeout(lambda: self.handle_response(response)),
+                lambda error: sublime.set_timeout(lambda: self.handle_response_error(error)))
 
     def handle_response(self, response: Any) -> None:
+        self.view.settings().erase(SUPPRESS_INPUT_SETTING_KEY)
         window = self.view.window()
         if window and isinstance(response, list) and len(response) > 0:
             self.old_regions = [sublime.Region(r.a, r.b) for r in self.view.sel()]
@@ -93,6 +101,10 @@ def handle_response(self, response: Any) -> None:
                 self.on_highlighted)
             self.view.run_command("lsp_selection_clear")
 
+    def handle_response_error(self, error: Any) -> None:
+        self.view.settings().erase(SUPPRESS_INPUT_SETTING_KEY)
+        print_to_status_bar(error)
+
     def region(self, index: int) -> sublime.Region:
         return self.regions[index][0]
 


Test patch: