Repository: sublimelsp/LSP

Issue:
erase_regions causes "markup.unnecessary.lsp" to flicker
**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Run Customize Color scheme from the command palette:
2. Paste this
```
{
    "rules": [
        {
            "scope": "markup.unnecessary.lsp",
            "foreground_adjust": "l(- 40%)",
            "background": "#00000001"
        },
    ]
}
```
4. Open a `hello.vue` file, that looks like this
```
<script setup lang="ts">
let xas = 312

asdaaasssdsasdasd // type here and see the flicker 

</script>
```
6. Type where the `asdaaasssdsasdasd` string is
7. See flicker

**Expected behavior**
There should be no flicker.

**Screenshots**

![output](https://github.com/sublimelsp/LSP/assets/22029477/de824d96-e361-47a9-b2b9-e94dfd859875)

This cannot be reproduced in all vue/ts files, 
only in certain fails like the one I provided.

----

#### Solution

I solved the problem by modifying this function,
but don't know if you guys have a better suggestion.
![2023-05-17-212104_855x298_scrot](https://github.com/sublimelsp/LSP/assets/22029477/679297ec-da7f-4afa-b586-96888f6aea73)

![output](https://github.com/sublimelsp/LSP/assets/22029477/d1e0d279-ed9d-4b91-8699-5b506317dabe)



Discussion:
This suggested fix might not be 100% correct (even if it might be in practice) because in theory there could exist a tag in `regions_with_tag` but we would not create region for it due to being filtered out due to severity check.

But I see if I can come up with some fix for this.

Resolving patch:
diff --git a/plugin/session_view.py b/plugin/session_view.py
--- a/plugin/session_view.py
+++ b/plugin/session_view.py
@@ -19,10 +19,19 @@
 import functools
 import sublime
 
-DIAGNOSTIC_TAG_VALUES = [v for (k, v) in DiagnosticTag.__dict__.items() if not k.startswith('_')]
+DIAGNOSTIC_TAG_VALUES = [v for (k, v) in DiagnosticTag.__dict__.items() if not k.startswith('_')]  # type: List[int]
 HOVER_HIGHLIGHT_KEY = "lsp_hover_highlight"
 
 
+class TagData:
+    __slots__ = ('key', 'regions', 'scope')
+
+    def __init__(self, key: str, regions: List[sublime.Region] = [], scope: str = '') -> None:
+        self.key = key
+        self.regions = regions
+        self.scope = scope
+
+
 class SessionView:
     """
     Holds state per session per view.
@@ -286,9 +295,7 @@ def present_diagnostics_async(self, is_view_visible: bool) -> None:
     def _draw_diagnostics(self, severity: int, max_severity_level: int, flags: int, multiline: bool) -> None:
         ICON_FLAGS = sublime.HIDE_ON_MINIMAP | sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE
         key = self.diagnostics_key(severity, multiline)
-        key_tags = {tag: '{}_tags_{}'.format(key, tag) for tag in DIAGNOSTIC_TAG_VALUES}
-        for key_tag in key_tags.values():
-            self.view.erase_regions(key_tag)
+        tags = {tag: TagData('{}_tags_{}'.format(key, tag)) for tag in DIAGNOSTIC_TAG_VALUES}
         data = self.session_buffer.data_per_severity.get((severity, multiline))
         if data and severity <= max_severity_level:
             non_tag_regions = data.regions
@@ -296,7 +303,8 @@ def _draw_diagnostics(self, severity: int, max_severity_level: int, flags: int,
                 tag_scope = self.diagnostics_tag_scope(tag)
                 # Trick to only add tag regions if there is a corresponding color scheme scope defined.
                 if tag_scope and 'background' in self.view.style_for_scope(tag_scope):
-                    self.view.add_regions(key_tags[tag], regions, tag_scope, flags=sublime.DRAW_NO_OUTLINE)
+                    tags[tag].regions = regions
+                    tags[tag].scope = tag_scope
                 else:
                     non_tag_regions.extend(regions)
             self.view.add_regions("{}_icon".format(key), non_tag_regions, data.scope, data.icon, ICON_FLAGS)
@@ -304,6 +312,11 @@ def _draw_diagnostics(self, severity: int, max_severity_level: int, flags: int,
         else:
             self.view.erase_regions("{}_icon".format(key))
             self.view.erase_regions("{}_underline".format(key))
+        for data in tags.values():
+            if data.regions:
+                self.view.add_regions(data.key, data.regions, data.scope, flags=sublime.DRAW_NO_OUTLINE)
+            else:
+                self.view.erase_regions(data.key)
 
     def on_request_started_async(self, request_id: int, request: Request) -> None:
         self._active_requests[request_id] = ActiveRequest(self, request_id, request)


Test patch: