Skip to content

Commit 4c37df7

Browse files
committed
Convert to decorator
1 parent 7a8b482 commit 4c37df7

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

plugin/documents.py

+26-15
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@
5555
from .session_buffer import SessionBuffer
5656
from .session_view import SessionView
5757
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
5960
from typing import cast
61+
from typing_extensions import ParamSpec
6062
from weakref import WeakSet
6163
from weakref import WeakValueDictionary
6264
import itertools
@@ -68,6 +70,22 @@
6870

6971
SUBLIME_WORD_MASK = 515
7072

73+
P = ParamSpec('P')
74+
R = TypeVar('R')
75+
76+
77+
def requires_session(func: Callable[P, R]) -> Callable[P, R | None]:
78+
"""
79+
A decorator for the `DocumentSyncListener` event handlers, which immediately returns `None` if there are no
80+
`SessionView`s.
81+
"""
82+
@wraps(func)
83+
def wrapper(self: DocumentSyncListener, *args: P.args, **kwargs: P.kwargs) -> R | None:
84+
if not self.session_views_async():
85+
return None
86+
return func(self, *args, **kwargs) # pyright: ignore[reportCallIssue]
87+
return wrapper # pyright: ignore[reportReturnType]
88+
7189

7290
def is_regular_view(v: sublime.View) -> bool:
7391
# Not from the quick panel (CTRL+P), and not a special view like a console, output panel or find-in-files panels.
@@ -327,12 +345,10 @@ def session_buffers_async(self, capability: str | None = None) -> list[SessionBu
327345
def session_views_async(self) -> list[SessionView]:
328346
return list(self._session_views.values())
329347

348+
@requires_session
330349
def on_text_changed_async(self, change_count: int, changes: Iterable[sublime.TextChange]) -> None:
331-
session_views = self.session_views_async()
332-
if not session_views:
333-
return
334350
if self.view.is_primary():
335-
for sv in session_views:
351+
for sv in self.session_views_async():
336352
sv.on_text_changed_async(change_count, changes)
337353
self._on_view_updated_async()
338354

@@ -387,9 +403,8 @@ def on_activated_async(self) -> None:
387403
sb.set_inlay_hints_pending_refresh(needs_refresh=False)
388404
sb.do_inlay_hints_async(self.view)
389405

406+
@requires_session
390407
def on_selection_modified_async(self) -> None:
391-
if not self.session_views_async():
392-
return
393408
first_region, _ = self._update_stored_selection_async()
394409
if first_region is None:
395410
return
@@ -490,9 +505,8 @@ def on_query_context(self, key: str, operator: int, operand: Any, match_all: boo
490505
return operand == bool(session_view.session_buffer.get_document_link_at_point(self.view, position))
491506
return None
492507

508+
@requires_session
493509
def on_hover(self, point: int, hover_zone: int) -> None:
494-
if not self.session_views_async():
495-
return
496510
if self.view.is_popup_visible():
497511
return
498512
window = self.view.window()
@@ -534,9 +548,8 @@ def _on_hover_gutter_async(self, point: int) -> None:
534548
location=point,
535549
on_navigate=lambda href: self._on_navigate(href, point))
536550

551+
@requires_session
537552
def on_text_command(self, command_name: str, args: dict | None) -> tuple[str, dict] | None:
538-
if not self.session_views_async():
539-
return None
540553
if command_name == "auto_complete":
541554
self._auto_complete_triggered_manually = True
542555
elif command_name == "show_scope_name" and userprefs().semantic_highlighting:
@@ -551,9 +564,8 @@ def on_text_command(self, command_name: str, args: dict | None) -> tuple[str, di
551564
return ('paste', {})
552565
return None
553566

567+
@requires_session
554568
def on_post_text_command(self, command_name: str, args: dict[str, Any] | None) -> None:
555-
if not self.session_views_async():
556-
return
557569
if command_name == 'paste':
558570
format_on_paste = self.view.settings().get('lsp_format_on_paste', userprefs().lsp_format_on_paste)
559571
if format_on_paste and self.session_async("documentRangeFormattingProvider"):
@@ -566,9 +578,8 @@ def on_post_text_command(self, command_name: str, args: dict[str, Any] | None) -
566578
# hide the popup when `esc` or arrows are pressed pressed
567579
self.view.hide_popup()
568580

581+
@requires_session
569582
def on_query_completions(self, prefix: str, locations: list[int]) -> sublime.CompletionList | None:
570-
if not self.session_views_async():
571-
return None
572583
completion_list = sublime.CompletionList()
573584
triggered_manually = self._auto_complete_triggered_manually
574585
self._auto_complete_triggered_manually = False # reset state for next completion popup

0 commit comments

Comments
 (0)