diff --git a/plugin/semantic_highlighting.py b/plugin/semantic_highlighting.py
index 5621996e8..e4cec4585 100644
--- a/plugin/semantic_highlighting.py
+++ b/plugin/semantic_highlighting.py
@@ -1,6 +1,7 @@
from .core.registry import LspTextCommand
-from .core.typing import List
+from .core.typing import Any, List, Tuple, cast
import sublime
+import os
class SemanticToken:
@@ -13,6 +14,12 @@ def __init__(self, region: sublime.Region, type: str, modifiers: List[str]):
self.modifiers = modifiers
+def copy(view: sublime.View, text: str) -> None:
+ sublime.set_clipboard(text)
+ view.hide_popup()
+ sublime.status_message('Scope name copied to clipboard')
+
+
class LspShowScopeNameCommand(LspTextCommand):
"""
Like the builtin show_scope_name command from Default/show_scope_name.py,
@@ -21,14 +28,56 @@ class LspShowScopeNameCommand(LspTextCommand):
capability = 'semanticTokensProvider'
- def run(self, edit: sublime.Edit) -> None:
+ def run(self, _: sublime.Edit) -> None:
point = self.view.sel()[-1].b
-
scope = self.view.scope_name(point).rstrip()
scope_list = scope.replace(' ', '
')
-
stack = self.view.context_backtrace(point)
-
+ token_type, token_modifiers = self._get_semantic_info(point)
+ if isinstance(stack, list) and len(stack) > 0 and not isinstance(stack[0], str):
+ self._render_with_fancy_stackframes(
+ scope,
+ scope_list,
+ cast(List[sublime.ContextStackFrame], stack),
+ token_type,
+ token_modifiers
+ )
+ else:
+ self._render_with_plain_string_stackframes(
+ scope,
+ scope_list,
+ cast(List[str], stack),
+ token_type,
+ token_modifiers
+ )
+
+ def _get_semantic_info(self, point: int) -> Tuple[str, str]:
+ session = self.best_session('semanticTokensProvider')
+ session_buffer = None
+ if session:
+ for sv in session.session_views_async():
+ if self.view == sv.view:
+ session_buffer = sv.session_buffer
+ break
+ token_type = '-'
+ token_modifiers = '-'
+ if session_buffer:
+ for token in session_buffer.get_semantic_tokens():
+ if token.region.contains(point) and point < token.region.end():
+ token_type = token.type
+ if token.modifiers:
+ token_modifiers = ', '.join(token.modifiers)
+ break
+ return token_type, token_modifiers
+
+ def _render_with_plain_string_stackframes(
+ self,
+ scope: str,
+ scope_list: str,
+ stack: List[str],
+ token_type: str,
+ token_modifiers: str
+ ) -> None:
backtrace = ''
digits_len = 1
for i, ctx in enumerate(reversed(stack)):
@@ -44,26 +93,84 @@ def run(self, edit: sublime.Edit) -> None:
backtrace += '\n'
backtrace += '
%s
+Type: %s
Modifiers: %s
%s