Skip to content

Commit

Permalink
Fix diagnostic regions being hidden by semantic regions
Browse files Browse the repository at this point in the history
Fixes #1934
  • Loading branch information
rchl committed May 22, 2022
1 parent f518fb1 commit ca87a28
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
4 changes: 2 additions & 2 deletions plugin/core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@ def __init__(self, manager: Manager, logger: Logger, workspace_folders: List[Wor
self._plugin = None # type: Optional[AbstractPlugin]
self._status_messages = {} # type: Dict[str, str]
self.diagnostics_manager = DiagnosticsManager()
self.semantic_tokens_map = get_semantic_tokens_map(config.semantic_tokens)
self._semantic_tokens_map = get_semantic_tokens_map(config.semantic_tokens)

def __getattr__(self, name: str) -> Any:
"""
Expand Down Expand Up @@ -1532,7 +1532,7 @@ def decode_semantic_token(
types_legend = tuple(cast(List[str], self.get_capability('semanticTokensProvider.legend.tokenTypes')))
modifiers_legend = tuple(cast(List[str], self.get_capability('semanticTokensProvider.legend.tokenModifiers')))
return decode_semantic_token(
types_legend, modifiers_legend, self.semantic_tokens_map, token_type_encoded, token_modifiers_encoded)
types_legend, modifiers_legend, self._semantic_tokens_map, token_type_encoded, token_modifiers_encoded)

# --- server request handlers --------------------------------------------------------------------------------------

Expand Down
36 changes: 22 additions & 14 deletions plugin/session_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ def __init__(self, severity: int) -> None:
class SemanticTokensData:

__slots__ = (
'data', 'result_id', 'active_scopes', 'tokens', 'view_change_count', 'needs_refresh', 'pending_response')
'data', 'result_id', 'active_region_keys', 'tokens', 'view_change_count', 'needs_refresh', 'pending_response')

def __init__(self) -> None:
self.data = [] # type: List[int]
self.result_id = None # type: Optional[str]
self.active_scopes = [] # type: List[str]
self.active_region_keys = [] # type: List[int]
self.tokens = [] # type: List[SemanticToken]
self.view_change_count = 0
self.needs_refresh = False
Expand Down Expand Up @@ -105,6 +105,8 @@ def __init__(self, session_view: SessionViewProtocol, buffer_id: int, uri: Docum
self.diagnostics_debouncer = Debouncer()
self.color_phantoms = sublime.PhantomSet(view, "lsp_color")
self.semantic_tokens = SemanticTokensData()
self._semantic_region_keys = {} # type: Dict[str, int]
self._last_semantic_region_key = 0
self._check_did_open(view)
self._session.register_session_buffer_async(self)

Expand Down Expand Up @@ -502,7 +504,7 @@ def _draw_semantic_tokens_async(self) -> None:
if view is None:
return
self.semantic_tokens.tokens.clear()
scope_regions = dict() # type: Dict[str, List[sublime.Region]]
scope_regions = dict() # type: Dict[int, Tuple[str, List[sublime.Region]]]
prev_line = 0
prev_col_utf16 = 0
for idx in range(0, len(self.semantic_tokens.data), 5):
Expand Down Expand Up @@ -537,24 +539,30 @@ def _draw_semantic_tokens_async(self) -> None:
scope = "meta.semantic-token.{}.lsp".format(token_type.lower())
self.semantic_tokens.tokens.append(SemanticToken(r, token_type, token_modifiers))
if scope:
scope_regions.setdefault(scope, []).append(r)
scope_regions.setdefault(self._get_region_key_for_scope(scope), (scope, []))[1].append(r)
# don't update regions if there were additional changes to the buffer in the meantime
if self.semantic_tokens.view_change_count != view.change_count():
return
for scope in self.semantic_tokens.active_scopes.copy():
if scope not in scope_regions.keys():
self.semantic_tokens.active_scopes.remove(scope)
for region_key in self.semantic_tokens.active_region_keys.copy():
if region_key not in scope_regions.keys():
self.semantic_tokens.active_region_keys.remove(region_key)
for sv in self.session_views:
sv.view.erase_regions("lsp_{}".format(scope))
for scope, regions in scope_regions.items():
if scope not in self.semantic_tokens.active_scopes:
self.semantic_tokens.active_scopes.append(scope)
sv.view.erase_regions("lsp_semantic_{}".format(region_key))
for region_key, (scope, regions) in scope_regions.items():
if region_key not in self.semantic_tokens.active_region_keys:
self.semantic_tokens.active_region_keys.append(region_key)
for sv in self.session_views:
sv.view.add_regions("lsp_{}".format(scope), regions, scope, flags=sublime.DRAW_NO_OUTLINE)
sv.view.add_regions("lsp_semantic_{}".format(region_key), regions, scope, flags=sublime.DRAW_NO_OUTLINE)

def _get_region_key_for_scope(self, scope: str) -> int:
if scope not in self._semantic_region_keys:
self._last_semantic_region_key += 1
self._semantic_region_keys[scope] = self._last_semantic_region_key
return self._semantic_region_keys[scope]

def _clear_semantic_token_regions(self, view: sublime.View) -> None:
for scope in self.semantic_tokens.active_scopes:
view.erase_regions("lsp_{}".format(scope))
for region_key in self.semantic_tokens.active_region_keys:
view.erase_regions("lsp_semantic_{}".format(region_key))

def set_semantic_tokens_pending_refresh(self, needs_refresh: bool = True) -> None:
self.semantic_tokens.needs_refresh = needs_refresh
Expand Down
4 changes: 2 additions & 2 deletions plugin/session_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ def _initialize_region_keys(self) -> None:
document_highlight_kinds = ["text", "read", "write"]
line_modes = ["m", "s"]
self.view.add_regions(self.CODE_ACTIONS_KEY, r) # code actions lightbulb icon should always be on top
for key, scope in self.session.semantic_tokens_map:
self.view.add_regions("lsp_{} meta.semantic-token.{}.lsp".format(scope, key.lower()), r)
for key in range(0, 100):
self.view.add_regions("lsp_semantic_{}".format(key), r)
if document_highlight_style == "fill":
for kind in document_highlight_kinds:
for mode in line_modes:
Expand Down

0 comments on commit ca87a28

Please sign in to comment.