internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: sublimelsp/LSP

Issue:
send `textDocument/didChange` before `textDocument/completion`
Otherwise, the server is not able to pick up the most recent changes to generate completion list.


Discussion:
LSP should be sending these, did you check your logs?
Implemented here, see `purge_did_change`: https://github.com/tomv564/LSP/blob/9a546564806453f830ab6394f47e33d56e174181/main.py#L2137-L2151
It seems it is not always the case. Maybe due to buffer not in `pending_buffer_changes`?
After some investigation, it is caused by the dissynchronization between the `view.on_modified_async` and `CompletionHandler`. If `view.on_modified_async` is triggered after `CompletionHandler`, then `pending_buffer_changes` would not be updated and `purge_did_change` is not functional.

A quick fix is changing
https://github.com/tomv564/LSP/blob/3014171cac21f894b71ebeb6c2cc93e2e853f8a9/main.py#L2546-L2546
to `on_modified` so that `queue_did_change` is always called before the completion ViewEventListener. However, it may introduce a little but neglectable overhead.

Resolving patch:
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -1215,7 +1215,7 @@ def initialize_document_sync(text_document_sync_kind):
     # TODO: hook up events per scope/client
     Events.subscribe('view.on_load_async', notify_did_open)
     Events.subscribe('view.on_activated_async', notify_did_open)
-    Events.subscribe('view.on_modified_async', queue_did_change)
+    Events.subscribe('view.on_modified', queue_did_change)
     Events.subscribe('view.on_post_save_async', notify_did_save)
     Events.subscribe('view.on_close', notify_did_close)
 
@@ -2543,9 +2543,9 @@ def on_load_async(self):
         # skip transient views: if not is_transient_view(self.view):
         Events.publish("view.on_load_async", self.view)
 
-    def on_modified_async(self):
+    def on_modified(self):
         if self.view.file_name():
-            Events.publish("view.on_modified_async", self.view)
+            Events.publish("view.on_modified", self.view)
 
     def on_activated_async(self):
         if self.view.file_name():


Test patch:
Repository: sublimelsp/LSP

Issue:
Word completions are no longer shown
For some reason,  PR #136 breaks Sublime Text default word completion.

at e04aa1a0f2767a82d6166924296a3ecb3b9b1ffc

It shows both LSP completions and ST completions.
<img width="353" alt="screen shot 2017-10-07 at 1 14 56 am" src="https://user-images.githubusercontent.com/1690993/31304981-fdeaabe4-aafc-11e7-9082-83fa65d3d49a.png">

but at 67b7715326a675a61c058b3ab990eb03b81c3d7d

It shows only LSP completions
<img width="376" alt="screen shot 2017-10-07 at 1 17 10 am" src="https://user-images.githubusercontent.com/1690993/31304999-42d7fe3c-aafd-11e7-8899-db9801069013.png">


cc: @deathaxe 


Discussion:
~Please report issues to PRs in the PR itself before it is merged. Thanks!~
Sorry, just realised this was an old PR!
Ya, it was merged 3 days ago.

Resolving patch:
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -2233,7 +2233,7 @@ def format_completion(self, item) -> 'Tuple[str, str]':
         if insert_text[0] == '$':  # sublime needs leading '$' escaped.
             insert_text = '\$' + insert_text[1:]
         # only return label with a hint if available
-        return " \t ".join((label, hint)) if hint else label, insert_text
+        return "\t  ".join((label, hint)) if hint else label, insert_text
 
     def handle_response(self, response):
         global resolvable_completion_items


Test patch:
Repository: sublimelsp/LSP

Issue:
Autocompletion hints fail if CompletionItem label is empty 
This could happen when an user requests autocompletion hints for all the members and functions of some package like OpenCV (``cv2``), using python-language-server as LSP backend.


Discussion:

Resolving patch:
diff --git a/plugin/completion.py b/plugin/completion.py
--- a/plugin/completion.py
+++ b/plugin/completion.py
@@ -230,7 +230,7 @@ def format_completion(self, item: dict) -> 'Tuple[str, str]':
                 hint = completion_item_kind_names[kind]
         # label is an alternative for insertText if insertText not provided
         insert_text = item.get("insertText") or label
-        if insert_text[0] == '$':  # sublime needs leading '$' escaped.
+        if len(insert_text) > 0 and insert_text[0] == '$':  # sublime needs leading '$' escaped.
             insert_text = '\$' + insert_text[1:]
         # only return label with a hint if available
         return "\t  ".join((label, hint)) if hint else label, insert_text


Test patch:
Repository: sublimelsp/LSP

Issue:
space wrongly triggers autocompletion
following https://github.com/tomv564/LSP/pull/197#discussion_r151605795

<img width="418" alt="screen shot 2017-11-17 at 12 23 30 am" src="https://user-images.githubusercontent.com/1690993/32930648-f23bb3be-cb2d-11e7-96bf-437671397099.png">

It could be reproduced by typing `y` and `<space>` very quickly or when the language server responds slowly.

We might need to check if the context which triggered the completion is still a prefix of the current cursor.


Discussion:
Thanks for reminding me, it is easy to reproduce but I must have ignored it so far if it occurred in regular coding. Is there a particularly bothersome example where you see this in everyday coding?

As for a solution, prefix checking needs to allow completion if I've typed `yie` when a completion is returned for `y` but not when I've typed `y `. 

We could also check if the last character is whitespace and set the completion state to CANCELLING in `on_modified`?
Need to look at the "undo whitespace" logic together with this as well as reported by @django-wong
> There is another small issue, when I type fast, the completion comes later and some times it undo what I just typed (keywords in most case).

Resolving patch:
diff --git a/plugin/completion.py b/plugin/completion.py
--- a/plugin/completion.py
+++ b/plugin/completion.py
@@ -168,6 +168,10 @@ def on_modified(self):
         if self.view.sel()[0].begin() < self.last_location:
             self.last_location = 0
             self.view.run_command("hide_auto_complete")
+        # cancel current completion if the previous input is an space
+        prev_char = self.view.substr(self.view.sel()[0].begin() - 1)
+        if self.state == CompletionState.REQUESTING and prev_char.isspace():
+            self.state = CompletionState.CANCELLING
 
     def on_query_completions(self, prefix, locations):
         if self.view.match_selector(locations[0], NO_COMPLETION_SCOPES):


Test patch:
Repository: sublimelsp/LSP

Issue:
Feature request: Toggle diagnostic panel
Hi Tom, I have a suggestion.

Right now I have a keyboard shortcut to open the diagnostic panel `ctrl+shift+m`.
As you can see. When I open the panel with that keybinding, and press the keybinding again the panel is still visible. 

![notoggle](https://user-images.githubusercontent.com/22029477/36727088-45b28d4a-1bbc-11e8-9f72-3a6d7f611f09.gif)

Wouldn't it be better if the panel could be toggled like this? :)

![output3](https://user-images.githubusercontent.com/22029477/36727446-8e5a78d6-1bbd-11e8-8968-a914264a20da.gif)


If the answer is yes? I have already done that and I could create a pull request if you want :)


Discussion:

Resolving patch:
diff --git a/plugin/diagnostics.py b/plugin/diagnostics.py
--- a/plugin/diagnostics.py
+++ b/plugin/diagnostics.py
@@ -206,7 +206,13 @@ def clear_diagnostics_status(self):
 class LspShowDiagnosticsPanelCommand(sublime_plugin.WindowCommand):
     def run(self):
         ensure_diagnostics_panel(self.window)
-        self.window.run_command("show_panel", {"panel": "output.diagnostics"})
+        active_panel = self.window.active_panel()
+        is_active_panel = (active_panel == "output.diagnostics")
+
+        if is_active_panel:
+            self.window.run_command("hide_panel", {"panel": "output.diagnostics"})
+        else:
+            self.window.run_command("show_panel", {"panel": "output.diagnostics"})
 
 
 def create_diagnostics_panel(window):


Test patch:
Repository: sublimelsp/LSP

Issue:
Scopes priorities while selecting configuration
## Bug:

When there are multiple language servers configured, all of which are for similar scopes (Ex. `source.json`, `source.json.sublime.settings`) the configuration with the most specific scope should be preferred; however right now one or the other could "win", some times leading to erroneous configuration.

Example comes from configuring **vscode-json-languageserver** to work with both `json` and `jsonc` languageIds.

### Suggestion:

Give priority to the configuration with the most specific scope that matches.



Discussion:

Resolving patch:
diff --git a/plugin/core/configurations.py b/plugin/core/configurations.py
--- a/plugin/core/configurations.py
+++ b/plugin/core/configurations.py
@@ -17,13 +17,21 @@
 
 
 def get_scope_client_config(view: 'sublime.View', configs: 'List[ClientConfig]') -> 'Optional[ClientConfig]':
+    # When there are multiple server configurations, all of which are for
+    # similar scopes (e.g. 'source.json', 'source.json.sublime.settings') the
+    # configuration with the most specific scope (highest ranked selector)
+    # in the current position is preferred.
+    scope_score = 0
+    scope_client_config = None
     for config in configs:
         for scope in config.scopes:
-            if len(view.sel()) > 0:
-                if view.match_selector(view.sel()[0].begin(), scope):
-                    return config
-
-    return None
+            sel = view.sel()
+            if len(sel) > 0:
+                score = view.score_selector(sel[0].begin(), scope)
+                if score > scope_score:
+                    scope_score = score
+                    scope_client_config = config
+    return scope_client_config
 
 
 def register_client_config(config: ClientConfig) -> None:


Test patch:
Repository: sublimelsp/LSP

Issue:
Use case-insensitive Regexps for matching syntaxes
### Suggestion:

When using `settings.get('syntax')` to filter configurations, it's needed such configurations to match exactly. Many times there are more than one single package for any given syntax (and oftentimes there are packages that haven't been updated in some time and for which syntax files have moved or extension definition changed from `tmLanguage` to `sublime-syntax`). This can lead in the need to configure server languages "guessing" what syntax files are configured for it.

