12
12
from .core .types import debounced
13
13
from .core .types import Debouncer
14
14
from .core .types import FEATURES_TIMEOUT
15
- from .core .typing import Any , Callable , Iterable , Optional , List , Dict , Tuple
15
+ from .core .typing import Any , Callable , Iterable , Optional , List , Set , Dict , Tuple
16
16
from .core .views import DIAGNOSTIC_SEVERITY
17
17
from .core .views import diagnostic_severity
18
18
from .core .views import did_change
@@ -61,12 +61,12 @@ def __init__(self, severity: int) -> None:
61
61
class SemanticTokensData :
62
62
63
63
__slots__ = (
64
- 'data' , 'result_id' , 'active_scopes ' , 'tokens' , 'view_change_count' , 'needs_refresh' , 'pending_response' )
64
+ 'data' , 'result_id' , 'active_region_keys ' , 'tokens' , 'view_change_count' , 'needs_refresh' , 'pending_response' )
65
65
66
66
def __init__ (self ) -> None :
67
67
self .data = [] # type: List[int]
68
68
self .result_id = None # type: Optional[str]
69
- self .active_scopes = [] # type: List[str ]
69
+ self .active_region_keys = set () # type: Set[int ]
70
70
self .tokens = [] # type: List[SemanticToken]
71
71
self .view_change_count = 0
72
72
self .needs_refresh = False
@@ -105,6 +105,8 @@ def __init__(self, session_view: SessionViewProtocol, buffer_id: int, uri: Docum
105
105
self .diagnostics_debouncer = Debouncer ()
106
106
self .color_phantoms = sublime .PhantomSet (view , "lsp_color" )
107
107
self .semantic_tokens = SemanticTokensData ()
108
+ self ._semantic_region_keys = {} # type: Dict[str, int]
109
+ self ._last_semantic_region_key = 0
108
110
self ._check_did_open (view )
109
111
self ._session .register_session_buffer_async (self )
110
112
@@ -502,7 +504,7 @@ def _draw_semantic_tokens_async(self) -> None:
502
504
if view is None :
503
505
return
504
506
self .semantic_tokens .tokens .clear ()
505
- scope_regions = dict () # type: Dict[str, List[sublime.Region]]
507
+ scope_regions = dict () # type: Dict[int, Tuple[ str, List[sublime.Region] ]]
506
508
prev_line = 0
507
509
prev_col_utf16 = 0
508
510
for idx in range (0 , len (self .semantic_tokens .data ), 5 ):
@@ -526,7 +528,6 @@ def _draw_semantic_tokens_async(self) -> None:
526
528
# This logic should not be cached (in the decode_semantic_token method) because otherwise new user
527
529
# customizations in the color scheme for the scopes of custom token types would require a restart of
528
530
# Sublime Text to take effect.
529
- # Note that the region keys for these scopes are not initialized in SessionView._initialize_region_keys.
530
531
token_general_style = view .style_for_scope ("meta.semantic-token" )
531
532
token_type_style = view .style_for_scope ("meta.semantic-token.{}" .format (token_type .lower ()))
532
533
if token_general_style ["source_line" ] != token_type_style ["source_line" ] or \
@@ -537,24 +538,30 @@ def _draw_semantic_tokens_async(self) -> None:
537
538
scope = "meta.semantic-token.{}.lsp" .format (token_type .lower ())
538
539
self .semantic_tokens .tokens .append (SemanticToken (r , token_type , token_modifiers ))
539
540
if scope :
540
- scope_regions .setdefault (scope , []).append (r )
541
+ scope_regions .setdefault (self . _get_semantic_region_key_for_scope ( scope ), ( scope , []))[ 1 ] .append (r )
541
542
# don't update regions if there were additional changes to the buffer in the meantime
542
543
if self .semantic_tokens .view_change_count != view .change_count ():
543
544
return
544
- for scope in self .semantic_tokens .active_scopes .copy ():
545
- if scope not in scope_regions .keys ():
546
- self .semantic_tokens .active_scopes .remove (scope )
545
+ for region_key in self .semantic_tokens .active_region_keys .copy ():
546
+ if region_key not in scope_regions .keys ():
547
+ self .semantic_tokens .active_region_keys .remove (region_key )
547
548
for sv in self .session_views :
548
- sv .view .erase_regions ("lsp_ {}" .format (scope ))
549
- for scope , regions in scope_regions .items ():
550
- if scope not in self .semantic_tokens .active_scopes :
551
- self .semantic_tokens .active_scopes . append ( scope )
549
+ sv .view .erase_regions ("lsp_semantic_ {}" .format (region_key ))
550
+ for region_key , ( scope , regions ) in scope_regions .items ():
551
+ if region_key not in self .semantic_tokens .active_region_keys :
552
+ self .semantic_tokens .active_region_keys . add ( region_key )
552
553
for sv in self .session_views :
553
- sv .view .add_regions ("lsp_{}" .format (scope ), regions , scope , flags = sublime .DRAW_NO_OUTLINE )
554
+ sv .view .add_regions ("lsp_semantic_{}" .format (region_key ), regions , scope , flags = sublime .DRAW_NO_OUTLINE )
555
+
556
+ def _get_semantic_region_key_for_scope (self , scope : str ) -> int :
557
+ if scope not in self ._semantic_region_keys :
558
+ self ._last_semantic_region_key += 1
559
+ self ._semantic_region_keys [scope ] = self ._last_semantic_region_key
560
+ return self ._semantic_region_keys [scope ]
554
561
555
562
def _clear_semantic_token_regions (self , view : sublime .View ) -> None :
556
- for scope in self .semantic_tokens .active_scopes :
557
- view .erase_regions ("lsp_ {}" .format (scope ))
563
+ for region_key in self .semantic_tokens .active_region_keys :
564
+ view .erase_regions ("lsp_semantic_ {}" .format (region_key ))
558
565
559
566
def set_semantic_tokens_pending_refresh (self , needs_refresh : bool = True ) -> None :
560
567
self .semantic_tokens .needs_refresh = needs_refresh
0 commit comments