From c715589d149ce26042c009e2f1d3a6e5e959ca9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Wed, 21 Apr 2021 23:22:09 +0200 Subject: [PATCH 01/12] Handle no selection consistently Fixes a crash that could happen in certain scenarios and also an issue with showing the hover popup with hovering 0 offset in the view. Fixes #1645 --- docs/src/troubleshooting.md | 5 +++++ plugin/core/sessions.py | 3 +++ 2 files changed, 8 insertions(+) diff --git a/docs/src/troubleshooting.md b/docs/src/troubleshooting.md index c0d7841fd..c5dc1e0a4 100644 --- a/docs/src/troubleshooting.md +++ b/docs/src/troubleshooting.md @@ -5,6 +5,11 @@ Enable server logging: set `log_server` to ["panel"] Run "LSP: Toggle Log Panel" from the command palette. No restart is needed. If you believe the issue is with this package, please include the output from the Sublime console in your issue report! +| test | foo | +| ---- | --- | +| hey | ho | +| hey | ho | + ## Updating the PATH used by LSP servers You can confirm that your issue is due to `PATH` being different by starting Sublime Text from the command line so that it inherits your shell's environment. diff --git a/plugin/core/sessions.py b/plugin/core/sessions.py index 4a87805bf..35b58540e 100644 --- a/plugin/core/sessions.py +++ b/plugin/core/sessions.py @@ -257,6 +257,9 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor "didChangeConfiguration": { "dynamicRegistration": True }, + "didChangeWatchedFiles": { + "dynamicRegistration": True + }, "executeCommand": {}, "workspaceEdit": { "documentChanges": True, From ddc85e8b124fa2aed82cff30d2b4eb511b5f7e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Wed, 21 Apr 2021 23:23:05 +0200 Subject: [PATCH 02/12] actual changes --- plugin/code_actions.py | 6 +++--- plugin/core/registry.py | 13 +++++++------ plugin/core/views.py | 4 ++++ plugin/documents.py | 14 +++++--------- plugin/execute_command.py | 28 +++++++++++++++------------- plugin/formatting.py | 3 ++- plugin/hover.py | 10 +++++++++- plugin/rename.py | 7 +++++-- 8 files changed, 50 insertions(+), 35 deletions(-) diff --git a/plugin/code_actions.py b/plugin/code_actions.py index 385b9d0d1..4461e3f95 100644 --- a/plugin/code_actions.py +++ b/plugin/code_actions.py @@ -11,6 +11,7 @@ from .core.settings import userprefs from .core.typing import Any, List, Dict, Callable, Optional, Tuple, Union, Sequence from .core.views import entire_content_region +from .core.views import first_selection from .core.views import text_document_code_action_params from .save_command import LspSaveCommand, SaveTask import sublime @@ -276,9 +277,8 @@ def run(self, edit: sublime.Edit, event: Optional[dict] = None, only_kinds: Opti self.commands = [] # type: List[Tuple[str, str, CodeActionOrCommand]] self.commands_by_config = {} # type: CodeActionsByConfigName view = self.view - try: - region = view.sel()[0] - except IndexError: + region = first_selection(view) + if not region: return listener = windows.listener_for_view(view) if not listener: diff --git a/plugin/core/registry.py b/plugin/core/registry.py index 7b398c9c1..2756e5e6a 100644 --- a/plugin/core/registry.py +++ b/plugin/core/registry.py @@ -37,13 +37,14 @@ def best_session(view: sublime.View, sessions: Iterable[Session], point: Optiona def get_position(view: sublime.View, event: Optional[dict] = None, point: Optional[int] = None) -> int: if isinstance(point, int): return point - if event is None: - return view.sel()[0].begin() - x, y = event.get("x"), event.get("y") - if x is not None and y is not None: - return view.window_to_text((x, y)) - else: + if event: + x, y = event.get("x"), event.get("y") + if x is not None and y is not None: + return view.window_to_text((x, y)) + try: return view.sel()[0].begin() + except IndexError: + return 0 class LspTextCommand(sublime_plugin.TextCommand): diff --git a/plugin/core/views.py b/plugin/core/views.py index 2e80c949d..0761719b4 100644 --- a/plugin/core/views.py +++ b/plugin/core/views.py @@ -192,6 +192,10 @@ def text_document_identifier(view_or_file_name: Union[str, sublime.View]) -> Dic uri = uri_from_view(view_or_file_name) return {"uri": uri} +def first_selection(view: sublime.View) -> Optional[sublime.Region]: + if len(view.sel()): + return view.sel()[0] + return None def entire_content_region(view: sublime.View) -> sublime.Region: return sublime.Region(0, view.size()) diff --git a/plugin/documents.py b/plugin/documents.py index 7ea5a2fd0..47f2bc1a2 100644 --- a/plugin/documents.py +++ b/plugin/documents.py @@ -26,6 +26,7 @@ from .core.typing import Any, Callable, Optional, Dict, Generator, Iterable, List, Tuple, Union from .core.views import DIAGNOSTIC_SEVERITY from .core.views import document_color_params +from .core.views import first_selection from .core.views import format_completion from .core.views import lsp_color_to_phantom from .core.views import make_command_link @@ -598,9 +599,10 @@ def _is_in_higlighted_region(self, point: int) -> bool: return False def _do_highlights_async(self) -> None: - if not len(self.view.sel()): + region = first_selection(self.view) + if not region: return - point = self.view.sel()[0].b + point = region.b session = self.session("documentHighlightProvider", point) if session: params = text_document_position_params(self.view, point) @@ -806,19 +808,13 @@ def _update_stored_region_async(self) -> Tuple[bool, sublime.Region]: :returns: A tuple with two elements. The second element is the new region, the first element signals whether the previous region was different from the newly stored region. """ - current_region = self._get_current_region_async() + current_region = first_selection(self.view) if current_region is not None: if self._stored_region != current_region: self._stored_region = current_region return True, current_region return False, sublime.Region(-1, -1) - def _get_current_region_async(self) -> Optional[sublime.Region]: - try: - return self.view.sel()[0] - except IndexError: - return None - def _clear_session_views_async(self) -> None: session_views = self._session_views diff --git a/plugin/execute_command.py b/plugin/execute_command.py index 707f7127b..720bed5c5 100644 --- a/plugin/execute_command.py +++ b/plugin/execute_command.py @@ -4,6 +4,7 @@ from .core.registry import LspTextCommand from .core.registry import windows from .core.typing import List, Optional, Any +from .core.views import first_selection from .core.views import uri_from_view, offset_to_point, region_to_range, text_document_identifier @@ -49,24 +50,25 @@ def handle_response(response: Any) -> None: def _expand_variables(self, command_args: List[Any]) -> List[Any]: view = self.view # type: sublime.View - region = view.sel()[0] + region = first_selection(view) for i, arg in enumerate(command_args): if arg in ["$document_id", "${document_id}"]: command_args[i] = text_document_identifier(view) elif arg in ["$file_uri", "${file_uri}"]: command_args[i] = uri_from_view(view) - elif arg in ["$selection", "${selection}"]: - command_args[i] = view.substr(region) - elif arg in ["$offset", "${offset}"]: - command_args[i] = region.b - elif arg in ["$selection_begin", "${selection_begin}"]: - command_args[i] = region.begin() - elif arg in ["$selection_end", "${selection_end}"]: - command_args[i] = region.end() - elif arg in ["$position", "${position}"]: - command_args[i] = offset_to_point(view, region.b).to_lsp() - elif arg in ["$range", "${range}"]: - command_args[i] = region_to_range(view, region).to_lsp() + elif region: + if arg in ["$selection", "${selection}"]: + command_args[i] = view.substr(region) + elif arg in ["$offset", "${offset}"]: + command_args[i] = region.b + elif arg in ["$selection_begin", "${selection_begin}"]: + command_args[i] = region.begin() + elif arg in ["$selection_end", "${selection_end}"]: + command_args[i] = region.end() + elif arg in ["$position", "${position}"]: + command_args[i] = offset_to_point(view, region.b).to_lsp() + elif arg in ["$range", "${range}"]: + command_args[i] = region_to_range(view, region).to_lsp() window = view.window() window_variables = window.extract_variables() if window else {} return sublime.expand_variables(command_args, window_variables) diff --git a/plugin/formatting.py b/plugin/formatting.py index 31ac08a69..71ea8e166 100644 --- a/plugin/formatting.py +++ b/plugin/formatting.py @@ -5,6 +5,7 @@ from .core.settings import userprefs from .core.typing import Any, Callable, List, Optional, Iterator from .core.views import entire_content_region +from .core.views import first_selection from .core.views import text_document_formatting from .core.views import text_document_range_formatting from .core.views import will_save_wait_until @@ -120,5 +121,5 @@ def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) def run(self, edit: sublime.Edit, event: Optional[dict] = None) -> None: session = self.best_session(self.capability) if session: - req = text_document_range_formatting(self.view, self.view.sel()[0]) + req = text_document_range_formatting(self.view, first_selection(self.view)) session.send_request(req, lambda response: apply_response_to_view(response, self.view)) diff --git a/plugin/hover.py b/plugin/hover.py index f814d9bce..10b6fbb38 100644 --- a/plugin/hover.py +++ b/plugin/hover.py @@ -10,6 +10,7 @@ from .core.typing import List, Optional, Any, Dict, Tuple, Sequence from .core.views import diagnostic_severity from .core.views import format_diagnostic_for_html +from .core.views import first_selection from .core.views import FORMAT_MARKED_STRING, FORMAT_MARKUP_CONTENT, minihtml from .core.views import make_command_link from .core.views import make_link @@ -70,10 +71,17 @@ def run( point: Optional[int] = None, event: Optional[dict] = None ) -> None: - hover_point = point or self.view.sel()[0].begin() + temp_point = point + if temp_point is None: + region = first_selection(self.view) + if region: + temp_point = region.begin() + if temp_point is None: + return window = self.view.window() if not window: return + hover_point = temp_point wm = windows.lookup(window) self._base_dir = wm.get_project_path(self.view.file_name() or "") self._hover = None # type: Optional[Any] diff --git a/plugin/rename.py b/plugin/rename.py index a0a805dc7..97dbccf8f 100644 --- a/plugin/rename.py +++ b/plugin/rename.py @@ -10,7 +10,7 @@ from .core.registry import windows from .core.types import PANEL_FILE_REGEX, PANEL_LINE_REGEX from .core.typing import Any, Optional, Dict, List -from .core.views import range_to_region, get_line +from .core.views import first_selection, range_to_region, get_line from .core.views import text_document_position_params import os import sublime @@ -63,7 +63,10 @@ def input(self, args: dict) -> Optional[sublime_plugin.TextInputHandler]: point = args.get("point") # guess the symbol name if not isinstance(point, int): - point = self.view.sel()[0].b + region = first_selection(self.view) + if not region: + return None + point = region.b placeholder = self.view.substr(self.view.word(point)) return RenameSymbolInputHandler(self.view, placeholder) else: From b955b7de8a29c6c14592b0454e7f3c0c4ac676c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Wed, 21 Apr 2021 23:23:12 +0200 Subject: [PATCH 03/12] unrelated --- docs/src/troubleshooting.md | 5 ----- plugin/core/sessions.py | 3 --- 2 files changed, 8 deletions(-) diff --git a/docs/src/troubleshooting.md b/docs/src/troubleshooting.md index c5dc1e0a4..c0d7841fd 100644 --- a/docs/src/troubleshooting.md +++ b/docs/src/troubleshooting.md @@ -5,11 +5,6 @@ Enable server logging: set `log_server` to ["panel"] Run "LSP: Toggle Log Panel" from the command palette. No restart is needed. If you believe the issue is with this package, please include the output from the Sublime console in your issue report! -| test | foo | -| ---- | --- | -| hey | ho | -| hey | ho | - ## Updating the PATH used by LSP servers You can confirm that your issue is due to `PATH` being different by starting Sublime Text from the command line so that it inherits your shell's environment. diff --git a/plugin/core/sessions.py b/plugin/core/sessions.py index 35b58540e..4a87805bf 100644 --- a/plugin/core/sessions.py +++ b/plugin/core/sessions.py @@ -257,9 +257,6 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor "didChangeConfiguration": { "dynamicRegistration": True }, - "didChangeWatchedFiles": { - "dynamicRegistration": True - }, "executeCommand": {}, "workspaceEdit": { "documentChanges": True, From 0c7a6c2c73134e7ee78e3b1fdc1a46aab81ddae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Wed, 21 Apr 2021 23:30:17 +0200 Subject: [PATCH 04/12] lint --- docs/src/troubleshooting.md | 5 +++++ plugin/core/sessions.py | 3 +++ plugin/formatting.py | 5 +++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/src/troubleshooting.md b/docs/src/troubleshooting.md index c0d7841fd..c5dc1e0a4 100644 --- a/docs/src/troubleshooting.md +++ b/docs/src/troubleshooting.md @@ -5,6 +5,11 @@ Enable server logging: set `log_server` to ["panel"] Run "LSP: Toggle Log Panel" from the command palette. No restart is needed. If you believe the issue is with this package, please include the output from the Sublime console in your issue report! +| test | foo | +| ---- | --- | +| hey | ho | +| hey | ho | + ## Updating the PATH used by LSP servers You can confirm that your issue is due to `PATH` being different by starting Sublime Text from the command line so that it inherits your shell's environment. diff --git a/plugin/core/sessions.py b/plugin/core/sessions.py index 4a87805bf..35b58540e 100644 --- a/plugin/core/sessions.py +++ b/plugin/core/sessions.py @@ -257,6 +257,9 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor "didChangeConfiguration": { "dynamicRegistration": True }, + "didChangeWatchedFiles": { + "dynamicRegistration": True + }, "executeCommand": {}, "workspaceEdit": { "documentChanges": True, diff --git a/plugin/formatting.py b/plugin/formatting.py index 71ea8e166..ce4cdb654 100644 --- a/plugin/formatting.py +++ b/plugin/formatting.py @@ -120,6 +120,7 @@ def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) def run(self, edit: sublime.Edit, event: Optional[dict] = None) -> None: session = self.best_session(self.capability) - if session: - req = text_document_range_formatting(self.view, first_selection(self.view)) + selection = first_selection(self.view) + if session and selection: + req = text_document_range_formatting(self.view, selection) session.send_request(req, lambda response: apply_response_to_view(response, self.view)) From 0e270185399d9decf25b81f6790c696394100a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Thu, 22 Apr 2021 08:21:42 +0200 Subject: [PATCH 05/12] accident --- docs/src/troubleshooting.md | 5 ----- plugin/core/sessions.py | 3 --- 2 files changed, 8 deletions(-) diff --git a/docs/src/troubleshooting.md b/docs/src/troubleshooting.md index c5dc1e0a4..c0d7841fd 100644 --- a/docs/src/troubleshooting.md +++ b/docs/src/troubleshooting.md @@ -5,11 +5,6 @@ Enable server logging: set `log_server` to ["panel"] Run "LSP: Toggle Log Panel" from the command palette. No restart is needed. If you believe the issue is with this package, please include the output from the Sublime console in your issue report! -| test | foo | -| ---- | --- | -| hey | ho | -| hey | ho | - ## Updating the PATH used by LSP servers You can confirm that your issue is due to `PATH` being different by starting Sublime Text from the command line so that it inherits your shell's environment. diff --git a/plugin/core/sessions.py b/plugin/core/sessions.py index 35b58540e..4a87805bf 100644 --- a/plugin/core/sessions.py +++ b/plugin/core/sessions.py @@ -257,9 +257,6 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor "didChangeConfiguration": { "dynamicRegistration": True }, - "didChangeWatchedFiles": { - "dynamicRegistration": True - }, "executeCommand": {}, "workspaceEdit": { "documentChanges": True, From f602749a6a1d9d14abc1ed5b3bba93493ad522f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Thu, 22 Apr 2021 08:24:13 +0200 Subject: [PATCH 06/12] lint --- plugin/core/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/core/views.py b/plugin/core/views.py index 0761719b4..e52271571 100644 --- a/plugin/core/views.py +++ b/plugin/core/views.py @@ -192,11 +192,13 @@ def text_document_identifier(view_or_file_name: Union[str, sublime.View]) -> Dic uri = uri_from_view(view_or_file_name) return {"uri": uri} + def first_selection(view: sublime.View) -> Optional[sublime.Region]: if len(view.sel()): return view.sel()[0] return None + def entire_content_region(view: sublime.View) -> sublime.Region: return sublime.Region(0, view.size()) From b6d1a14985f3455461240b7bafcfa99bd94ff59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Thu, 22 Apr 2021 22:21:03 +0200 Subject: [PATCH 07/12] nicer style --- plugin/hover.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plugin/hover.py b/plugin/hover.py index 10b6fbb38..41fb8f53a 100644 --- a/plugin/hover.py +++ b/plugin/hover.py @@ -71,17 +71,13 @@ def run( point: Optional[int] = None, event: Optional[dict] = None ) -> None: - temp_point = point - if temp_point is None: - region = first_selection(self.view) - if region: - temp_point = region.begin() - if temp_point is None: - return window = self.view.window() if not window: return - hover_point = temp_point + region = first_selection(self.view) + if point is None and region is None: + return + hover_point = point or region.begin() wm = windows.lookup(window) self._base_dir = wm.get_project_path(self.view.file_name() or "") self._hover = None # type: Optional[Any] From fe4d777c498343c47a2a4061842242667e80beef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Thu, 22 Apr 2021 22:27:37 +0200 Subject: [PATCH 08/12] Revert "nicer style" This reverts commit b6d1a14985f3455461240b7bafcfa99bd94ff59c. --- plugin/hover.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugin/hover.py b/plugin/hover.py index 41fb8f53a..10b6fbb38 100644 --- a/plugin/hover.py +++ b/plugin/hover.py @@ -71,13 +71,17 @@ def run( point: Optional[int] = None, event: Optional[dict] = None ) -> None: + temp_point = point + if temp_point is None: + region = first_selection(self.view) + if region: + temp_point = region.begin() + if temp_point is None: + return window = self.view.window() if not window: return - region = first_selection(self.view) - if point is None and region is None: - return - hover_point = point or region.begin() + hover_point = temp_point wm = windows.lookup(window) self._base_dir = wm.get_project_path(self.view.file_name() or "") self._hover = None # type: Optional[Any] From 16d485f52f44bef160f0e3844bf475ae5a5173af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Thu, 22 Apr 2021 22:48:09 +0200 Subject: [PATCH 09/12] change return type of get_position to optional --- plugin/core/registry.py | 9 ++++++--- plugin/goto.py | 5 ++++- plugin/references.py | 2 ++ plugin/rename.py | 5 ++++- plugin/selection_range.py | 5 ++++- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/plugin/core/registry.py b/plugin/core/registry.py index 2756e5e6a..752f54ec8 100644 --- a/plugin/core/registry.py +++ b/plugin/core/registry.py @@ -34,7 +34,7 @@ def best_session(view: sublime.View, sessions: Iterable[Session], point: Optiona windows = WindowRegistry(configs) -def get_position(view: sublime.View, event: Optional[dict] = None, point: Optional[int] = None) -> int: +def get_position(view: sublime.View, event: Optional[dict] = None, point: Optional[int] = None) -> Optional[int]: if isinstance(point, int): return point if event: @@ -44,7 +44,7 @@ def get_position(view: sublime.View, event: Optional[dict] = None, point: Option try: return view.sel()[0].begin() except IndexError: - return 0 + return None class LspTextCommand(sublime_plugin.TextCommand): @@ -64,7 +64,10 @@ class LspTextCommand(sublime_plugin.TextCommand): def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) -> bool: if self.capability: # At least one active session with the given capability must exist. - if not self.best_session(self.capability, get_position(self.view, event, point)): + position = get_position(self.view, event, point) + if position is None: + return False + if not self.best_session(self.capability, position): return False if self.session_name: # There must exist an active session with the given (config) name. diff --git a/plugin/goto.py b/plugin/goto.py index 7e452aff7..ef5f547b5 100644 --- a/plugin/goto.py +++ b/plugin/goto.py @@ -49,7 +49,10 @@ def run( ) -> None: session = self.best_session(self.capability) if session: - params = text_document_position_params(self.view, get_position(self.view, event, point)) + position = get_position(self.view, event, point) + if position is None: + return + params = text_document_position_params(self.view, position) session.send_request( Request(self.method, params, self.view, progress=True), # It's better to run this on the UI thread so we are guaranteed no AttributeErrors anywhere diff --git a/plugin/references.py b/plugin/references.py index 0c0302da4..b4725f652 100644 --- a/plugin/references.py +++ b/plugin/references.py @@ -38,6 +38,8 @@ def run(self, edit: sublime.Edit, event: Optional[dict] = None, point: Optional[ file_path = self.view.file_name() if session and file_path: pos = get_position(self.view, event, point) + if pos is None: + return window = self.view.window() if not window: return diff --git a/plugin/rename.py b/plugin/rename.py index 97dbccf8f..7f23f881c 100644 --- a/plugin/rename.py +++ b/plugin/rename.py @@ -82,7 +82,10 @@ def run( point: Optional[int] = None ) -> None: if position is None: - pos = get_position(self.view, event, point) + tmp_pos = get_position(self.view, event, point) + if tmp_pos is None: + return + pos = tmp_pos if new_name: return self._do_rename(pos, new_name) else: diff --git a/plugin/selection_range.py b/plugin/selection_range.py index af244734a..8935ffe8d 100644 --- a/plugin/selection_range.py +++ b/plugin/selection_range.py @@ -22,7 +22,10 @@ def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) return True def run(self, edit: sublime.Edit, event: Optional[dict] = None) -> None: - session = self.best_session(self.capability, get_position(self.view, event)) + position = get_position(self.view, event) + if position is None: + return + session = self.best_session(self.capability, position) if session: params = selection_range_params(self.view) self._regions.extend(self.view.sel()) From 4f21ca6e01264e78d656112616b2dcbe329f9da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Thu, 22 Apr 2021 22:50:05 +0200 Subject: [PATCH 10/12] mypy --- plugin/references.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugin/references.py b/plugin/references.py index b4725f652..6be78b3af 100644 --- a/plugin/references.py +++ b/plugin/references.py @@ -37,9 +37,10 @@ def run(self, edit: sublime.Edit, event: Optional[dict] = None, point: Optional[ session = self.best_session(self.capability) file_path = self.view.file_name() if session and file_path: - pos = get_position(self.view, event, point) - if pos is None: + tmp_pos = get_position(self.view, event, point) + if tmp_pos is None: return + pos = tmp_pos window = self.view.window() if not window: return From 878f2e9bdd72ae086548d51390600faa282994ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Fri, 23 Apr 2021 16:44:40 +0200 Subject: [PATCH 11/12] fix region checks ("is None" instead of "not" which is also true for empty selection) --- plugin/code_actions.py | 2 +- plugin/documents.py | 2 +- plugin/execute_command.py | 2 +- plugin/formatting.py | 2 +- plugin/hover.py | 2 +- plugin/rename.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin/code_actions.py b/plugin/code_actions.py index 4461e3f95..d04da068e 100644 --- a/plugin/code_actions.py +++ b/plugin/code_actions.py @@ -278,7 +278,7 @@ def run(self, edit: sublime.Edit, event: Optional[dict] = None, only_kinds: Opti self.commands_by_config = {} # type: CodeActionsByConfigName view = self.view region = first_selection(view) - if not region: + if region is None: return listener = windows.listener_for_view(view) if not listener: diff --git a/plugin/documents.py b/plugin/documents.py index 47f2bc1a2..036058344 100644 --- a/plugin/documents.py +++ b/plugin/documents.py @@ -600,7 +600,7 @@ def _is_in_higlighted_region(self, point: int) -> bool: def _do_highlights_async(self) -> None: region = first_selection(self.view) - if not region: + if region is None: return point = region.b session = self.session("documentHighlightProvider", point) diff --git a/plugin/execute_command.py b/plugin/execute_command.py index 720bed5c5..e2f148ea4 100644 --- a/plugin/execute_command.py +++ b/plugin/execute_command.py @@ -56,7 +56,7 @@ def _expand_variables(self, command_args: List[Any]) -> List[Any]: command_args[i] = text_document_identifier(view) elif arg in ["$file_uri", "${file_uri}"]: command_args[i] = uri_from_view(view) - elif region: + elif region is not None: if arg in ["$selection", "${selection}"]: command_args[i] = view.substr(region) elif arg in ["$offset", "${offset}"]: diff --git a/plugin/formatting.py b/plugin/formatting.py index ce4cdb654..3718ab3a7 100644 --- a/plugin/formatting.py +++ b/plugin/formatting.py @@ -121,6 +121,6 @@ def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) def run(self, edit: sublime.Edit, event: Optional[dict] = None) -> None: session = self.best_session(self.capability) selection = first_selection(self.view) - if session and selection: + if session and selection is not None: req = text_document_range_formatting(self.view, selection) session.send_request(req, lambda response: apply_response_to_view(response, self.view)) diff --git a/plugin/hover.py b/plugin/hover.py index 10b6fbb38..3980438a8 100644 --- a/plugin/hover.py +++ b/plugin/hover.py @@ -74,7 +74,7 @@ def run( temp_point = point if temp_point is None: region = first_selection(self.view) - if region: + if region is not None: temp_point = region.begin() if temp_point is None: return diff --git a/plugin/rename.py b/plugin/rename.py index 7f23f881c..39f1b5786 100644 --- a/plugin/rename.py +++ b/plugin/rename.py @@ -64,7 +64,7 @@ def input(self, args: dict) -> Optional[sublime_plugin.TextInputHandler]: # guess the symbol name if not isinstance(point, int): region = first_selection(self.view) - if not region: + if region is None: return None point = region.b placeholder = self.view.substr(self.view.word(point)) From 65ef4ca36200df38821d7cb3084034d35993233f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ch=C5=82odnicki?= Date: Fri, 23 Apr 2021 22:20:28 +0200 Subject: [PATCH 12/12] address comments --- plugin/code_actions.py | 4 ++-- plugin/core/views.py | 7 ++++--- plugin/documents.py | 6 +++--- plugin/execute_command.py | 4 ++-- plugin/formatting.py | 4 ++-- plugin/hover.py | 4 ++-- plugin/rename.py | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/plugin/code_actions.py b/plugin/code_actions.py index d04da068e..8fbdf0ce7 100644 --- a/plugin/code_actions.py +++ b/plugin/code_actions.py @@ -11,7 +11,7 @@ from .core.settings import userprefs from .core.typing import Any, List, Dict, Callable, Optional, Tuple, Union, Sequence from .core.views import entire_content_region -from .core.views import first_selection +from .core.views import first_selection_region from .core.views import text_document_code_action_params from .save_command import LspSaveCommand, SaveTask import sublime @@ -277,7 +277,7 @@ def run(self, edit: sublime.Edit, event: Optional[dict] = None, only_kinds: Opti self.commands = [] # type: List[Tuple[str, str, CodeActionOrCommand]] self.commands_by_config = {} # type: CodeActionsByConfigName view = self.view - region = first_selection(view) + region = first_selection_region(view) if region is None: return listener = windows.listener_for_view(view) diff --git a/plugin/core/views.py b/plugin/core/views.py index e52271571..4522cd1ff 100644 --- a/plugin/core/views.py +++ b/plugin/core/views.py @@ -193,10 +193,11 @@ def text_document_identifier(view_or_file_name: Union[str, sublime.View]) -> Dic return {"uri": uri} -def first_selection(view: sublime.View) -> Optional[sublime.Region]: - if len(view.sel()): +def first_selection_region(view: sublime.View) -> Optional[sublime.Region]: + try: return view.sel()[0] - return None + except IndexError: + return None def entire_content_region(view: sublime.View) -> sublime.Region: diff --git a/plugin/documents.py b/plugin/documents.py index 036058344..58320e704 100644 --- a/plugin/documents.py +++ b/plugin/documents.py @@ -26,7 +26,7 @@ from .core.typing import Any, Callable, Optional, Dict, Generator, Iterable, List, Tuple, Union from .core.views import DIAGNOSTIC_SEVERITY from .core.views import document_color_params -from .core.views import first_selection +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 @@ -599,7 +599,7 @@ def _is_in_higlighted_region(self, point: int) -> bool: return False def _do_highlights_async(self) -> None: - region = first_selection(self.view) + region = first_selection_region(self.view) if region is None: return point = region.b @@ -808,7 +808,7 @@ def _update_stored_region_async(self) -> Tuple[bool, sublime.Region]: :returns: A tuple with two elements. The second element is the new region, the first element signals whether the previous region was different from the newly stored region. """ - current_region = first_selection(self.view) + current_region = first_selection_region(self.view) if current_region is not None: if self._stored_region != current_region: self._stored_region = current_region diff --git a/plugin/execute_command.py b/plugin/execute_command.py index e2f148ea4..791dd6a24 100644 --- a/plugin/execute_command.py +++ b/plugin/execute_command.py @@ -4,7 +4,7 @@ from .core.registry import LspTextCommand from .core.registry import windows from .core.typing import List, Optional, Any -from .core.views import first_selection +from .core.views import first_selection_region from .core.views import uri_from_view, offset_to_point, region_to_range, text_document_identifier @@ -50,7 +50,7 @@ def handle_response(response: Any) -> None: def _expand_variables(self, command_args: List[Any]) -> List[Any]: view = self.view # type: sublime.View - region = first_selection(view) + region = first_selection_region(view) for i, arg in enumerate(command_args): if arg in ["$document_id", "${document_id}"]: command_args[i] = text_document_identifier(view) diff --git a/plugin/formatting.py b/plugin/formatting.py index 3718ab3a7..f65c47fd8 100644 --- a/plugin/formatting.py +++ b/plugin/formatting.py @@ -5,7 +5,7 @@ from .core.settings import userprefs from .core.typing import Any, Callable, List, Optional, Iterator from .core.views import entire_content_region -from .core.views import first_selection +from .core.views import first_selection_region from .core.views import text_document_formatting from .core.views import text_document_range_formatting from .core.views import will_save_wait_until @@ -120,7 +120,7 @@ def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) def run(self, edit: sublime.Edit, event: Optional[dict] = None) -> None: session = self.best_session(self.capability) - selection = first_selection(self.view) + selection = first_selection_region(self.view) if session and selection is not None: req = text_document_range_formatting(self.view, selection) session.send_request(req, lambda response: apply_response_to_view(response, self.view)) diff --git a/plugin/hover.py b/plugin/hover.py index 3980438a8..6b1ea32e1 100644 --- a/plugin/hover.py +++ b/plugin/hover.py @@ -10,7 +10,7 @@ from .core.typing import List, Optional, Any, Dict, Tuple, Sequence from .core.views import diagnostic_severity from .core.views import format_diagnostic_for_html -from .core.views import first_selection +from .core.views import first_selection_region from .core.views import FORMAT_MARKED_STRING, FORMAT_MARKUP_CONTENT, minihtml from .core.views import make_command_link from .core.views import make_link @@ -73,7 +73,7 @@ def run( ) -> None: temp_point = point if temp_point is None: - region = first_selection(self.view) + region = first_selection_region(self.view) if region is not None: temp_point = region.begin() if temp_point is None: diff --git a/plugin/rename.py b/plugin/rename.py index 39f1b5786..e940490a8 100644 --- a/plugin/rename.py +++ b/plugin/rename.py @@ -10,7 +10,7 @@ from .core.registry import windows from .core.types import PANEL_FILE_REGEX, PANEL_LINE_REGEX from .core.typing import Any, Optional, Dict, List -from .core.views import first_selection, range_to_region, get_line +from .core.views import first_selection_region, range_to_region, get_line from .core.views import text_document_position_params import os import sublime @@ -63,7 +63,7 @@ def input(self, args: dict) -> Optional[sublime_plugin.TextInputHandler]: point = args.get("point") # guess the symbol name if not isinstance(point, int): - region = first_selection(self.view) + region = first_selection_region(self.view) if region is None: return None point = region.b