Real-world examples of such:

**Markdown**:
1. `Packages/Markdown/Markdown.sublime-syntax`
2. `Packages/Markdown Extended/Syntaxes/Markdown Extended.sublime-syntax`
3. `Packages/Markdown Extended/Syntaxes/Markdown Extended.tmLanguage`

**SCSS**:
1. `Packages/Sass/Syntaxes/SCSS.sublime-syntax`
2. `Packages/SCSS/SCSS.tmLanguage`

**JSON**:
1. `Packages/JavaScript/JSON.sublime-syntax`
2. `Packages/Babel/JSON (Babel).sublime-syntax`
3. `Packages/PackageDev/Package/Sublime Text Settings/Sublime Text Settings.sublime-syntax`

It could very well be better to have a set of case insensitive regexps to match the language from the syntax (after all scopes are later used to confirm). That way we could have, accordingly, the following syntaxes that would do a `re.search()`.

```json
  "syntaxes": [
    "Markdown"
  ]
```

```json
  "syntaxes": [
    "SCSS"
  ]
```

```json
  "syntaxes": [
    "JSON",
    "Sublime Text Settings"
  ]
```

_Alternatively_, we could add `languages` as the list of regexps that match, keeping `syntaxes` for exact matches and using `languages` as fallbacks to figure out the language configuration.


Discussion:

Resolving patch:
diff --git a/plugin/core/configurations.py b/plugin/core/configurations.py
--- a/plugin/core/configurations.py
+++ b/plugin/core/configurations.py
@@ -1,3 +1,4 @@
+import re
 import sublime
 
 from .settings import ClientConfig, client_configs
@@ -105,14 +106,14 @@ def apply_window_settings(client_config: 'ClientConfig', view: 'sublime.View') -
 def is_supportable_syntax(syntax: str) -> bool:
     # TODO: filter out configs disabled by the user.
     for config in client_configs.defaults:
