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

Issue:
Server is being shutdown on server sending empty stderr line
When server triggers stderr output that is an empty string (or becomes an empty string after `rstrip` then LSP closes the transports and thus the server.

Issue found when analyzing https://github.com/sublimelsp/LSP-angular/issues/1


Discussion:

Resolving patch:
diff --git a/plugin/core/transports.py b/plugin/core/transports.py
--- a/plugin/core/transports.py
+++ b/plugin/core/transports.py
@@ -45,6 +45,7 @@ class JsonRpcTransport(Transport):
 
     def __init__(self, name: str, process: subprocess.Popen, socket: Optional[socket.socket], reader: IO[bytes],
                  writer: IO[bytes], stderr: Optional[IO[bytes]], callback_object: TransportCallbacks) -> None:
+        self._closed = False
         self._process = process
         self._socket = socket
         self._reader = reader
@@ -58,7 +59,6 @@ def __init__(self, name: str, process: subprocess.Popen, socket: Optional[socket
         self._reader_thread.start()
         self._writer_thread.start()
         self._stderr_thread.start()
-        self._closed = False
 
     def send(self, payload: Dict[str, Any]) -> None:
         self._send_queue.put_nowait(payload)
@@ -157,9 +157,9 @@ def _write_loop(self) -> None:
     def _stderr_loop(self) -> None:
         try:
             while self._stderr:
-                message = self._stderr.readline().decode('utf-8', 'replace').rstrip()
-                if not message:
+                if self._closed:
                     break
+                message = self._stderr.readline().decode('utf-8', 'replace').rstrip()
                 callback_object = self._callback_object()
                 if callback_object:
                     callback_object.on_stderr_message(message)


Test patch:
Repository: sublimelsp/LSP

Issue:
Server is being shutdown on server sending empty stderr line
When server triggers stderr output that is an empty string (or becomes an empty string after `rstrip` then LSP closes the transports and thus the server.

Issue found when analyzing https://github.com/sublimelsp/LSP-angular/issues/1


Discussion:
Fixed by #1241 :)
Another follow-up merged (see linked PRs), but I've also noticed that it's still possible to reproduce freeze by force-killing the server. So when transport shutdown is not initiated by us.

Resolving patch:
diff --git a/plugin/core/transports.py b/plugin/core/transports.py
--- a/plugin/core/transports.py
+++ b/plugin/core/transports.py
@@ -137,6 +137,7 @@ def _end(self, exception: Optional[Exception]) -> None:
         callback_object = self._callback_object()
         if callback_object:
             callback_object.on_transport_close(exit_code, exception)
+        self.close()
 
     def _write_loop(self) -> None:
         exception = None  # type: Optional[Exception]


Test patch:
Repository: sublimelsp/LSP

Issue:
Support document symbol sorting
Currently, when we call `LSP: Document Symbols`, we get document symbols displayed in reverse order from the actual code. Like this:

![image](https://user-images.githubusercontent.com/23649474/90335784-3fa48080-e012-11ea-96a9-2b4199572b8f.png)

This is because the LSP server returns document symbols in reverse order (in this example, the server is `rust-analyzer`).
Language Server Protocol doesn't specify the order of document symbols returned from the server, so how symbols are displayed should probably be decided and handled on the client-side.

Looking at VSCode, users have options to sort symbols in several ways (by position, by name, by category).

![image](https://user-images.githubusercontent.com/23649474/90335952-74650780-e013-11ea-8252-7b84614de26c.png)

It would be best to provide sort options like VSCode, but for now, to sort them by something (I think by position is good) should be implemented before providing sort options.


Discussion:

Resolving patch:
diff --git a/plugin/symbols.py b/plugin/symbols.py
--- a/plugin/symbols.py
+++ b/plugin/symbols.py
@@ -125,10 +125,16 @@ def on_highlighted(self, index: int) -> None:
 
     def process_symbols(self, items: List[Dict[str, Any]]) -> List[sublime.QuickPanelItem]:
         self.regions.clear()
+        panel_items = []
         if 'selectionRange' in items[0]:
-            return self.process_document_symbols(items)
+            panel_items = self.process_document_symbols(items)
         else:
-            return self.process_symbol_informations(items)
+            panel_items = self.process_symbol_informations(items)
+        # Sort both lists in sync according to the range's begin point.
+        sorted_results = zip(*sorted(zip(self.regions, panel_items), key=lambda item: item[0][0].begin()))
+        sorted_regions, sorted_panel_items = sorted_results
+        self.regions = list(sorted_regions)
+        return list(sorted_panel_items)
 
     def process_document_symbols(self, items: List[Dict[str, Any]]) -> List[sublime.QuickPanelItem]:
         quick_panel_items = []  # type: List[sublime.QuickPanelItem]


Test patch:
Repository: sublimelsp/LSP

Issue:
Possibility to click on the comment links
Some documentation blocks has links to more complete documentation. It would be interesting to be able to click on these links directly from the popup.

## ACTUAL BEHAVIOR

![lsp](https://user-images.githubusercontent.com/3408809/91644805-04448180-ea16-11ea-9e6c-e834a47a2e5b.png)

## PROPOSED

![lsp-proposal](https://user-images.githubusercontent.com/3408809/91644887-bda35700-ea16-11ea-9ea3-bb7f86c1b3f8.png)


Discussion:
Seems to be a language server issue https://github.com/bmewburn/vscode-intelephense/issues/1316
Well, the image on second example is from VSCode using `vscode-intelephense`. I thought this would have to be identified by the LSP package

LSP would have to detect/parse URLs and make them into links
I just saw on Discord, you said It only happens for plaintext and for markdown LSP trust the langserver to do it.

What is the possibility of this being handled by the LSP?
There are complications with markdown that would make it fragile to try to parse links. For example, we should not make links clickable inside backticks or inside `<a>` tags. We could kindly ask @facelessuser, the author of [mdpopups](https://facelessuser.github.io/sublime-markdown-popups/), to implement automatic link parsing of some sorts for markdown, possibly enabled with frontmatter.
Just use the MagicLink extension.
I was on my phone when I posted that, but here is the link: https://facelessuser.github.io/pymdown-extensions/extensions/magiclink/. It is already included in Sublime Text if you are using mdpopups, but you probably just need to enable it.

Resolving patch:
diff --git a/plugin/core/views.py b/plugin/core/views.py
--- a/plugin/core/views.py
+++ b/plugin/core/views.py
@@ -415,6 +415,11 @@ def minihtml(view: sublime.View, content: Union[str, Dict[str, str], list], allo
                         "hardbreak": False,
                         "nbsp": False
                     }
+                },
+                {
+                    "pymdownx.magiclink": {
+                        "repo_url_shortener": True
+                    }
                 }
             ]
         }


Test patch:
diff --git a/tests/test_views.py b/tests/test_views.py
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -251,6 +251,11 @@ def test_minihtml_ignores_non_allowed_markup_content(self) -> None:
         expect = ""
         self.assertEqual(minihtml(self.view, content, allowed_formats=FORMAT_STRING), expect)
 
+    def test_minihtml_magiclinks(self) -> None:
+        content = {'value': 'https://github.com/sublimelsp/LSP', 'kind': 'markdown'}
+        expect = '<p><a href="https://github.com/sublimelsp/LSP">https://github.com/sublimelsp/LSP</a></p>'
+        self.assertEqual(minihtml(self.view, content, allowed_formats=FORMAT_MARKUP_CONTENT), expect)
+
     def _strip_style_attributes(self, content: str) -> str:
         return re.sub(r'\s+style="[^"]+"', '', content)
Repository: sublimelsp/LSP

Issue:
[LSP-elm] Documentation popup is no logner visible when "More" link is clicked
* OS and language server - Ubunutu 20.04, LSP-elm, ST 4085 
* How you installed LSP - git, latest st-4000-exploration

When clicking the `More` link in the AC popup,
I expect to see a documentation popup.
But I see nothing. 

This commit introduced this behavior 19df9e19afeb0f32064a8b7e3a11ebaa4254f63c
If I checkout the commit before 19df9e19afeb0f32064a8b7e3a11ebaa4254f63c, everything works as expected.


Discussion:
Can you post some logs for the relevant completion item and the resolve request?
I have a fix. It's due to the server not supporting the resolve provider.

Resolving patch:
diff --git a/plugin/completion.py b/plugin/completion.py
--- a/plugin/completion.py
+++ b/plugin/completion.py
@@ -25,10 +25,12 @@ def run(self, edit: sublime.Edit, index: int, event: Optional[dict] = None) -> N
         if not detail or not documentation:
             # To make sure that the detail or documentation fields doesn't exist we need to resove the completion item.
             # If those fields appear after the item is resolved we show them in the popup.
-            self.do_resolve(item)
-        else:
-            minihtml_content = self.get_content(documentation, detail)
-            self.show_popup(minihtml_content)
+            session = self.best_session('completionProvider.resolveProvider')
+            if session:
+                session.send_request(Request.resolveCompletionItem(item), self.handle_resolve_response)
+                return
+        minihtml_content = self.get_content(documentation, detail)
+        self.show_popup(minihtml_content)
 
     def format_documentation(self, content: Union[str, Dict[str, str]]) -> str:
         return minihtml(self.view, content, allowed_formats=FORMAT_STRING | FORMAT_MARKUP_CONTENT)
@@ -56,13 +58,6 @@ def show_popup(self, minihtml_content: str) -> None:
     def on_navigate(self, url: str) -> None:
         webbrowser.open(url)
 
-    def do_resolve(self, item: dict) -> None:
-        session = self.best_session('completionProvider.resolveProvider')
-        if session:
-            session.send_request(
-                Request.resolveCompletionItem(item),
-                lambda res: self.handle_resolve_response(res))
-
     def handle_resolve_response(self, item: Optional[dict]) -> None:
         detail = ""
         documentation = ""


Test patch:
Repository: sublimelsp/LSP

Issue:
Request code actions when new diagnostics arrive on the current line
I'm starting to depend more on code actions and one thing that is somewhat annoying is that code action requests are triggered when the text changes or when the caret changes position. But not when diagnostics are updated. Frequently what happens is that I'm done typing, code actions are then requested. No code actions return. Then diagnostics come in and they carry code actions stored on the server. So we should re-request code actions in that case.

As a workaround I now have to press the left arrow button.


Discussion:

Resolving patch:
diff --git a/plugin/core/windows.py b/plugin/core/windows.py
--- a/plugin/core/windows.py
+++ b/plugin/core/windows.py
@@ -72,7 +72,7 @@ def sum_total_errors_and_warnings_async(self) -> Tuple[int, int]:
         raise NotImplementedError()
 
     @abstractmethod
-    def update_diagnostic_in_status_bar_async(self) -> None:
+    def on_diagnostics_updated_async(self) -> None:
         raise NotImplementedError()
 
     @abstractmethod
diff --git a/plugin/documents.py b/plugin/documents.py
--- a/plugin/documents.py
+++ b/plugin/documents.py
@@ -224,7 +224,12 @@ def diagnostics_async(self) -> Dict[str, List[Diagnostic]]:
             result[sv.session.config.name] = sv.get_diagnostics_async()
         return result
 
-    def update_diagnostic_in_status_bar_async(self) -> None:
+    def on_diagnostics_updated_async(self) -> None:
+        self._clear_code_actions_annotation()
+        self._do_code_actions()
+        self._update_diagnostic_in_status_bar_async()
+
+    def _update_diagnostic_in_status_bar_async(self) -> None:
         if userprefs().show_diagnostics_in_view_status:
             r = self._get_current_range_async()
             if r is not None:
@@ -292,7 +297,7 @@ def on_selection_modified_async(self) -> None:
             self._clear_code_actions_annotation()
             self._when_selection_remains_stable_async(self._do_code_actions, current_region,
                                                       after_ms=self.code_actions_debounce_time)
-            self.update_diagnostic_in_status_bar_async()
+            self._update_diagnostic_in_status_bar_async()
 
     def on_post_save_async(self) -> None:
         if self.view.is_primary():
diff --git a/plugin/session_view.py b/plugin/session_view.py
--- a/plugin/session_view.py
+++ b/plugin/session_view.py
@@ -130,7 +130,7 @@ def present_diagnostics_async(self, flags: int) -> None:
                 self.view.erase_regions(key)
         listener = self.listener()
         if listener:
-            listener.update_diagnostic_in_status_bar_async()
+            listener.on_diagnostics_updated_async()
 
     def get_diagnostics_async(self) -> List[Diagnostic]:
         return self.session_buffer.diagnostics


Test patch:
Repository: sublimelsp/LSP

Issue:
Diagnostic not highlighted in view when range is empty
**Describe the bug**
A diagnostic that has an empty range is not visible in the view (only in the gutter and in diagnostics panel).

**To Reproduce**
Receive a diagnostic like:
```js
{
  "diagnostics": [
    {
      "code": {
        "target": "https://eslint.org/docs/rules/curly",
        "value": "curly"
      },
      "message": "Expected { after 'if' condition.",
      "range": {
        "end": {
          "character": 9,
          "line": 607
        },
        "start": {
          "character": 9,
          "line": 607
        }
      },
      "severity": 1,
      "source": "eslint"
    },
```

**Expected behavior**
See where on the line the problem is. Otherwise, it's difficult to know where code action can be triggered.

**Screenshots**
![Screenshot 2020-09-25 at 22 58 01](https://user-images.githubusercontent.com/153197/94315521-f6394080-ff82-11ea-9dc6-7adffb643465.png)


**Environment (please complete the following information):**
- OS: macOS
- Sublime Text version: 4087
- LSP version: 49ea7330301078035ad56b94218a9c6edb604498
- Language servers used: eslint


Discussion:

Resolving patch:
diff --git a/plugin/session_view.py b/plugin/session_view.py
--- a/plugin/session_view.py
+++ b/plugin/session_view.py
@@ -127,7 +127,15 @@ def present_diagnostics_async(self, flags: int) -> None:
                 self.view.erase_regions(key)
             elif ((severity <= userprefs().show_diagnostics_severity_level) and
                     (data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE))):
-                self.view.add_regions(key, data.regions, data.scope, data.icon, flags)
+
+                def handle_same_regions(region: sublime.Region) -> sublime.Region:
+                    # this allows showing diagnostics with same begin and end in the view
+                    if region.a == region.b:
+                        return sublime.Region(region.a, region.a + 1)
+                    return region
+
+                underline_regions = list(map(handle_same_regions, data.regions))
+                self.view.add_regions(key, underline_regions, data.scope, data.icon, flags)
             else:
                 self.view.erase_regions(key)
         listener = self.listener()


Test patch:
Repository: sublimelsp/LSP

Issue:
Advertise window.showMessageRequest.messageActionItem.additionalPropertiesSupport
See: https://github.com/microsoft/language-server-protocol/commit/4a29ca0725469624fc07425c3fa0fde386e7ee55


Discussion:

Resolving patch:
diff --git a/plugin/core/sessions.py b/plugin/core/sessions.py
--- a/plugin/core/sessions.py
+++ b/plugin/core/sessions.py
@@ -229,6 +229,11 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor
             "configuration": True
         },
         "window": {
+            "showMessage": {
+                "messageActionItem": {
+                    "additionalPropertiesSupport": True
+                }
+            },
             "workDoneProgress": True
         }
     }


Test patch:
Repository: sublimelsp/LSP

Issue:
LspHoverCommand should check whether the view is actually under the session's control
We try to find the most suitable session in LspHoverCommand, but that session may not actually have the view under document sync. For example, when hovering over a symbol with the mouse for a transient view via CTRL+P.


Discussion:

Resolving patch:
diff --git a/plugin/core/registry.py b/plugin/core/registry.py
--- a/plugin/core/registry.py
+++ b/plugin/core/registry.py
@@ -74,7 +74,8 @@ def want_event(self) -> bool:
         return True
 
     def best_session(self, capability: str, point: Optional[int] = None) -> Optional[Session]:
-        return best_session(self.view, self.sessions(capability), point)
+        listener = windows.listener_for_view(self.view)
+        return listener.session(capability, point) if listener else None
 
     def session_by_name(self, name: Optional[str] = None) -> Optional[Session]:
         target = name if name else self.session_name
diff --git a/plugin/core/windows.py b/plugin/core/windows.py
--- a/plugin/core/windows.py
+++ b/plugin/core/windows.py
@@ -51,6 +51,10 @@ class AbstractViewListener(metaclass=ABCMeta):
     def manager(self) -> "WindowManager":
         raise NotImplementedError()
 
+    @abstractmethod
+    def session(self, capability_path: str, point: Optional[int] = None) -> Optional[Session]:
+        raise NotImplementedError()
+
     @abstractmethod
     def on_session_initialized_async(self, session: Session) -> None:
         raise NotImplementedError()
@@ -517,14 +521,21 @@ def __init__(self, configs: ConfigManager) -> None:
         self._configs = configs
 
     def lookup(self, window: sublime.Window) -> WindowManager:
-        if window.id() in self._windows:
-            return self._windows[window.id()]
+        wm = self._windows.get(window.id())
+        if wm:
+            return wm
         workspace = ProjectFolders(window)
         window_configs = self._configs.for_window(window)
         state = WindowManager(window=window, workspace=workspace, configs=window_configs)
         self._windows[window.id()] = state
         return state
 
+    def listener_for_view(self, view: sublime.View) -> Optional[AbstractViewListener]:
+        w = view.window()
+        if not w:
+            return None
+        return self.lookup(w).listener_for_view(view)
+
     def discard(self, window: sublime.Window) -> None:
         self._windows.pop(window.id(), None)
 


Test patch:
Repository: sublimelsp/LSP

Issue:
Rename `auto_show_diagnostics_panel_level` to `show_diagnostics_panel_on_save`
`auto_show_diagnostics_panel_level` might not be a clear and simple setting name as it could be.

**Describe the solution you'd like**
`show_diagnostics_panel_on_save` gives more context that `auto_show_diagnostics_panel_level`.

**Describe alternatives you've considered**
I considered even suggesting the removed `auto_show_diagnostics_panel` instead of `auto_show_diagnostics_panel_level`, but I still think that `show_diagnostics_panel_on_save` is more descriptive.




Discussion:
Sounds good to me.

Resolving patch:
diff --git a/plugin/core/types.py b/plugin/core/types.py
--- a/plugin/core/types.py
+++ b/plugin/core/types.py
@@ -147,7 +147,7 @@ def read_list_setting(settings_obj: sublime.Settings, key: str, default: list) -
 class Settings:
 
     # This is only for mypy
-    auto_show_diagnostics_panel_level = None  # type: int
+    show_diagnostics_panel_on_save = None  # type: int
     code_action_on_save_timeout_ms = None  # type: int
     diagnostics_additional_delay_auto_complete_ms = None  # type: int
     diagnostics_delay_ms = None  # type: int
@@ -183,7 +183,7 @@ def r(name: str, default: Union[bool, int, str, list, dict]) -> None:
             val = s.get(name)
             setattr(self, name, val if isinstance(val, default.__class__) else default)
 
-        r("auto_show_diagnostics_panel_level", 2)
+        r("show_diagnostics_panel_on_save", 2)
         r("code_action_on_save_timeout_ms", 2000)
         r("diagnostics_additional_delay_auto_complete_ms", 0)
         r("diagnostics_delay_ms", 0)
@@ -221,10 +221,10 @@ def r(name: str, default: Union[bool, int, str, list, dict]) -> None:
         auto_show_diagnostics_panel = s.get("auto_show_diagnostics_panel")
         if isinstance(auto_show_diagnostics_panel, bool):
             if not auto_show_diagnostics_panel:
-                self.auto_show_diagnostics_panel_level = 0
+                self.show_diagnostics_panel_on_save = 0
         elif isinstance(auto_show_diagnostics_panel, str):
             if auto_show_diagnostics_panel == "never":
-                self.auto_show_diagnostics_panel_level = 0
+                self.show_diagnostics_panel_on_save = 0
 
         # Backwards-compatible with "only_show_lsp_completions"
         only_show_lsp_completions = s.get("only_show_lsp_completions")
diff --git a/plugin/session_buffer.py b/plugin/session_buffer.py
--- a/plugin/session_buffer.py
+++ b/plugin/session_buffer.py
@@ -269,7 +269,7 @@ def on_diagnostics_async(self, raw_diagnostics: List[Diagnostic], version: Optio
                     total_warnings += 1
                 if severity <= userprefs().diagnostics_panel_include_severity_level:
                     data.panel_contribution.append(format_diagnostic_for_panel(diagnostic))
-                if severity <= userprefs().auto_show_diagnostics_panel_level:
+                if severity <= userprefs().show_diagnostics_panel_on_save:
                     should_show_diagnostics_panel = True
             self._publish_diagnostics_to_session_views(
                 diagnostics_version,


Test patch:
Repository: sublimelsp/LSP

Issue:
[regression] lsp_execute does nothing due to empty session
Since this [commit](https://github.com/sublimelsp/LSP/commit/7d05794fa3cc4ecd3931d09a90e801addc70d9fa) the `capability` variable got deleted which means that `self.best_session(self.capability)` is unable to find session.

The consequence is that [LSP-metals.sublime-commands](https://github.com/scalameta/metals-sublime/blob/master/LSP-metals.sublime-commands) aren't executed.

 



Discussion:

Resolving patch:
diff --git a/plugin/execute_command.py b/plugin/execute_command.py
--- a/plugin/execute_command.py
+++ b/plugin/execute_command.py
@@ -27,7 +27,7 @@ def run_async() -> None:
                     listener.do_signature_help_async(manual=False)
 
             return sublime.set_timeout_async(run_async)
-        session = self.session_by_name(session_name) if session_name else self.best_session(self.capability)
+        session = self.session_by_name(session_name if session_name else self.session_name)
         if session and command_name:
             if command_args:
                 self._expand_variables(command_args)


Test patch: