Skip to content

Commit

Permalink
feat: add GlobalLspListener
Browse files Browse the repository at this point in the history
  • Loading branch information
rchl committed Sep 29, 2024
1 parent 603632e commit 770d53c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
6 changes: 6 additions & 0 deletions plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
from .core.protocol import Notification
from .core.protocol import Request
from .core.protocol import Response
from .core.registry import AbstractViewListener
from .core.registry import LspTextCommand
from .core.registry import LspWindowCommand
from .core.registry import windows
from .core.sessions import AbstractPlugin
from .core.sessions import register_plugin
from .core.sessions import Session
Expand All @@ -24,12 +26,14 @@
from .core.version import __version__
from .core.views import MarkdownLangMap
from .core.views import uri_from_view
from .core.windows import GlobalLspListener
from .core.workspace import WorkspaceFolder

# This is the public API for LSP-* packages
__all__ = [
'__version__',
'AbstractPlugin',
'AbstractViewListener',
'apply_text_edits',
'ClientConfig',
'css',
Expand All @@ -39,6 +43,7 @@
'FileWatcherEvent',
'FileWatcherEventType',
'FileWatcherProtocol',
'GlobalLspListener',
'LspTextCommand',
'LspWindowCommand',
'MarkdownLangMap',
Expand All @@ -54,5 +59,6 @@
'unregister_plugin',
'uri_from_view',
'uri_to_filename', # deprecated
'windows',
'WorkspaceFolder',
]
45 changes: 42 additions & 3 deletions plugin/core/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
from .views import make_link
from .workspace import ProjectFolders
from .workspace import sorted_workspace_folders
from abc import ABCMeta
from abc import abstractmethod
from collections import deque
from collections import OrderedDict
from datetime import datetime
Expand Down Expand Up @@ -70,11 +72,29 @@ def set_diagnostics_count(view: sublime.View, errors: int, warnings: int) -> Non
pass


class GlobalLspListener(metaclass=ABCMeta):

@abstractmethod
def on_session_initialized_async(self, view_listener: AbstractViewListener, session: Session) -> None:
raise NotImplementedError()

@abstractmethod
def on_session_shutdown_async(self, view_listener: AbstractViewListener, session: Session) -> None:
raise NotImplementedError()


class WindowManager(Manager, WindowConfigChangeListener):

def __init__(self, window: sublime.Window, workspace: ProjectFolders, config_manager: WindowConfigManager) -> None:
def __init__(
self,
window: sublime.Window,
workspace: ProjectFolders,
config_manager: WindowConfigManager,
global_listener: GlobalLspListener,
) -> None:
self._window = window
self._config_manager = config_manager
self._global_listener = global_listener
self._sessions: set[Session] = set()
self._workspace = workspace
self._pending_listeners: deque[AbstractViewListener] = deque()
Expand Down Expand Up @@ -198,6 +218,8 @@ def _publish_sessions_to_listener_async(self, listener: AbstractViewListener) ->
except Exception as ex:
message = f"failed to register session {session.config.name} to listener {listener}"
exception_log(message, ex)
return
self._global_listener.on_session_initialized_async(listener, session)

def sessions(self, view: sublime.View, capability: str | None = None) -> Generator[Session, None, None]:
inside_workspace = self._workspace.contains(view)
Expand Down Expand Up @@ -387,6 +409,7 @@ def on_post_exit_async(self, session: Session, exit_code: int, exception: Except
self._sessions.discard(session)
for listener in self._listeners:
listener.on_session_shutdown_async(session)
self._global_listener.on_session_shutdown_async(listener, session)
if exit_code != 0 or exception:
config = session.config
restart = self._config_manager.record_crash(config.name, exit_code, exception)
Expand Down Expand Up @@ -518,12 +541,19 @@ def on_configs_changed(self, config_name: str | None = None) -> None:
sublime.set_timeout_async(lambda: self.restart_sessions_async(config_name))


class WindowRegistry:
class WindowRegistry(GlobalLspListener):
def __init__(self) -> None:
self._enabled = False
self._windows: dict[int, WindowManager] = {}
self._global_listeners: set[GlobalLspListener] = set()
client_configs.set_listener(self._on_client_config_updated)

def add_global_listener(self, listener: GlobalLspListener) -> None:
self._global_listeners.add(listener)

def remove_global_listener(self, listener: GlobalLspListener) -> None:
self._global_listeners.discard(listener)

def _on_client_config_updated(self, config_name: str | None = None) -> None:
for wm in self._windows.values():
wm.get_config_manager().update(config_name)
Expand Down Expand Up @@ -551,7 +581,7 @@ def lookup(self, window: sublime.Window | None) -> WindowManager | None:
return wm
workspace = ProjectFolders(window)
window_config_manager = WindowConfigManager(window, client_configs.all)
manager = WindowManager(window, workspace, window_config_manager)
manager = WindowManager(window, workspace, window_config_manager, self)
self._windows[window.id()] = manager
return manager

Expand All @@ -566,6 +596,15 @@ def discard(self, window: sublime.Window) -> None:
if wm:
sublime.set_timeout_async(wm.destroy)

# --- Implements GlobalLspListener ---------------------------------------------------------------------------------

def on_session_initialized_async(self, view_listener: AbstractViewListener, session: Session) -> None:
for listener in self._global_listeners:
listener.on_session_initialized_async(view_listener, session)

def on_session_shutdown_async(self, view_listener: AbstractViewListener, session: Session) -> None:
for listener in self._global_listeners:
listener.on_session_shutdown_async(view_listener, session)

class RequestTimeTracker:
def __init__(self) -> None:
Expand Down

0 comments on commit 770d53c

Please sign in to comment.