Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
bivashy authored Oct 22, 2024
2 parents e5b9050 + fbbbd77 commit c4c74cc
Show file tree
Hide file tree
Showing 16 changed files with 850 additions and 332 deletions.
Binary file removed .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
LSP.sublime-workspace
LSP.sublime-project
.DS_Store
.mypy_cache
.pytest_cache
.tox
Expand Down
10 changes: 7 additions & 3 deletions plugin/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def __init__(
view: sublime.View,
location: int,
triggered_manually: bool,
on_done_async: Callable[[list[sublime.CompletionItem], int], None]
on_done_async: Callable[[list[sublime.CompletionItem], sublime.AutoCompleteFlags], None]
) -> None:
self._view = view
self._location = location
Expand Down Expand Up @@ -212,7 +212,7 @@ def _resolve_completions_async(self, responses: list[ResolvedCompletions]) -> No
items: list[sublime.CompletionItem] = []
item_defaults: CompletionItemDefaults = {}
errors: list[Error] = []
flags = 0
flags = sublime.AutoCompleteFlags.NONE
prefs = userprefs()
if prefs.inhibit_snippet_completions:
flags |= sublime.INHIBIT_EXPLICIT_COMPLETIONS
Expand Down Expand Up @@ -263,7 +263,11 @@ def _cancel_pending_requests_async(self) -> None:
session.cancel_request(request_id, False)
self._pending_completion_requests.clear()

def _resolve_task_async(self, completions: list[sublime.CompletionItem], flags: int = 0) -> None:
def _resolve_task_async(
self,
completions: list[sublime.CompletionItem],
flags: sublime.AutoCompleteFlags = sublime.AutoCompleteFlags.NONE
) -> None:
if not self._resolved:
self._resolved = True
self._on_done_async(completions, flags)
Expand Down
4 changes: 2 additions & 2 deletions plugin/core/open.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def lsp_range_from_uri_fragment(fragment: str) -> Range | None:


def open_file_uri(
window: sublime.Window, uri: DocumentUri, flags: int = 0, group: int = -1
window: sublime.Window, uri: DocumentUri, flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE, group: int = -1
) -> Promise[sublime.View | None]:

decoded_uri = unquote(uri) # decode percent-encoded characters
Expand Down Expand Up @@ -84,7 +84,7 @@ def _find_open_file(window: sublime.Window, fname: str, group: int = -1) -> subl


def open_file(
window: sublime.Window, uri: DocumentUri, flags: int = 0, group: int = -1
window: sublime.Window, uri: DocumentUri, flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE, group: int = -1
) -> Promise[sublime.View | None]:
"""
Open a file asynchronously.
Expand Down
4 changes: 2 additions & 2 deletions plugin/core/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def run(
self,
location: Location | LocationLink,
session_name: str | None = None,
flags: int = 0,
flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE,
group: int = -1,
event: dict | None = None
) -> None:
Expand All @@ -191,7 +191,7 @@ def want_event(self) -> bool:
return True

def _run_async(
self, location: Location | LocationLink, session_name: str | None, flags: int, group: int
self, location: Location | LocationLink, session_name: str | None, flags: sublime.NewFileFlags, group: int
) -> None:
session = self.session_by_name(session_name) if session_name else self.session()
if session:
Expand Down
16 changes: 10 additions & 6 deletions plugin/core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1686,7 +1686,7 @@ def try_open_uri_async(
self,
uri: DocumentUri,
r: Range | None = None,
flags: int = 0,
flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE,
group: int = -1
) -> Promise[sublime.View | None] | None:
if uri.startswith("file:"):
Expand All @@ -1708,7 +1708,7 @@ def open_uri_async(
self,
uri: DocumentUri,
r: Range | None = None,
flags: int = 0,
flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE,
group: int = -1
) -> Promise[sublime.View | None]:
promise = self.try_open_uri_async(uri, r, flags, group)
Expand All @@ -1718,7 +1718,7 @@ def _open_file_uri_async(
self,
uri: DocumentUri,
r: Range | None = None,
flags: int = 0,
flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE,
group: int = -1
) -> Promise[sublime.View | None]:
result: PackagedTask[sublime.View | None] = Promise.packaged_task()
Expand All @@ -1736,7 +1736,7 @@ def _open_uri_with_plugin_async(
plugin: AbstractPlugin,
uri: DocumentUri,
r: Range | None,
flags: int,
flags: sublime.NewFileFlags,
group: int,
) -> Promise[sublime.View | None] | None:
# I cannot type-hint an unpacked tuple
Expand Down Expand Up @@ -1765,8 +1765,12 @@ def open_scratch_buffer(title: str, content: str, syntax: str) -> None:
return result[0]
return None

def open_location_async(self, location: Location | LocationLink, flags: int = 0,
group: int = -1) -> Promise[sublime.View | None]:
def open_location_async(
self,
location: Location | LocationLink,
flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE,
group: int = -1
) -> Promise[sublime.View | None]:
uri, r = get_uri_and_range_from_location(location)
return self.open_uri_async(uri, r, flags, group)

Expand Down
8 changes: 4 additions & 4 deletions plugin/core/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ def r(name: str, default: bool | int | str | list | dict) -> None:

set_debug_logging(self.log_debug)

def highlight_style_region_flags(self, style_str: str) -> tuple[int, int]:
def highlight_style_region_flags(self, style_str: str) -> tuple[sublime.RegionFlags, sublime.RegionFlags]:
default = sublime.NO_UNDO
if style_str in ("background", "fill"): # Backwards-compatible with "fill"
style = default | sublime.DRAW_NO_OUTLINE
Expand All @@ -341,7 +341,7 @@ def highlight_style_region_flags(self, style_str: str) -> tuple[int, int]:
return default | sublime.DRAW_NO_FILL, default | sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE | sublime.DRAW_SOLID_UNDERLINE # noqa: E501

@staticmethod
def _style_str_to_flag(style_str: str) -> int | None:
def _style_str_to_flag(style_str: str) -> sublime.RegionFlags | None:
default = sublime.DRAW_EMPTY_AS_OVERWRITE | sublime.DRAW_NO_FILL | sublime.NO_UNDO
# This method could be a dict or lru_cache
if style_str == "":
Expand All @@ -357,13 +357,13 @@ def _style_str_to_flag(style_str: str) -> int | None:
# default style (includes NO_UNDO)
return None

def diagnostics_highlight_style_flags(self) -> list[int | None]:
def diagnostics_highlight_style_flags(self) -> list[sublime.RegionFlags | None]:
"""Returns flags for highlighting diagnostics on single lines per severity"""
if isinstance(self.diagnostics_highlight_style, str):
# same style for all severity levels
return [self._style_str_to_flag(self.diagnostics_highlight_style)] * 4
elif isinstance(self.diagnostics_highlight_style, dict):
flags: list[int | None] = []
flags: list[sublime.RegionFlags | None] = []
for sev in ("error", "warning", "info", "hint"):
user_style = self.diagnostics_highlight_style.get(sev)
if user_style is None: # user did not provide a style
Expand Down
4 changes: 2 additions & 2 deletions plugin/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
_baseflags = sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE | sublime.DRAW_EMPTY_AS_OVERWRITE | sublime.NO_UNDO
_multilineflags = sublime.DRAW_NO_FILL | sublime.NO_UNDO

DIAGNOSTIC_SEVERITY: list[tuple[str, str, str, str, int, int]] = [
DIAGNOSTIC_SEVERITY: list[tuple[str, str, str, str, sublime.RegionFlags, sublime.RegionFlags]] = [
# Kind CSS class Scope for color Icon resource add_regions flags for single-line diagnostic multi-line diagnostic # noqa: E501
("error", "errors", "region.redish markup.error.lsp", "Packages/LSP/icons/error.png", _baseflags | sublime.DRAW_SQUIGGLY_UNDERLINE, _multilineflags), # noqa: E501
("warning", "warnings", "region.yellowish markup.warning.lsp", "Packages/LSP/icons/warning.png", _baseflags | sublime.DRAW_SQUIGGLY_UNDERLINE, _multilineflags), # noqa: E501
Expand Down Expand Up @@ -429,7 +429,7 @@ def show_lsp_popup(
*,
location: int = -1,
md: bool = False,
flags: int = 0,
flags: sublime.PopupFlags = sublime.PopupFlags.NONE,
css: str | None = None,
wrapper_class: str | None = None,
body_id: str | None = None,
Expand Down
40 changes: 36 additions & 4 deletions plugin/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@
from .session_buffer import SessionBuffer
from .session_view import SessionView
from functools import partial
from typing import Any, Callable, Generator, Iterable
from functools import wraps
from typing import Any, Callable, Generator, Iterable, TypeVar
from typing import cast
from typing_extensions import Concatenate, ParamSpec
from weakref import WeakSet
from weakref import WeakValueDictionary
import itertools
Expand All @@ -68,6 +70,24 @@

SUBLIME_WORD_MASK = 515

P = ParamSpec('P')
R = TypeVar('R')


def requires_session(
func: Callable[Concatenate[DocumentSyncListener, P], R]
) -> Callable[Concatenate[DocumentSyncListener, P], R | None]:
"""
A decorator for the `DocumentSyncListener` event handlers, which immediately returns `None` if there are no
`SessionView`s.
"""
@wraps(func)
def wrapper(self: DocumentSyncListener, *args: P.args, **kwargs: P.kwargs) -> R | None:
if not self.session_views_async():
return None
return func(self, *args, **kwargs)
return wrapper


def is_regular_view(v: sublime.View) -> bool:
# Not from the quick panel (CTRL+P), and not a special view like a console, output panel or find-in-files panels.
Expand All @@ -86,7 +106,7 @@ def is_regular_view(v: sublime.View) -> bool:
def previous_non_whitespace_char(view: sublime.View, pt: int) -> str:
prev = view.substr(pt - 1)
if prev.isspace():
return view.substr(view.find_by_class(pt, False, ~0) - 1)
return view.substr(view.find_by_class(pt, False, ~0) - 1) # type: ignore
return prev


Expand Down Expand Up @@ -327,6 +347,7 @@ def session_buffers_async(self, capability: str | None = None) -> list[SessionBu
def session_views_async(self) -> list[SessionView]:
return list(self._session_views.values())

@requires_session
def on_text_changed_async(self, change_count: int, changes: Iterable[sublime.TextChange]) -> None:
if self.view.is_primary():
for sv in self.session_views_async():
Expand Down Expand Up @@ -364,9 +385,12 @@ def on_activated_async(self) -> None:
return
if not self._registered:
self._register_async()
session_views = self.session_views_async()
if not session_views:
return
if userprefs().show_code_actions:
self._do_code_actions_async()
for sv in self.session_views_async():
for sv in session_views:
if sv.code_lenses_needs_refresh:
sv.set_code_lenses_pending_refresh(needs_refresh=False)
sv.start_code_lenses_async()
Expand All @@ -381,6 +405,7 @@ def on_activated_async(self) -> None:
sb.set_inlay_hints_pending_refresh(needs_refresh=False)
sb.do_inlay_hints_async(self.view)

@requires_session
def on_selection_modified_async(self) -> None:
first_region, _ = self._update_stored_selection_async()
if first_region is None:
Expand Down Expand Up @@ -482,6 +507,7 @@ def on_query_context(self, key: str, operator: int, operand: Any, match_all: boo
return operand == bool(session_view.session_buffer.get_document_link_at_point(self.view, position))
return None

@requires_session
def on_hover(self, point: int, hover_zone: int) -> None:
if self.view.is_popup_visible():
return
Expand Down Expand Up @@ -524,6 +550,7 @@ def _on_hover_gutter_async(self, point: int) -> None:
location=point,
on_navigate=lambda href: self._on_navigate(href, point))

@requires_session
def on_text_command(self, command_name: str, args: dict | None) -> tuple[str, dict] | None:
if command_name == "auto_complete":
self._auto_complete_triggered_manually = True
Expand All @@ -539,6 +566,7 @@ def on_text_command(self, command_name: str, args: dict | None) -> tuple[str, di
return ('paste', {})
return None

@requires_session
def on_post_text_command(self, command_name: str, args: dict[str, Any] | None) -> None:
if command_name == 'paste':
format_on_paste = self.view.settings().get('lsp_format_on_paste', userprefs().lsp_format_on_paste)
Expand All @@ -552,6 +580,7 @@ def on_post_text_command(self, command_name: str, args: dict[str, Any] | None) -
# hide the popup when `esc` or arrows are pressed pressed
self.view.hide_popup()

@requires_session
def on_query_completions(self, prefix: str, locations: list[int]) -> sublime.CompletionList | None:
completion_list = sublime.CompletionList()
triggered_manually = self._auto_complete_triggered_manually
Expand All @@ -577,7 +606,10 @@ def _on_query_completions_async(
self._completions_task.query_completions_async(sessions)

def _on_query_completions_resolved_async(
self, clist: sublime.CompletionList, completions: list[sublime.CompletionItem], flags: int = 0
self,
clist: sublime.CompletionList,
completions: list[sublime.CompletionItem],
flags: sublime.AutoCompleteFlags = sublime.AutoCompleteFlags.NONE
) -> None:
self._completions_task = None
# Resolve on the main thread to prevent any sort of data race for _set_target (see sublime_plugin.py).
Expand Down
10 changes: 8 additions & 2 deletions plugin/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ def is_applicable(cls, view: sublime.View) -> bool:
def run_async(self) -> None:
super().run_async()
self._purge_changes_async()
base_scope = self._task_runner.view.syntax().scope
syntax = self._task_runner.view.syntax()
if not syntax:
return
base_scope = syntax.scope
formatter = get_formatter(self._task_runner.view.window(), base_scope)
format_document(self._task_runner, formatter).then(self._on_response)

Expand All @@ -121,7 +124,10 @@ def is_enabled(self, event: dict | None = None, select: bool = False) -> bool:

def run(self, edit: sublime.Edit, event: dict | None = None, select: bool = False) -> None:
session_names = [session.config.name for session in self.sessions(self.capability)]
base_scope = self.view.syntax().scope
syntax = self.view.syntax()
if not syntax:
return
base_scope = syntax.scope
if select:
self.select_formatter(base_scope, session_names)
elif len(session_names) > 1:
Expand Down
2 changes: 1 addition & 1 deletion plugin/goto.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ def run(
fallback: bool = False,
group: int = -1
) -> None:
session = self.best_session(self.capability)
position = get_position(self.view, event, point)
session = self.best_session(self.capability, position)
if session and position is not None:
params = text_document_position_params(self.view, position)
request = Request(self.method, params, self.view, progress=True)
Expand Down
4 changes: 3 additions & 1 deletion plugin/goto_diagnostic.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ def diagnostic_location(parsed_uri: ParsedUri, diagnostic: Diagnostic) -> Locati
}


def open_location(session: Session, location: Location, flags: int = 0, group: int = -1) -> sublime.View:
def open_location(
session: Session, location: Location, flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE, group: int = -1
) -> sublime.View:
uri, position = get_uri_and_position_from_location(location)
file_name = to_encoded_filename(session.config.map_server_uri_to_client_path(uri), position)
return session.window.open_file(file_name, flags=flags | sublime.ENCODED_POSITION, group=group)
Expand Down
2 changes: 1 addition & 1 deletion plugin/locationpicker.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def open_basic_file(
session: Session,
uri: str,
position: Position,
flags: int = 0,
flags: sublime.NewFileFlags = sublime.NewFileFlags.NONE,
group: int | None = None
) -> sublime.View | None:
if group is None:
Expand Down
2 changes: 1 addition & 1 deletion plugin/session_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def _draw_diagnostics(
self,
severity: int,
max_severity_level: int,
flags: int,
flags: sublime.RegionFlags,
multiline: bool
) -> None:
ICON_FLAGS = sublime.HIDE_ON_MINIMAP | sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE | sublime.NO_UNDO
Expand Down
Loading

0 comments on commit c4c74cc

Please sign in to comment.