Repository: sublimelsp/LSP

Issue:
Goto Symbol boots slowly on large files, first characters are inserted in the code as a result
**Describe the bug**
LSP Goto Symbol suddenly started being a little slower to "boot", and I end up littering my code with unwanted characters as a result: I hit Ctrl-R to open LSP Goto Symbol, and immediately start typing the name of the function I’m looking for, as I always do, but now it fires a little bit late and the first character of my function name is inserted in the code.

**To Reproduce**
Steps to reproduce the behavior:
1. Open a source file that is long enough for the problem to be noticeable and annoying (4-5k lines on my computer)
2. Hit Ctrl-R or whatever your keybinding is for "LSP Goto Symbol"…
3. …and start typing right away. The characters you type before the input panel is up are inserted into the code, generating syntax errors just before you jump to another part of the code as Goto Symbol starts accepting your input (that makes it hard to notice you’re adding these characters).

**Expected behavior**
I’m not sure which is the main issue, but both would be good to fix I guess:

- have the LSP Goto Symbol command fire near-instantly, even in large files (examples: legacy applications, languages which encourage large files)
- have the view be blocked while the input panel is loading (is it possible?) 

**Environment (please complete the following information):**
- OS: Linux Mint 21.2 x86_64
- Sublime Text version: 4152
- LSP version: 1.26.0
- Language servers used: intelephense



Discussion:
Note that we have logic for [preventing keys from modifying the view when document symbols are requested](https://github.com/sublimelsp/LSP/blob/2e06833ca86cb88b4ae3acf663541551de675458/plugin/symbols.py#L167-L167) but maybe some recent changes opened some timing window where this doesn't apply. Maybe due to extra [`input` handler](https://github.com/sublimelsp/LSP/blob/2e06833ca86cb88b4ae3acf663541551de675458/plugin/symbols.py#L172-L172)
I guess it might happen because we still erase that setting directly when the response arrives at https://github.com/sublimelsp/LSP/blob/2e06833ca86cb88b4ae3acf663541551de675458/plugin/symbols.py#L190 but after that there might still be a small delay before the overlay opens because we run it through `window.run_command`. Maybe we can move that line somewhere into the input handler class. But I'll have to take a closer look later, not that we possibly miss some code path in that case where the setting accidentally won't get erased.

It might also be possible now to catch the typed input during that time and insert it into the text field when it opens, via `initial_text` of the newly introduced input handler. But I guess I'll need a sufficiently large file to be able to test this; when I run the command the overlay still opens basically instantly even on files with several thousand lines.
When testing on a server (tsc) that is still initializing I can easily trigger a case where documentSymbols will take a long time to respond but in that case I can't reproduce the issue (the input is blocked in that case). So I guess it's as you are saying that it's the period between when the response arrives and when the list is shown that is problematic.

Resolving patch:
diff --git a/plugin/symbols.py b/plugin/symbols.py
--- a/plugin/symbols.py
+++ b/plugin/symbols.py
@@ -174,6 +174,7 @@ def input(self, args: dict) -> Optional[sublime_plugin.CommandInputHandler]:
             self.cached = False
             if self.kind and not any(item.value['kind'] == self.kind for item in self.items):
                 self.has_matching_symbols = False
+                self._reset_suppress_input()
                 return None
             window = self.view.window()
             if not window:
@@ -183,11 +184,11 @@ def input(self, args: dict) -> Optional[sublime_plugin.CommandInputHandler]:
                 SYMBOL_KIND_NAMES.get(symbol_kind, 'All Kinds'),
                 self.kind,
                 kind=SYMBOL_KINDS.get(symbol_kind, sublime.KIND_AMBIGUOUS))
+            sublime.set_timeout(self._reset_suppress_input)
             return DocumentSymbolsKindInputHandler(window, initial_value, self.view, self.items)
         return None
 
     def handle_response_async(self, response: Union[List[DocumentSymbol], List[SymbolInformation], None]) -> None:
-        self.view.settings().erase(SUPPRESS_INPUT_SETTING_KEY)
         self.items.clear()
         if response and self.view.is_valid():
             if 'selectionRange' in response[0]:
@@ -205,9 +206,12 @@ def handle_response_async(self, response: Union[List[DocumentSymbol], List[Symbo
                 window.run_command('show_overlay', {'overlay': 'command_palette', 'command': 'lsp_document_symbols'})
 
     def handle_response_error(self, error: Any) -> None:
-        self.view.settings().erase(SUPPRESS_INPUT_SETTING_KEY)
+        self._reset_suppress_input()
         print_to_status_bar(error)
 
+    def _reset_suppress_input(self) -> None:
+        self.view.settings().erase(SUPPRESS_INPUT_SETTING_KEY)
+
     def process_document_symbol_recursive(
         self, item: DocumentSymbol, hierarchy: str = ''
     ) -> List[sublime.ListInputItem]:


Test patch: