diff --git a/plugin/documents.py b/plugin/documents.py index d1a1667a4..852076a00 100644 --- a/plugin/documents.py +++ b/plugin/documents.py @@ -25,10 +25,8 @@ from .core.url import parse_uri from .core.url import view_to_uri from .core.views import diagnostic_severity -from .core.views import document_color_params from .core.views import first_selection_region from .core.views import format_completion -from .core.views import lsp_color_to_phantom from .core.views import make_command_link from .core.views import range_to_region from .core.views import show_lsp_popup @@ -176,7 +174,6 @@ def _setup(self) -> None: self._manager = None # type: Optional[WindowManager] self._session_views = {} # type: Dict[str, SessionView] self._stored_region = sublime.Region(-1, -1) - self._color_phantoms = sublime.PhantomSet(self.view, "lsp_color") self._sighelp = None # type: Optional[SigHelp] self._registered = False @@ -186,7 +183,6 @@ def _cleanup(self) -> None: triggers = [trigger for trigger in triggers if 'server' not in trigger] settings.set("auto_complete_triggers", triggers) self._stored_region = sublime.Region(-1, -1) - self._color_phantoms.update([]) self.view.erase_status(AbstractViewListener.TOTAL_ERRORS_AND_WARNINGS_STATUS_KEY) self._clear_highlight_regions() self._clear_session_views_async() @@ -224,7 +220,6 @@ def on_session_initialized_async(self, session: Session) -> None: self.view.settings().set("lsp_active", True) added = True if added: - self._do_color_boxes_async() self._do_code_lenses_async() def on_session_shutdown_async(self, session: Session) -> None: @@ -322,8 +317,6 @@ def on_text_changed_async(self, change_count: int, changes: Iterable[sublime.Tex if userprefs().document_highlight_style: self._when_selection_remains_stable_async(self._do_highlights_async, current_region, after_ms=self.highlights_debounce_time) - self._when_selection_remains_stable_async(self._do_color_boxes_async, current_region, - after_ms=self.color_boxes_debounce_time) self.do_signature_help_async(manual=False) self._when_selection_remains_stable_async(self._do_code_lenses_async, current_region, after_ms=self.code_lenses_debounce_time) @@ -543,18 +536,6 @@ def _on_code_actions(self, responses: CodeActionsByConfigName) -> None: def _clear_code_actions_annotation(self) -> None: self.view.erase_regions(self.CODE_ACTIONS_KEY) - # --- textDocument/documentColor ----------------------------------------------------------------------------------- - - def _do_color_boxes_async(self) -> None: - session = self.session_async("colorProvider") - if session: - session.send_request_async( - Request.documentColor(document_color_params(self.view), self.view), self._on_color_boxes) - - def _on_color_boxes(self, response: Any) -> None: - color_infos = response if response else [] - self._color_phantoms.update([lsp_color_to_phantom(self.view, color_info) for color_info in color_infos]) - # --- textDocument/codeLens ---------------------------------------------------------------------------------------- def on_code_lens_capability_registered_async(self) -> None: diff --git a/plugin/session_buffer.py b/plugin/session_buffer.py index a3c827a49..227ca5f9c 100644 --- a/plugin/session_buffer.py +++ b/plugin/session_buffer.py @@ -2,6 +2,7 @@ from .core.protocol import DiagnosticSeverity from .core.protocol import DocumentUri from .core.protocol import Range +from .core.protocol import Request from .core.protocol import TextDocumentSyncKindFull from .core.protocol import TextDocumentSyncKindNone from .core.sessions import SessionViewProtocol @@ -10,13 +11,15 @@ from .core.types import debounced from .core.types import Debouncer from .core.types import FEATURES_TIMEOUT -from .core.typing import Any, Iterable, Optional, List, Dict, Tuple +from .core.typing import Any, Callable, Iterable, Optional, List, Dict, Tuple from .core.views import DIAGNOSTIC_SEVERITY from .core.views import diagnostic_severity from .core.views import did_change from .core.views import did_close from .core.views import did_open from .core.views import did_save +from .core.views import document_color_params +from .core.views import lsp_color_to_phantom from .core.views import MissingUriError from .core.views import range_to_region from .core.views import will_save @@ -81,6 +84,7 @@ def __init__(self, session_view: SessionViewProtocol, buffer_id: int, uri: Docum self.total_warnings = 0 self.should_show_diagnostics_panel = False self.diagnostics_debouncer = Debouncer() + self.color_phantoms = sublime.PhantomSet(view, "lsp_color") self._check_did_open(view) self.session.register_session_buffer_async(self) @@ -88,6 +92,7 @@ def __del__(self) -> None: mgr = self.session.manager() if mgr: mgr.update_diagnostics_panel_async() + self.color_phantoms.update([]) # If the session is exiting then there's no point in sending textDocument/didClose and there's also no point # in unregistering ourselves from the session. if not self.session.exiting: @@ -103,6 +108,7 @@ def _check_did_open(self, view: sublime.View) -> None: return self.session.send_notification(did_open(view, language_id)) self.opened = True + self._do_color_boxes_async(view, view.change_count()) self.session.notify_plugin_on_session_buffer_change(self) def _check_did_close(self) -> None: @@ -235,8 +241,10 @@ def purge_changes_async(self, view: sublime.View) -> None: notification = did_change(view, version, changes) self.session.send_notification(notification) except MissingUriError: - pass # we're closing - self.pending_changes = None + return # we're closing + finally: + self.pending_changes = None + self._do_color_boxes_async(view, version) self.session.notify_plugin_on_session_buffer_change(self) def on_pre_save_async(self, view: sublime.View) -> None: @@ -265,6 +273,32 @@ def some_view(self) -> Optional[sublime.View]: return sv.view return None + def _if_view_unchanged(self, f: Callable[[sublime.View, Any], None], version: int) -> Callable[[Any], None]: + """ + Ensures that the view is at the same version when we were called, before calling the `f` function. + """ + def handler(*args: Any) -> None: + view = self.some_view() + if view and view.change_count() == version: + f(view, *args) + + return handler + + # --- textDocument/documentColor ----------------------------------------------------------------------------------- + + def _do_color_boxes_async(self, view: sublime.View, version: int) -> None: + if self.session.has_capability("colorProvider"): + self.session.send_request_async( + Request.documentColor(document_color_params(view), view), + self._if_view_unchanged(self._on_color_boxes_async, version) + ) + + def _on_color_boxes_async(self, view: sublime.View, response: Any) -> None: + color_infos = response if response else [] + self.color_phantoms.update([lsp_color_to_phantom(view, color_info) for color_info in color_infos]) + + # --- textDocument/publishDiagnostics ------------------------------------------------------------------------------ + def on_diagnostics_async(self, raw_diagnostics: List[Diagnostic], version: Optional[int]) -> None: data_per_severity = {} # type: Dict[Tuple[int, bool], DiagnosticSeverityData] total_errors = 0 diff --git a/unittesting.json b/unittesting.json index bc526bed2..5d550ba89 100644 --- a/unittesting.json +++ b/unittesting.json @@ -3,7 +3,7 @@ "verbosity": 2, "capture_console": true, "failfast": false, - "reload_package_on_testing": true, + "reload_package_on_testing": false, "start_coverage_after_reload": false, "show_reload_progress": false, "output": null,