Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle custom URI schemes in hover text links #2339

Merged
merged 7 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions plugin/core/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from urllib.parse import urlparse
rchl marked this conversation as resolved.
Show resolved Hide resolved
from .css import css as lsp_css
from .protocol import CodeAction
from .protocol import CodeActionKind
Expand Down Expand Up @@ -997,6 +998,34 @@ def is_location_href(href: str) -> bool:
return href.startswith("location:")


def starts_with_custom_uri_scheme(href: str) -> bool:
jwortmann marked this conversation as resolved.
Show resolved Hide resolved
return urlparse(href).scheme.lower() not in ("", "http", "https")


def row_col_from_uri_fragment(href: str) -> Tuple[Optional[int], Optional[int]]:
jwortmann marked this conversation as resolved.
Show resolved Hide resolved
fragment = urlparse(href).fragment
if not fragment:
return (None, None)
rowcol = fragment.split(":")
row = None # type: Optional[int]
col = None # type: Optional[int]
if len(rowcol) >= 1:
try:
row = int(rowcol[0])
# rowcols in URI fragments are 1-based (dubious)
row -= 1
except Exception:
pass
if len(rowcol) >= 2:
try:
col = int(rowcol[1])
# rowcols in URI fragments are 1-based (dubious)
col -= 1
except Exception:
pass
return (row, col)


def _format_diagnostic_related_info(
config: ClientConfig,
info: DiagnosticRelatedInformation,
Expand Down
16 changes: 16 additions & 0 deletions plugin/hover.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
from .core.views import MarkdownLangMap
from .core.views import minihtml
from .core.views import range_to_region
from .core.views import row_col_from_uri_fragment
from .core.views import show_lsp_popup
from .core.views import starts_with_custom_uri_scheme
from .core.views import text_document_position_params
from .core.views import unpack_href_location
from .core.views import update_lsp_popup
Expand Down Expand Up @@ -353,6 +355,8 @@ def on_select(targets: List[str], idx: int) -> None:
position = {"line": row, "character": col_utf16} # type: Position
r = {"start": position, "end": position} # type: Range
sublime.set_timeout_async(partial(session.open_uri_async, uri, r))
elif starts_with_custom_uri_scheme(href):
sublime.set_timeout_async(partial(self.try_open_custom_uri_async, href))
else:
open_in_browser(href)

Expand All @@ -366,3 +370,15 @@ def run_async() -> None:
session.run_code_action_async(actions[index], progress=True, view=self.view)

sublime.set_timeout_async(run_async)

def try_open_custom_uri_async(self, href: str) -> None:
row, col_utf16 = row_col_from_uri_fragment(href)
if isinstance(row, int):
position = {"line": row, "character": col_utf16 or 0} # type: Position
r = {"start": position, "end": position} # type: Optional[Range]
else:
r = None
for session in self.sessions():
promise = session.open_uri_async(href, r)
if not promise.resolved or isinstance(promise.value, sublime.View):
return
rwols marked this conversation as resolved.
Show resolved Hide resolved