55
55
from .session_buffer import SessionBuffer
56
56
from .session_view import SessionView
57
57
from functools import partial
58
- from typing import Any , Callable , Generator , Iterable
58
+ from functools import wraps
59
+ from typing import Any , Callable , Generator , Iterable , TypeVar
59
60
from typing import cast
61
+ from typing_extensions import Concatenate , ParamSpec
60
62
from weakref import WeakSet
61
63
from weakref import WeakValueDictionary
62
64
import itertools
68
70
69
71
SUBLIME_WORD_MASK = 515
70
72
73
+ P = ParamSpec ('P' )
74
+ R = TypeVar ('R' )
75
+
76
+
77
+ def requires_session (
78
+ func : Callable [Concatenate [DocumentSyncListener , P ], R ]
79
+ ) -> Callable [Concatenate [DocumentSyncListener , P ], R | None ]:
80
+ """
81
+ A decorator for the `DocumentSyncListener` event handlers, which immediately returns `None` if there are no
82
+ `SessionView`s.
83
+ """
84
+ @wraps (func )
85
+ def wrapper (self : DocumentSyncListener , * args : P .args , ** kwargs : P .kwargs ) -> R | None :
86
+ if not self .session_views_async ():
87
+ return None
88
+ return func (self , * args , ** kwargs )
89
+ return wrapper
90
+
71
91
72
92
def is_regular_view (v : sublime .View ) -> bool :
73
93
# Not from the quick panel (CTRL+P), and not a special view like a console, output panel or find-in-files panels.
@@ -327,6 +347,7 @@ def session_buffers_async(self, capability: str | None = None) -> list[SessionBu
327
347
def session_views_async (self ) -> list [SessionView ]:
328
348
return list (self ._session_views .values ())
329
349
350
+ @requires_session
330
351
def on_text_changed_async (self , change_count : int , changes : Iterable [sublime .TextChange ]) -> None :
331
352
if self .view .is_primary ():
332
353
for sv in self .session_views_async ():
@@ -364,9 +385,12 @@ def on_activated_async(self) -> None:
364
385
return
365
386
if not self ._registered :
366
387
self ._register_async ()
388
+ session_views = self .session_views_async ()
389
+ if not session_views :
390
+ return
367
391
if userprefs ().show_code_actions :
368
392
self ._do_code_actions_async ()
369
- for sv in self . session_views_async () :
393
+ for sv in session_views :
370
394
if sv .code_lenses_needs_refresh :
371
395
sv .set_code_lenses_pending_refresh (needs_refresh = False )
372
396
sv .start_code_lenses_async ()
@@ -381,6 +405,7 @@ def on_activated_async(self) -> None:
381
405
sb .set_inlay_hints_pending_refresh (needs_refresh = False )
382
406
sb .do_inlay_hints_async (self .view )
383
407
408
+ @requires_session
384
409
def on_selection_modified_async (self ) -> None :
385
410
first_region , _ = self ._update_stored_selection_async ()
386
411
if first_region is None :
@@ -482,6 +507,7 @@ def on_query_context(self, key: str, operator: int, operand: Any, match_all: boo
482
507
return operand == bool (session_view .session_buffer .get_document_link_at_point (self .view , position ))
483
508
return None
484
509
510
+ @requires_session
485
511
def on_hover (self , point : int , hover_zone : int ) -> None :
486
512
if self .view .is_popup_visible ():
487
513
return
@@ -524,6 +550,7 @@ def _on_hover_gutter_async(self, point: int) -> None:
524
550
location = point ,
525
551
on_navigate = lambda href : self ._on_navigate (href , point ))
526
552
553
+ @requires_session
527
554
def on_text_command (self , command_name : str , args : dict | None ) -> tuple [str , dict ] | None :
528
555
if command_name == "auto_complete" :
529
556
self ._auto_complete_triggered_manually = True
@@ -539,6 +566,7 @@ def on_text_command(self, command_name: str, args: dict | None) -> tuple[str, di
539
566
return ('paste' , {})
540
567
return None
541
568
569
+ @requires_session
542
570
def on_post_text_command (self , command_name : str , args : dict [str , Any ] | None ) -> None :
543
571
if command_name == 'paste' :
544
572
format_on_paste = self .view .settings ().get ('lsp_format_on_paste' , userprefs ().lsp_format_on_paste )
@@ -552,6 +580,7 @@ def on_post_text_command(self, command_name: str, args: dict[str, Any] | None) -
552
580
# hide the popup when `esc` or arrows are pressed pressed
553
581
self .view .hide_popup ()
554
582
583
+ @requires_session
555
584
def on_query_completions (self , prefix : str , locations : list [int ]) -> sublime .CompletionList | None :
556
585
completion_list = sublime .CompletionList ()
557
586
triggered_manually = self ._auto_complete_triggered_manually
0 commit comments