-        if syntax in config.syntaxes:
+        if re.search(r'|'.join(r'\b%s\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):
             return True
     return False
 
 
 def is_supported_syntax(syntax: str) -> bool:
     for config in client_configs.all:
-        if syntax in config.syntaxes:
+        if re.search(r'|'.join(r'\b%s\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):
             return True
     return False
 


Test patch:
Repository: sublimelsp/LSP

Issue:
Don't move cursor at the end when populating the diagnostics panel
When the diagnostics are populated the cursor in the panel is moved to the end. See [here](https://github.com/tomv564/LSP/blob/2869978d8b46d717da27eb0ac7a7e234840b218d/plugin/core/panels.py#L53-L56).

Is there a reason for this? 

Because I can't use the `f4` keybinding to goto the next result when it is opened.
Instead I need first to press the `shift + f4`, which is the backward direction.


Here is a simple solution.
```diff
     def run(self, edit, characters):
         self.view.replace(edit, sublime.Region(0, self.view.size()), characters)
 
-        # Move cursor to the end
+        # Clear the selection
         selection = self.view.sel()
         selection.clear()
-        selection.add(sublime.Region(self.view.size(), self.view.size()))
```



Discussion:
Unsure, the change was never explained by @rmccue in https://github.com/tomv564/LSP/pull/91
Feel free to open a PR to remove it, maybe we'll find out why soon! 

Resolving patch:
diff --git a/plugin/core/panels.py b/plugin/core/panels.py
--- a/plugin/core/panels.py
+++ b/plugin/core/panels.py
@@ -50,7 +50,6 @@ class LspUpdatePanelCommand(sublime_plugin.TextCommand):
     def run(self, edit, characters):
         self.view.replace(edit, sublime.Region(0, self.view.size()), characters)
 
-        # Move cursor to the end
+        # Clear the selection
         selection = self.view.sel()
         selection.clear()
-        selection.add(sublime.Region(self.view.size(), self.view.size()))


Test patch:
Repository: sublimelsp/LSP

Issue:
[bug] CamelCase instead of snace_case 
`documentChanges` argument on the left https://github.com/tomv564/LSP/blob/5a472ba6f23d70f6f8f1ebaabb83015c066ce198/plugin/rename.py#L69
should be `document_changes`, like `LspApplyWorkspaceEditCommand` expects:
https://github.com/tomv564/LSP/blob/5a472ba6f23d70f6f8f1ebaabb83015c066ce198/plugin/core/edit.py#L19

When doing a rename, this popped up in the console
```
LSP:  --> textDocument/rename
Traceback (most recent call last):
  File "/opt/sublime_text/sublime_plugin.py", line 1034, in run_
    return self.run(**args)
TypeError: run() got an unexpected keyword argument 'documentChanges'
```


Discussion:
I recently changed that keyword, but did not check rename.py. I will make a PR to rectify that, or, if you’re busy with it anyway, you can do the changes.

Resolving patch:
diff --git a/plugin/rename.py b/plugin/rename.py
--- a/plugin/rename.py
+++ b/plugin/rename.py
@@ -66,7 +66,7 @@ def handle_response(self, response: 'Optional[Dict]') -> None:
         if response:
             self.view.window().run_command('lsp_apply_workspace_edit',
                                            {'changes': response.get('changes'),
-                                            'documentChanges': response.get('documentChanges')})
+                                            'document_changes': response.get('documentChanges')})
         else:
             self.view.window().status_message('No rename edits returned')
 


Test patch:
Repository: sublimelsp/LSP

Issue:
TypeError: 'NoneType' object is not iterable - golsp completion
Output from console with logging enabled:
```
LSP:  --> textDocument/completion
LSP:      {'isIncomplete': False, 'items': None}
Error handling server payload
Traceback (most recent call last):
  File "/Users/margus/Library/Application Support/Sublime Text 3/Packages/LSP/plugin/core/rpc.py", line 141, in receive_payload
    self.response_handler(payload)
  File "/Users/margus/Library/Application Support/Sublime Text 3/Packages/LSP/plugin/core/rpc.py", line 160, in response_handler
    handler(response["result"])
  File "/Users/margus/Library/Application Support/Sublime Text 3/Packages/LSP/plugin/completion.py", line 310, in handle_response
    items = sorted(items, key=lambda item: item.get("sortText") or item["label"])
TypeError: 'NoneType' object is not iterable
```

Not sure how to reproduce exactly as I haven't noticed the exact moment when it happens. But sometimes the whole completion stops working after this issue and all I see in the console (until sublime restart) is `LSP:  --> textDocument/didChange`

It seems to be protocol implementation issue as null values in response seem to be allowed: https://microsoft.github.io/language-server-protocol/specification#textDocument_completion

> result: CompletionItem[] | CompletionList | null. If a CompletionItem[] is provided it is interpreted to be complete. So it is the same as { isIncomplete: false, items }

* OS and language server:
  * macOS
  * https://github.com/saibing/bingo
* How you installed LSP (Package Control or from git?)
```
$ git rev-parse HEAD
263b5b30b0744d777a3bdfb77aa174abf6b1664b
```

* User config:
```
{
	"clients":
	{
		"golsp":
		{
			"command":
			[
				"/Users/margus/src/go/bin/bingo"
			],
			"enabled": true,
			"env":
			{
				"GOPATH": "/Users/margus/src/go"
			},
			"languageId": "go",
			"scopes":
			[
				"source.go"
			],
			"syntaxes":
			[
				"Packages/Go/Go.sublime-syntax"
			]
		}
	},
	"log_debug": true,
	"log_payloads": true,
	"log_stderr": true,
	"only_show_lsp_completions": true
}
```




Discussion:

Resolving patch:
diff --git a/plugin/completion.py b/plugin/completion.py
--- a/plugin/completion.py
+++ b/plugin/completion.py
@@ -304,7 +304,7 @@ def handle_response(self, response: 'Optional[Dict]'):
         if self.state == CompletionState.REQUESTING:
             items = []  # type: List[Dict]
             if isinstance(response, dict):
-                items = response["items"]
+                items = response["items"] or []
             elif isinstance(response, list):
                 items = response
             items = sorted(items, key=lambda item: item.get("sortText") or item["label"])


Test patch:
Repository: sublimelsp/LSP

Issue:
hover regression
After the latest commits hover popups produce errors, I suspect c9a73907f00972a415e8e979d5dcc96c11ec3f09 is responsible for this
* OS: Windows 10
* language server: pyls
* How you installed LSP: git
* Minimal reproduction steps
    1. open a .py file
    2. hover over an function name
* Log
```
LSP:  --> textDocument/hover
LSP:      {'contents': "is_supported_syntax(syntax: str, configs: 'List[ClientConfig]') -> bool"}
Parse Error: #x27;List[ClientConfig]&#x27;) -&gt; bool</p><p><a href='definition'>Definition</a> | <a href='references'>References</a> | <a href='rename'>Rename</a></p></div></div> code: Unexpected character
Parse Error: 27;List[ClientConfig]&#x27;) -&gt; bool</p><p><a href='definition'>Definition</a> | <a href='references'>References</a> | <a href='rename'>Rename</a></p></div></div> code: Unexpected character
Parse Error: 7;List[ClientConfig]&#x27;) -&gt; bool</p><p><a href='definition'>Definition</a> | <a href='references'>References</a> | <a href='rename'>Rename</a></p></div></div> code: Unexpected character
Parse Error: #x27; code: Unknown entity
Parse Error: #x27;) -&gt; bool</p><p><a href='definition'>Definition</a> | <a href='references'>References</a> | <a href='rename'>Rename</a></p></div></div> code: Unexpected character
Parse Error: 27;) -&gt; bool</p><p><a href='definition'>Definition</a> | <a href='references'>References</a> | <a href='rename'>Rename</a></p></div></div> code: Unexpected character
Parse Error: 7;) -&gt; bool</p><p><a href='definition'>Definition</a> | <a href='references'>References</a> | <a href='rename'>Rename</a></p></div></div> code: Unexpected character
Parse Error: #x27; code: Unknown entity
```


Discussion:
Thanks for noticing this. I think I made a fix to satisfy both the C# and Python users.

Resolving patch:
diff --git a/plugin/hover.py b/plugin/hover.py
--- a/plugin/hover.py
+++ b/plugin/hover.py
@@ -139,9 +139,9 @@ def hover_content(self, point, response: 'Optional[Any]') -> str:
             value = ""
             language = None
             if isinstance(item, str):
-                value = escape(item)
+                value = item
             else:
-                value = escape(item.get("value"))
+                value = item.get("value")
                 language = item.get("language")
             if language:
                 formatted.append("```{}\n{}\n```\n".format(language, value))


Test patch:
Repository: sublimelsp/LSP

Issue:
when cancelling the symbols panel, the last symbol is selected
https://github.com/tomv564/LSP/blob/be904c56fddf35f724486de405a168786ed4ffeb/plugin/symbols.py#L82-L92
```diff
 def on_symbol_selected(self, symbol_index):
+    if symbol_index == -1:
+        return
     selected_symbol = self.symbols[symbol_index]
     range = selected_symbol.get('location', selected_symbol.get('range'))
     range = range.get('range', range)
```


Discussion:

Resolving patch:
diff --git a/plugin/symbols.py b/plugin/symbols.py
--- a/plugin/symbols.py
+++ b/plugin/symbols.py
@@ -80,6 +80,8 @@ def handle_response(self, response: 'Optional[List]') -> None:
         self.view.window().show_quick_panel(symbols, self.on_symbol_selected)
 
     def on_symbol_selected(self, symbol_index):
+        if symbol_index == -1:
+            return
         selected_symbol = self.symbols[symbol_index]
         range = selected_symbol.get('location', selected_symbol.get('range'))
         range = range.get('range', range)


Test patch: