Skip to content

Commit

Permalink
refactor: use native types and f-string
Browse files Browse the repository at this point in the history
Signed-off-by: Jack Cherng <[email protected]>
  • Loading branch information
jfcherng committed Apr 21, 2024
1 parent 4c8da78 commit 5672752
Show file tree
Hide file tree
Showing 69 changed files with 1,253 additions and 1,275 deletions.
6 changes: 3 additions & 3 deletions boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
from typing import Any, Dict, List, Optional, Type


def _get_final_subclasses(derived: List[Type], results: List[Type]) -> None:
def _get_final_subclasses(derived: list[type], results: list[type]) -> None:
for d in derived:
d_subclasses = d.__subclasses__()
if len(d_subclasses) > 0:
Expand All @@ -99,7 +99,7 @@ def _get_final_subclasses(derived: List[Type], results: List[Type]) -> None:


def _register_all_plugins() -> None:
plugin_classes: List[Type[AbstractPlugin]] = []
plugin_classes: list[type[AbstractPlugin]] = []
_get_final_subclasses(AbstractPlugin.__subclasses__(), plugin_classes)
for plugin_class in plugin_classes:
try:
Expand Down Expand Up @@ -187,7 +187,7 @@ def on_pre_close(self, view: sublime.View) -> None:
tup[1](None)
break

def on_post_window_command(self, window: sublime.Window, command_name: str, args: Optional[Dict[str, Any]]) -> None:
def on_post_window_command(self, window: sublime.Window, command_name: str, args: dict[str, Any] | None) -> None:
if command_name == "show_panel":
wm = windows.lookup(window)
if not wm:
Expand Down
119 changes: 59 additions & 60 deletions plugin/code_actions.py

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions plugin/code_lens.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class LspToggleCodeLensesCommand(LspWindowCommand):
capability = 'codeLensProvider'

@classmethod
def are_enabled(cls, window: Optional[sublime.Window]) -> bool:
def are_enabled(cls, window: sublime.Window | None) -> bool:
if not window:
return False
return bool(window.settings().get(CODE_LENS_ENABLED_KEY, True))
Expand Down Expand Up @@ -63,7 +63,7 @@ def __init__(self, data: CodeLens, view: sublime.View, session_name: str) -> Non
self.is_resolve_error = False

def __repr__(self) -> str:
return 'CodeLensData(resolved={0}, region={1!r})'.format(self.is_resolved(), self.region)
return f'CodeLensData(resolved={self.is_resolved()}, region={self.region!r})'

def is_resolved(self) -> bool:
"""A code lens is considered resolved if the inner data contains the 'command' key."""
Expand All @@ -76,7 +76,7 @@ def to_lsp(self) -> CodeLensExtended:

@property
def small_html(self) -> str:
return '<small style="font-family: system">{}</small>'.format(self.annotation)
return f'<small style="font-family: system">{self.annotation}</small>'

def resolve_annotation(self, view_id: int) -> None:
command = self.data.get('command')
Expand All @@ -93,7 +93,7 @@ def resolve_annotation(self, view_id: int) -> None:
else:
self.annotation = '...'

def resolve(self, view: sublime.View, code_lens_or_error: Union[CodeLens, Error]) -> None:
def resolve(self, view: sublime.View, code_lens_or_error: CodeLens | Error) -> None:
if isinstance(code_lens_or_error, Error):
self.is_resolve_error = True
self.annotation = '<span style="color: color(var(--redish)">error</span>'
Expand All @@ -110,7 +110,7 @@ def __init__(self, view: sublime.View) -> None:
self.view = view
self._init = False
self._phantom = sublime.PhantomSet(view, self.CODE_LENS_KEY)
self._code_lenses: Dict[Tuple[int, int], List[CodeLensData]] = {}
self._code_lenses: dict[tuple[int, int], list[CodeLensData]] = {}

def clear(self) -> None:
self._code_lenses.clear()
Expand All @@ -126,17 +126,17 @@ def _clear_annotations(self) -> None:
self.view.erase_regions(self._region_key(lens.session_name, index))

def _region_key(self, session_name: str, index: int) -> str:
return '{0}.{1}.{2}'.format(self.CODE_LENS_KEY, session_name, index)
return f'{self.CODE_LENS_KEY}.{session_name}.{index}'

def clear_view(self) -> None:
self._phantom.update([])
self._clear_annotations()

def handle_response(self, session_name: str, response: List[CodeLens]) -> None:
def handle_response(self, session_name: str, response: list[CodeLens]) -> None:
self._init = True
responses = [CodeLensData(data, self.view, session_name) for data in response]
responses.sort(key=lambda c: c.region)
result: Dict[Tuple[int, int], List[CodeLensData]] = {
result: dict[tuple[int, int], list[CodeLensData]] = {
region.to_tuple(): list(groups)
for region, groups in itertools.groupby(responses, key=lambda c: c.region)
}
Expand Down Expand Up @@ -217,7 +217,7 @@ def run(self, edit: sublime.Edit) -> None:
listener = windows.listener_for_view(self.view)
if not listener:
return
code_lenses: List[CodeLensExtended] = []
code_lenses: list[CodeLensExtended] = []
for region in self.view.sel():
for sv in listener.session_views_async():
code_lenses.extend(sv.get_resolved_code_lenses_for_region(region))
Expand All @@ -240,7 +240,7 @@ def run(self, edit: sublime.Edit) -> None:
lambda i: self.on_select(code_lenses, i)
)

def on_select(self, code_lenses: List[CodeLensExtended], index: int) -> None:
def on_select(self, code_lenses: list[CodeLensExtended], index: int) -> None:
try:
code_lens = code_lenses[index]
except IndexError:
Expand Down
4 changes: 2 additions & 2 deletions plugin/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def run(self, edit: sublime.Edit, color_information: ColorInformation) -> None:
def want_event(self) -> bool:
return False

def _handle_response_async(self, response: List[ColorPresentation]) -> None:
def _handle_response_async(self, response: list[ColorPresentation]) -> None:
if not response:
return
window = self.view.window()
Expand All @@ -39,7 +39,7 @@ def _handle_response_async(self, response: List[ColorPresentation]) -> None:
if self._version != self.view.change_count():
return
old_text = self.view.substr(range_to_region(self._range, self.view))
self._filtered_response: List[ColorPresentation] = []
self._filtered_response: list[ColorPresentation] = []
for item in response:
# Filter out items that would apply no change
text_edit = item.get('textEdit')
Expand Down
51 changes: 25 additions & 26 deletions plugin/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,12 @@ def format_completion(
lsp_detail = (item.get('detail') or "").replace("\n", " ")
completion_kind = item.get('kind')
kind = COMPLETION_KINDS.get(completion_kind, sublime.KIND_AMBIGUOUS) if completion_kind else sublime.KIND_AMBIGUOUS
details: List[str] = []
details: list[str] = []
if can_resolve_completion_items or item.get('documentation'):
# Not using "make_command_link" in a hot path to avoid slow json.dumps.
args = '{{"view_id":{},"command":"lsp_resolve_docs","args":{{"index":{},"session_name":"{}"}}}}'.format(
view_id, index, session_name)
href = 'subl:lsp_run_text_command_helper {}'.format(args)
details.append("<a href='{}'>More</a>".format(href))
args = f'{{"view_id":{view_id},"command":"lsp_resolve_docs","args":{{"index":{index},"session_name":"{session_name}"}}}}'
href = f'subl:lsp_run_text_command_helper {args}'
details.append(f"<a href='{href}'>More</a>")
if lsp_label_detail and (lsp_label + lsp_label_detail).startswith(lsp_filter_text):
if lsp_label_detail[0].isalnum() and lsp_label.startswith(lsp_filter_text):
# labelDetails.detail is likely a type annotation
Expand Down Expand Up @@ -97,12 +96,12 @@ def format_completion(
insert_mode = userprefs().completion_insert_mode
oposite_insert_mode = 'Replace' if insert_mode == 'insert' else 'Insert'
command_url = "subl:lsp_commit_completion_with_opposite_insert_mode"
details.append("<a href='{}'>{}</a>".format(command_url, oposite_insert_mode))
details.append(f"<a href='{command_url}'>{oposite_insert_mode}</a>")
completion = sublime.CompletionItem(
trigger,
annotation,
# Not using "sublime.format_command" in a hot path to avoid slow json.dumps.
'lsp_select_completion {{"index":{},"session_name":"{}"}}'.format(index, session_name),
f'lsp_select_completion {{"index":{index},"session_name":"{session_name}"}}',
sublime.COMPLETION_FORMAT_COMMAND,
kind,
details=" | ".join(details)
Expand All @@ -112,7 +111,7 @@ def format_completion(
return completion


def get_text_edit_range(text_edit: Union[TextEdit, InsertReplaceEdit]) -> Range:
def get_text_edit_range(text_edit: TextEdit | InsertReplaceEdit) -> Range:
if 'insert' in text_edit and 'replace' in text_edit:
text_edit = cast(InsertReplaceEdit, text_edit)
insert_mode = userprefs().completion_insert_mode
Expand All @@ -135,7 +134,7 @@ def completion_with_defaults(item: CompletionItem, item_defaults: CompletionItem
""" Currently supports defaults for: ["editRange", "insertTextFormat", "data"] """
if not item_defaults:
return item
default_text_edit: Optional[Union[TextEdit, InsertReplaceEdit]] = None
default_text_edit: TextEdit | InsertReplaceEdit | None = None
edit_range = item_defaults.get('editRange')
if edit_range:
# If textEditText is not provided and a list's default range is provided
Expand Down Expand Up @@ -178,16 +177,16 @@ 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], int], None]
) -> None:
self._view = view
self._location = location
self._triggered_manually = triggered_manually
self._on_done_async = on_done_async
self._resolved = False
self._pending_completion_requests: Dict[int, weakref.ref[Session]] = {}
self._pending_completion_requests: dict[int, weakref.ref[Session]] = {}

def query_completions_async(self, sessions: List[Session]) -> None:
def query_completions_async(self, sessions: list[Session]) -> None:
promises = [self._create_completion_request_async(session) for session in sessions]
Promise.all(promises).then(lambda response: self._resolve_completions_async(response))

Expand All @@ -205,13 +204,13 @@ def _on_completion_response_async(
self._pending_completion_requests.pop(request_id, None)
return (response, weak_session)

def _resolve_completions_async(self, responses: List[ResolvedCompletions]) -> None:
def _resolve_completions_async(self, responses: list[ResolvedCompletions]) -> None:
if self._resolved:
return
LspSelectCompletionCommand.completions = {}
items: List[sublime.CompletionItem] = []
items: list[sublime.CompletionItem] = []
item_defaults: CompletionItemDefaults = {}
errors: List[Error] = []
errors: list[Error] = []
flags = 0
prefs = userprefs()
if prefs.inhibit_snippet_completions:
Expand All @@ -228,7 +227,7 @@ def _resolve_completions_async(self, responses: List[ResolvedCompletions]) -> No
session = weak_session()
if not session:
continue
response_items: List[CompletionItem] = []
response_items: list[CompletionItem] = []
if isinstance(response, dict):
response_items = response["items"] or []
item_defaults = response.get('itemDefaults') or {}
Expand All @@ -249,7 +248,7 @@ def _resolve_completions_async(self, responses: List[ResolvedCompletions]) -> No
flags |= sublime.INHIBIT_REORDER
if errors:
error_messages = ", ".join(str(error) for error in errors)
sublime.status_message('Completion error: {}'.format(error_messages))
sublime.status_message(f'Completion error: {error_messages}')
self._resolve_task_async(items, flags)

def cancel_async(self) -> None:
Expand All @@ -263,15 +262,15 @@ 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: int = 0) -> None:
if not self._resolved:
self._resolved = True
self._on_done_async(completions, flags)


class LspResolveDocsCommand(LspTextCommand):

def run(self, edit: sublime.Edit, index: int, session_name: str, event: Optional[dict] = None) -> None:
def run(self, edit: sublime.Edit, index: int, session_name: str, event: dict | None = None) -> None:

def run_async() -> None:
items, item_defaults = LspSelectCompletionCommand.completions[session_name]
Expand All @@ -287,7 +286,7 @@ def run_async() -> None:

sublime.set_timeout_async(run_async)

def _handle_resolve_response_async(self, language_map: Optional[MarkdownLangMap], item: CompletionItem) -> None:
def _handle_resolve_response_async(self, language_map: MarkdownLangMap | None, item: CompletionItem) -> None:
detail = ""
documentation = ""
if item:
Expand All @@ -299,7 +298,7 @@ def _handle_resolve_response_async(self, language_map: Optional[MarkdownLangMap]
documentation = self._format_documentation(markdown, None)
minihtml_content = ""
if detail:
minihtml_content += "<div class='highlight'>{}</div>".format(detail)
minihtml_content += f"<div class='highlight'>{detail}</div>"
if documentation:
minihtml_content += documentation

Expand All @@ -320,8 +319,8 @@ def run_main() -> None:

def _format_documentation(
self,
content: Union[MarkedString, MarkupContent],
language_map: Optional[MarkdownLangMap]
content: MarkedString | MarkupContent,
language_map: MarkdownLangMap | None
) -> str:
return minihtml(self.view, content, FORMAT_STRING | FORMAT_MARKUP_CONTENT, language_map)

Expand All @@ -332,15 +331,15 @@ def _on_navigate(self, url: str) -> None:
class LspCommitCompletionWithOppositeInsertMode(LspTextCommand):
active = False

def run(self, edit: sublime.Edit, event: Optional[dict] = None) -> None:
def run(self, edit: sublime.Edit, event: dict | None = None) -> None:
LspCommitCompletionWithOppositeInsertMode.active = True
self.view.run_command("commit_completion")
LspCommitCompletionWithOppositeInsertMode.active = False


class LspSelectCompletionCommand(LspTextCommand):

completions: Dict[SessionName, CompletionsStore] = {}
completions: dict[SessionName, CompletionsStore] = {}

def run(self, edit: sublime.Edit, index: int, session_name: str) -> None:
items, item_defaults = LspSelectCompletionCommand.completions[session_name]
Expand Down Expand Up @@ -377,7 +376,7 @@ def _on_resolved(self, session_name: str, item: CompletionItem) -> None:
apply_text_edits(self.view, additional_edits)
command = item.get("command")
if command:
debug('Running server command "{}" for view {}'.format(command, self.view.id()))
debug(f'Running server command "{command}" for view {self.view.id()}')
args = {
"command_name": command["command"],
"command_args": command.get("arguments"),
Expand Down
14 changes: 7 additions & 7 deletions plugin/core/active_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self, sv: SessionViewProtocol, request_id: int, request: Request) -
self.weaksv = ref(sv)
self.request_id = request_id
self.request = request
self.progress: Optional[ProgressReporter] = None
self.progress: ProgressReporter | None = None
# `request.progress` is either a boolean or a string. If it's a boolean, then that signals that the server does
# not support client-initiated progress. However, for some requests we still want to notify some kind of
# progress to the end-user. This is communicated by the boolean value being "True".
Expand Down Expand Up @@ -47,20 +47,20 @@ def show() -> None:
def _start_progress_reporter_async(
self,
title: str,
message: Optional[str] = None,
percentage: Optional[float] = None
) -> Optional[ProgressReporter]:
message: str | None = None,
percentage: float | None = None
) -> ProgressReporter | None:
sv = self.weaksv()
if not sv:
return None
if self.request.view is not None:
key = "lspprogressview-{}-{}-{}".format(sv.session.config.name, self.request.view.id(), self.request_id)
key = f"lspprogressview-{sv.session.config.name}-{self.request.view.id()}-{self.request_id}"
return ViewProgressReporter(self.request.view, key, title, message, percentage)
else:
key = "lspprogresswindow-{}-{}-{}".format(sv.session.config.name, sv.session.window.id(), self.request_id)
key = f"lspprogresswindow-{sv.session.config.name}-{sv.session.window.id()}-{self.request_id}"
return WindowProgressReporter(sv.session.window, key, title, message, percentage)

def update_progress_async(self, params: Dict[str, Any]) -> None:
def update_progress_async(self, params: dict[str, Any]) -> None:
value = params['value']
kind = value['kind']
message = value.get("message")
Expand Down
Loading

0 comments on commit 5672752

Please sign in to comment.