Skip to content

Commit

Permalink
Merge branch 'fix-notification-order' into workspace-edit-preserve-tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
jwortmann committed Apr 14, 2024
2 parents 37d1f66 + 2b5f56f commit 7b71db2
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 40 deletions.
2 changes: 1 addition & 1 deletion plugin/core/input_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def get_list_items(self) -> ListItemsReturn:
class DynamicListInputHandler(sublime_plugin.ListInputHandler, metaclass=ABCMeta):
""" A ListInputHandler which can update its items while typing in the input field.
Subclasses of PreselectedListInputHandler must not implement the `list_items` method, but can override
Subclasses of DynamicListInputHandler must not implement the `list_items` method, but can override
`get_list_items` for the initial list items. The `on_modified` method will be called after a small delay (debounced)
whenever changes were made to the input text. You can use this to call the `update` method with a list of
`ListInputItem`s to update the list items.
Expand Down
5 changes: 4 additions & 1 deletion plugin/core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,10 @@ def should_ignore(cls, view: sublime.View) -> bool:
"""
Exclude a view from being handled by the language server, even if it matches the URI scheme(s) and selector from
the configuration. This can be used to, for example, ignore certain file patterns which are listed in a
configuration file (e.g. .gitignore).
configuration file (e.g. .gitignore). Please note that this also means that no document syncronization
notifications (textDocument/didOpen, textDocument/didChange, textDocument/didClose, etc.) are sent to the server
for ignored views, when they are opened in the editor. Therefore this method should be used with caution for
language servers which index all files in the workspace.
"""
return False

Expand Down
29 changes: 16 additions & 13 deletions plugin/session_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def purge_changes_async(self, view: sublime.View, suppress_requests: bool = Fals
return
if sync_kind == TextDocumentSyncKind.Full:
changes = None
version = view.change_count() if view.is_valid() else self._pending_changes.version
version = view.change_count() or self._pending_changes.version
else:
changes = self._pending_changes.changes
version = self._pending_changes.version
Expand All @@ -336,19 +336,22 @@ def _on_after_change_async(self, view: sublime.View, version: int, suppress_requ
if self._is_saving:
self._has_changed_during_save = True
return
if suppress_requests or not view.is_valid():
if suppress_requests:
return
self._do_color_boxes_async(view, version)
self.do_document_diagnostic_async(view, version)
if self.session.config.diagnostics_mode == "workspace" and \
not self.session.workspace_diagnostics_pending_response and \
self.session.has_capability('diagnosticProvider.workspaceDiagnostics'):
self._workspace_diagnostics_debouncer_async.debounce(
self.session.do_workspace_diagnostics_async, timeout_ms=WORKSPACE_DIAGNOSTICS_TIMEOUT)
self.do_semantic_tokens_async(view)
if userprefs().link_highlight_style in ("underline", "none"):
self._do_document_link_async(view, version)
self.do_inlay_hints_async(view)
try:
self._do_color_boxes_async(view, version)
self.do_document_diagnostic_async(view, version)
if self.session.config.diagnostics_mode == "workspace" and \
not self.session.workspace_diagnostics_pending_response and \
self.session.has_capability('diagnosticProvider.workspaceDiagnostics'):
self._workspace_diagnostics_debouncer_async.debounce(
self.session.do_workspace_diagnostics_async, timeout_ms=WORKSPACE_DIAGNOSTICS_TIMEOUT)
self.do_semantic_tokens_async(view)
if userprefs().link_highlight_style in ("underline", "none"):
self._do_document_link_async(view, version)
self.do_inlay_hints_async(view)
except MissingUriError:
pass

def on_pre_save_async(self, view: sublime.View) -> None:
self._is_saving = True
Expand Down
73 changes: 48 additions & 25 deletions tests/test_single_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,31 +84,6 @@ def test_did_close(self) -> 'Generator':
self.view.close()
yield from self.await_message("textDocument/didClose")

def test_did_change(self) -> 'Generator':
assert self.view
self.maxDiff = None
self.insert_characters("A")
yield from self.await_message("textDocument/didChange")
# multiple changes are batched into one didChange notification
self.insert_characters("B\n")
self.insert_characters("🙂\n")
self.insert_characters("D")
promise = YieldPromise()
yield from self.await_message("textDocument/didChange", promise)
self.assertEqual(promise.result(), {
'contentChanges': [
{'rangeLength': 0, 'range': {'start': {'line': 0, 'character': 1}, 'end': {'line': 0, 'character': 1}}, 'text': 'B'}, # noqa
{'rangeLength': 0, 'range': {'start': {'line': 0, 'character': 2}, 'end': {'line': 0, 'character': 2}}, 'text': '\n'}, # noqa
{'rangeLength': 0, 'range': {'start': {'line': 1, 'character': 0}, 'end': {'line': 1, 'character': 0}}, 'text': '🙂'}, # noqa
# Note that this is character offset (2) is correct (UTF-16).
{'rangeLength': 0, 'range': {'start': {'line': 1, 'character': 2}, 'end': {'line': 1, 'character': 2}}, 'text': '\n'}, # noqa
{'rangeLength': 0, 'range': {'start': {'line': 2, 'character': 0}, 'end': {'line': 2, 'character': 0}}, 'text': 'D'}], # noqa
'textDocument': {
'version': self.view.change_count(),
'uri': filename_to_uri(TEST_FILE_PATH)
}
})

def test_sends_save_with_purge(self) -> 'Generator':
assert self.view
self.view.settings().set("lsp_format_on_save", False)
Expand Down Expand Up @@ -371,6 +346,54 @@ def test_progress(self) -> 'Generator':
self.assertEqual(result, {"general": "kenobi"})


class SingleDocumentTestCase2(TextDocumentTestCase):

def test_did_change(self) -> 'Generator':
assert self.view
self.maxDiff = None
self.insert_characters("A")
yield from self.await_message("textDocument/didChange")
# multiple changes are batched into one didChange notification
self.insert_characters("B\n")
self.insert_characters("🙂\n")
self.insert_characters("D")
promise = YieldPromise()
yield from self.await_message("textDocument/didChange", promise)
self.assertEqual(promise.result(), {
'contentChanges': [
{'rangeLength': 0, 'range': {'start': {'line': 0, 'character': 1}, 'end': {'line': 0, 'character': 1}}, 'text': 'B'}, # noqa
{'rangeLength': 0, 'range': {'start': {'line': 0, 'character': 2}, 'end': {'line': 0, 'character': 2}}, 'text': '\n'}, # noqa
{'rangeLength': 0, 'range': {'start': {'line': 1, 'character': 0}, 'end': {'line': 1, 'character': 0}}, 'text': '🙂'}, # noqa
# Note that this is character offset (2) is correct (UTF-16).
{'rangeLength': 0, 'range': {'start': {'line': 1, 'character': 2}, 'end': {'line': 1, 'character': 2}}, 'text': '\n'}, # noqa
{'rangeLength': 0, 'range': {'start': {'line': 2, 'character': 0}, 'end': {'line': 2, 'character': 0}}, 'text': 'D'}], # noqa
'textDocument': {
'version': self.view.change_count(),
'uri': filename_to_uri(TEST_FILE_PATH)
}
})


class SingleDocumentTestCase3(TextDocumentTestCase):

@classmethod
def get_test_name(cls) -> str:
return "testfile2"

def test_did_change_before_did_close(self) -> 'Generator':
assert self.view
self.view.window().run_command("chain", {
"commands": [
["insert", {"characters": "TEST"}],
["save", {"async": False}],
["close", {}]
]
})
yield from self.await_message('textDocument/didChange')
# yield from self.await_message('textDocument/didSave') # TODO why is this not sent?
yield from self.await_message('textDocument/didClose')


class WillSaveWaitUntilTestCase(TextDocumentTestCase):

@classmethod
Expand Down
Empty file added tests/testfile2.txt
Empty file.

0 comments on commit 7b71db2

Please sign in to comment.