Repository: sublimelsp/LSP

Issue:
Diagnostics sync issue related to using undo
LSP 4070-1.0.6 (or thereabouts)

1. Create an issue in the code (I suggest to add a space where there shouldn't be one) to make diagnostic show up
2. If space was added, remove that space with a backspace
3. Very quickly press the shortcut for undo and immediately backspace to delete the space again

Expect: Diagnostic (added by undo) disappears
Actual: Diagnostic stays visible even though there are no diagnostic errors in the status bar or diagnostics panel.

What happens is that ST restores the error/warning diagnostic region on undoing and then, due to an unfortunate series of events and things being async, we fail to call `view.erase_regions`. And our model gets out of sync with the view.

This reproduces even with `diagnostics_delay_ms` set to 0 but it's a bit easier with higher value.


Discussion:
@ayoub-benali This is probably the issue you were seeing.
My original issue didn't involve any undo command. I was freshly opening a workspace which had diagnostic errors. 
LSP server was publishing diagnostics but sublime diagnostic panel wasn't showing them. I can't remember if the error count was correct or not. 

I assume both problems have the same root: the diagnostic state gets out sync between the server and client.
I don't see how it could happen without using undo though.

If you ever see the issue pop up at start again, it would be helpful to provide a server log for that.
I think what you're seeing is that we don't show viewless files anymore in the panel https://github.com/sublimelsp/LSP/issues/1198#issuecomment-663746788. This is a deliberate decision. Ultimately a build system has the final say on whether all the code in the workspace is correct.
> I think what you're seeing is that we don't show viewless files anymore in the panel [#1198 (comment)](https://github.com/sublimelsp/LSP/issues/1198#issuecomment-663746788). This is a deliberate decision. Ultimately a build system has the final say on whether all the code in the workspace is correct.

Yes I manged to reproduce the issue.
1. create an error in the workspace.
2. close the view for the file having an error.
3. restart ST
4. Notice the server logs: the server will report diagnostic errors but they aren't show in the diagnostic panels. The same goes for the errors count in the status bar. 

In your [#1198 (comment)](https://github.com/sublimelsp/LSP/issues/1198#issuecomment-663746788) @rwols you said `Only files that are tracked receive diagnostics.` These files are part of the workspace why would LSP not show either errors? especially when the server actually reports them.

The is a deliberate behavior is for me a bad UX because I would open a new project which would have several errors but LSP wouldn't report anyone and I would have to open files randomly to see LSP reporting errors. Or jump to a separate build tool to double check that there aren't any hidden errors.

 
The hard part is to decide when to remove those viewless diagnostics. I'm not saying it's impossible, but it's not trivial at all.
When diagnostics are attached to "tracked" views it's easy: just remove them when the tracked view dies.
I think we have two issues here. ~~The initial comment is about an issue that can be triggered with `diagnostics_delay_ms` > 0.~~
Yes I agree. Should I create a separate issue regarding when to clean the viewless diagnostics ? 

Resolving patch:
diff --git a/plugin/core/sessions.py b/plugin/core/sessions.py
--- a/plugin/core/sessions.py
+++ b/plugin/core/sessions.py
@@ -957,11 +957,6 @@ def call_manager(self, method: str, *args: Any) -> None:
         if mgr:
             getattr(mgr, method)(*args)
 
-    def clear_diagnostics_async(self) -> None:
-        # XXX: Remove this functionality?
-        for sb in self.session_buffers_async():
-            sb.on_diagnostics_async([], None)
-
     def on_stderr_message(self, message: str) -> None:
         self.call_manager('handle_stderr_log', self, message)
         self._logger.stderr_message(message)
diff --git a/plugin/session_buffer.py b/plugin/session_buffer.py
--- a/plugin/session_buffer.py
+++ b/plugin/session_buffer.py
@@ -302,10 +302,7 @@ def present() -> None:
 
         self.diagnostics_debouncer.cancel_pending()
 
-        if not bool(diagnostics) and not self.diagnostics_are_visible:
-            # Nothing was previously visible, and nothing will become visible. So do nothing.
-            pass
-        elif self.diagnostics_are_visible:
+        if self.diagnostics_are_visible:
             # Old diagnostics are visible. Update immediately.
             present()
         else:


Test patch: