Skip to content

Commit 2be06be

Browse files
authored
Refactor symbol and completion item kinds (#2000)
1 parent 7aef143 commit 2be06be

File tree

5 files changed

+185
-97
lines changed

5 files changed

+185
-97
lines changed

plugin/core/protocol.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,35 @@ class CompletionItemTag:
5555
Deprecated = 1
5656

5757

58+
class SymbolKind:
59+
File = 1
60+
Module = 2
61+
Namespace = 3
62+
Package = 4
63+
Class = 5
64+
Method = 6
65+
Property = 7
66+
Field = 8
67+
Constructor = 9
68+
Enum = 10
69+
Interface = 11
70+
Function = 12
71+
Variable = 13
72+
Constant = 14
73+
String = 15
74+
Number = 16
75+
Boolean = 17
76+
Array = 18
77+
Object = 19
78+
Key = 20
79+
Null = 21
80+
EnumMember = 22
81+
Struct = 23
82+
Event = 24
83+
Operator = 25
84+
TypeParameter = 26
85+
86+
5887
class SymbolTag:
5988
Deprecated = 1
6089

plugin/core/sessions.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from .promise import Promise
2020
from .protocol import CodeAction, CodeLens, InsertTextMode, Location, LocationLink
2121
from .protocol import Command
22+
from .protocol import CompletionItemKind
2223
from .protocol import CompletionItemTag
2324
from .protocol import Diagnostic
2425
from .protocol import DiagnosticSeverity
@@ -36,6 +37,7 @@
3637
from .protocol import Response
3738
from .protocol import SemanticTokenModifiers
3839
from .protocol import SemanticTokenTypes
40+
from .protocol import SymbolKind
3941
from .protocol import SymbolTag
4042
from .protocol import WorkspaceFolder
4143
from .settings import client_configs
@@ -55,13 +57,11 @@
5557
from .url import filename_to_uri
5658
from .url import parse_uri
5759
from .version import __version__
58-
from .views import COMPLETION_KINDS
5960
from .views import extract_variables
6061
from .views import get_storage_path
6162
from .views import get_uri_and_range_from_location
6263
from .views import MarkdownLangMap
6364
from .views import SEMANTIC_TOKENS_MAP
64-
from .views import SYMBOL_KINDS
6565
from .workspace import is_subpath_of
6666
from abc import ABCMeta
6767
from abc import abstractmethod
@@ -186,18 +186,14 @@ def on_post_exit_async(self, session: 'Session', exit_code: int, exception: Opti
186186
pass
187187

188188

189-
def _sequence_to_lsp_indices(sequence: Sequence[Any]) -> List[int]:
190-
return list(range(1, len(sequence) + 1))
191-
192-
193-
def _enum_like_class_to_list(c: Type[object]) -> List[str]:
189+
def _enum_like_class_to_list(c: Type[object]) -> List[Union[int, str]]:
194190
return [v for k, v in c.__dict__.items() if not k.startswith('_')]
195191

196192

197193
def get_initialize_params(variables: Dict[str, str], workspace_folders: List[WorkspaceFolder],
198194
config: ClientConfig) -> dict:
199-
completion_kinds = _sequence_to_lsp_indices(COMPLETION_KINDS)
200-
symbol_kinds = _sequence_to_lsp_indices(SYMBOL_KINDS)
195+
completion_kinds = _enum_like_class_to_list(CompletionItemKind)
196+
symbol_kinds = _enum_like_class_to_list(SymbolKind)
201197
diagnostic_tag_value_set = _enum_like_class_to_list(DiagnosticTag)
202198
completion_tag_value_set = _enum_like_class_to_list(CompletionItemTag)
203199
symbol_tag_value_set = _enum_like_class_to_list(SymbolTag)

plugin/core/views.py

Lines changed: 139 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from .css import css as lsp_css
22
from .protocol import CompletionItem
3+
from .protocol import CompletionItemKind
34
from .protocol import CompletionItemTag
45
from .protocol import Diagnostic
56
from .protocol import DiagnosticRelatedInformation
67
from .protocol import DiagnosticSeverity
8+
from .protocol import DocumentHighlightKind
79
from .protocol import DocumentUri
810
from .protocol import ExperimentalTextDocumentRangeParams
911
from .protocol import Location
@@ -16,6 +18,7 @@
1618
from .protocol import Range
1719
from .protocol import RangeLsp
1820
from .protocol import Request
21+
from .protocol import SymbolKind
1922
from .protocol import TextDocumentIdentifier
2023
from .protocol import TextDocumentPositionParams
2124
from .settings import userprefs
@@ -47,65 +50,142 @@
4750
("hint", "hints", "region.bluish markup.info.hint.lsp", "Packages/LSP/icons/info.png", _baseflags | sublime.DRAW_STIPPLED_UNDERLINE, sublime.DRAW_NO_FILL), # noqa: E501
4851
] # type: List[Tuple[str, str, str, str, int, int]]
4952

50-
# The scope names mainly come from http://www.sublimetext.com/docs/3/scope_naming.html
51-
SYMBOL_KINDS = [
52-
# ST Kind Icon Display Name ST Scope
53-
(sublime.KIND_ID_NAVIGATION, "f", "File", "string"),
54-
(sublime.KIND_ID_NAMESPACE, "m", "Module", "entity.name.namespace"),
55-
(sublime.KIND_ID_NAMESPACE, "n", "Namespace", "entity.name.namespace"),
56-
(sublime.KIND_ID_NAMESPACE, "p", "Package", "entity.name.namespace"),
57-
(sublime.KIND_ID_TYPE, "c", "Class", "entity.name.class"),
58-
(sublime.KIND_ID_FUNCTION, "m", "Method", "entity.name.function"),
59-
(sublime.KIND_ID_VARIABLE, "p", "Property", "variable.other.member"),
60-
(sublime.KIND_ID_VARIABLE, "f", "Field", "variable.other.member"),
61-
(sublime.KIND_ID_FUNCTION, "c", "Constructor", "entity.name.function.constructor"),
62-
(sublime.KIND_ID_TYPE, "e", "Enum", "entity.name.enum"),
63-
(sublime.KIND_ID_VARIABLE, "i", "Interface", "entity.name.interface"),
64-
(sublime.KIND_ID_FUNCTION, "f", "Function", "entity.name.function"),
65-
(sublime.KIND_ID_VARIABLE, "v", "Variable", "variable.other.readwrite"),
66-
(sublime.KIND_ID_VARIABLE, "c", "Constant", "variable.other.constant"),
67-
(sublime.KIND_ID_MARKUP, "s", "String", "string"),
68-
(sublime.KIND_ID_VARIABLE, "n", "Number", "constant.numeric"),
69-
(sublime.KIND_ID_VARIABLE, "b", "Boolean", "constant.language"),
70-
(sublime.KIND_ID_TYPE, "a", "Array", "meta.sequence"), # [scope taken from JSON.sublime-syntax]
71-
(sublime.KIND_ID_TYPE, "o", "Object", "meta.mapping"), # [scope taken from JSON.sublime-syntax]
72-
(sublime.KIND_ID_NAVIGATION, "k", "Key", "meta.mapping.key string"), # [from JSON.sublime-syntax]
73-
(sublime.KIND_ID_VARIABLE, "n", "Null", "constant.language"),
74-
(sublime.KIND_ID_VARIABLE, "e", "Enum Member", "constant.other.enum"), # Based on {Java,C#}.sublime-syntax
75-
(sublime.KIND_ID_TYPE, "s", "Struct", "entity.name.struct"),
76-
(sublime.KIND_ID_TYPE, "e", "Event", "storage.modifier"), # [scope taken from C#.sublime-syntax]
77-
(sublime.KIND_ID_FUNCTION, "o", "Operator", "keyword.operator"),
78-
(sublime.KIND_ID_TYPE, "t", "Type Parameter", "storage.type"),
79-
]
53+
# sublime.Kind tuples for sublime.CompletionItem, sublime.QuickPanelItem, sublime.ListInputItem
54+
# https://www.sublimetext.com/docs/api_reference.html#sublime.Kind
55+
KIND_ARRAY = (sublime.KIND_ID_TYPE, "a", "Array")
56+
KIND_BOOLEAN = (sublime.KIND_ID_VARIABLE, "b", "Boolean")
57+
KIND_CLASS = (sublime.KIND_ID_TYPE, "c", "Class")
58+
KIND_COLOR = (sublime.KIND_ID_MARKUP, "c", "Color")
59+
KIND_CONSTANT = (sublime.KIND_ID_VARIABLE, "c", "Constant")
60+
KIND_CONSTRUCTOR = (sublime.KIND_ID_FUNCTION, "c", "Constructor")
61+
KIND_ENUM = (sublime.KIND_ID_TYPE, "e", "Enum")
62+
KIND_ENUMMEMBER = (sublime.KIND_ID_VARIABLE, "e", "Enum Member")
63+
KIND_EVENT = (sublime.KIND_ID_FUNCTION, "e", "Event")
64+
KIND_FIELD = (sublime.KIND_ID_VARIABLE, "f", "Field")
65+
KIND_FILE = (sublime.KIND_ID_NAVIGATION, "f", "File")
66+
KIND_FOLDER = (sublime.KIND_ID_NAVIGATION, "f", "Folder")
67+
KIND_FUNCTION = (sublime.KIND_ID_FUNCTION, "f", "Function")
68+
KIND_INTERFACE = (sublime.KIND_ID_TYPE, "i", "Interface")
69+
KIND_KEY = (sublime.KIND_ID_NAVIGATION, "k", "Key")
70+
KIND_KEYWORD = (sublime.KIND_ID_KEYWORD, "k", "Keyword")
71+
KIND_METHOD = (sublime.KIND_ID_FUNCTION, "m", "Method")
72+
KIND_MODULE = (sublime.KIND_ID_NAMESPACE, "m", "Module")
73+
KIND_NAMESPACE = (sublime.KIND_ID_NAMESPACE, "n", "Namespace")
74+
KIND_NULL = (sublime.KIND_ID_VARIABLE, "n", "Null")
75+
KIND_NUMBER = (sublime.KIND_ID_VARIABLE, "n", "Number")
76+
KIND_OBJECT = (sublime.KIND_ID_TYPE, "o", "Object")
77+
KIND_OPERATOR = (sublime.KIND_ID_KEYWORD, "o", "Operator")
78+
KIND_PACKAGE = (sublime.KIND_ID_NAMESPACE, "p", "Package")
79+
KIND_PROPERTY = (sublime.KIND_ID_VARIABLE, "p", "Property")
80+
KIND_REFERENCE = (sublime.KIND_ID_NAVIGATION, "r", "Reference")
81+
KIND_SNIPPET = (sublime.KIND_ID_SNIPPET, "s", "Snippet")
82+
KIND_STRING = (sublime.KIND_ID_VARIABLE, "s", "String")
83+
KIND_STRUCT = (sublime.KIND_ID_TYPE, "s", "Struct")
84+
KIND_TEXT = (sublime.KIND_ID_MARKUP, "t", "Text")
85+
KIND_TYPEPARAMETER = (sublime.KIND_ID_TYPE, "t", "Type Parameter")
86+
KIND_UNIT = (sublime.KIND_ID_VARIABLE, "u", "Unit")
87+
KIND_VALUE = (sublime.KIND_ID_VARIABLE, "v", "Value")
88+
KIND_VARIABLE = (sublime.KIND_ID_VARIABLE, "v", "Variable")
89+
90+
KIND_UNSPECIFIED = (sublime.KIND_ID_AMBIGUOUS, "?", "???")
91+
92+
COMPLETION_KINDS = {
93+
CompletionItemKind.Text: KIND_TEXT,
94+
CompletionItemKind.Method: KIND_METHOD,
95+
CompletionItemKind.Function: KIND_FUNCTION,
96+
CompletionItemKind.Constructor: KIND_CONSTRUCTOR,
97+
CompletionItemKind.Field: KIND_FIELD,
98+
CompletionItemKind.Variable: KIND_VARIABLE,
99+
CompletionItemKind.Class: KIND_CLASS,
100+
CompletionItemKind.Interface: KIND_INTERFACE,
101+
CompletionItemKind.Module: KIND_MODULE,
102+
CompletionItemKind.Property: KIND_PROPERTY,
103+
CompletionItemKind.Unit: KIND_UNIT,
104+
CompletionItemKind.Value: KIND_VALUE,
105+
CompletionItemKind.Enum: KIND_ENUM,
106+
CompletionItemKind.Keyword: KIND_KEYWORD,
107+
CompletionItemKind.Snippet: KIND_SNIPPET,
108+
CompletionItemKind.Color: KIND_COLOR,
109+
CompletionItemKind.File: KIND_FILE,
110+
CompletionItemKind.Reference: KIND_REFERENCE,
111+
CompletionItemKind.Folder: KIND_FOLDER,
112+
CompletionItemKind.EnumMember: KIND_ENUMMEMBER,
113+
CompletionItemKind.Constant: KIND_CONSTANT,
114+
CompletionItemKind.Struct: KIND_STRUCT,
115+
CompletionItemKind.Event: KIND_EVENT,
116+
CompletionItemKind.Operator: KIND_OPERATOR,
117+
CompletionItemKind.TypeParameter: KIND_TYPEPARAMETER
118+
}
80119

81-
COMPLETION_KINDS = [
82-
# ST Kind Icon Display Name
83-
(sublime.KIND_ID_MARKUP, "t", "Text"),
84-
(sublime.KIND_ID_FUNCTION, "m", "Method"),
85-
(sublime.KIND_ID_FUNCTION, "f", "Function"),
86-
(sublime.KIND_ID_FUNCTION, "c", "Constructor"),
87-
(sublime.KIND_ID_VARIABLE, "f", "Field"),
88-
(sublime.KIND_ID_VARIABLE, "v", "Variable"),
89-
(sublime.KIND_ID_TYPE, "c", "Class"),
90-
(sublime.KIND_ID_TYPE, "i", "Interface"),
91-
(sublime.KIND_ID_NAMESPACE, "m", "Module"),
92-
(sublime.KIND_ID_VARIABLE, "p", "Property"),
93-
(sublime.KIND_ID_VARIABLE, "u", "Unit"),
94-
(sublime.KIND_ID_VARIABLE, "v", "Value"),
95-
(sublime.KIND_ID_TYPE, "e", "Enum"),
96-
(sublime.KIND_ID_KEYWORD, "k", "Keyword"),
97-
(sublime.KIND_ID_SNIPPET, "s", "Snippet"),
98-
(sublime.KIND_ID_MARKUP, "c", "Color"),
99-
(sublime.KIND_ID_NAVIGATION, "f", "File"),
100-
(sublime.KIND_ID_NAVIGATION, "r", "Reference"),
101-
(sublime.KIND_ID_NAMESPACE, "f", "Folder"),
102-
(sublime.KIND_ID_VARIABLE, "e", "Enum Member"),
103-
(sublime.KIND_ID_VARIABLE, "c", "Constant"),
104-
(sublime.KIND_ID_TYPE, "s", "Struct"),
105-
(sublime.KIND_ID_TYPE, "e", "Event"),
106-
(sublime.KIND_ID_KEYWORD, "o", "Operator"),
107-
(sublime.KIND_ID_TYPE, "t", "Type Parameter"),
108-
]
120+
SYMBOL_KINDS = {
121+
SymbolKind.File: KIND_FILE,
122+
SymbolKind.Module: KIND_MODULE,
123+
SymbolKind.Namespace: KIND_NAMESPACE,
124+
SymbolKind.Package: KIND_PACKAGE,
125+
SymbolKind.Class: KIND_CLASS,
126+
SymbolKind.Method: KIND_METHOD,
127+
SymbolKind.Property: KIND_PROPERTY,
128+
SymbolKind.Field: KIND_FIELD,
129+
SymbolKind.Constructor: KIND_CONSTRUCTOR,
130+
SymbolKind.Enum: KIND_ENUM,
131+
SymbolKind.Interface: KIND_INTERFACE,
132+
SymbolKind.Function: KIND_FUNCTION,
133+
SymbolKind.Variable: KIND_VARIABLE,
134+
SymbolKind.Constant: KIND_CONSTANT,
135+
SymbolKind.String: KIND_STRING,
136+
SymbolKind.Number: KIND_NUMBER,
137+
SymbolKind.Boolean: KIND_BOOLEAN,
138+
SymbolKind.Array: KIND_ARRAY,
139+
SymbolKind.Object: KIND_OBJECT,
140+
SymbolKind.Key: KIND_KEY,
141+
SymbolKind.Null: KIND_NULL,
142+
SymbolKind.EnumMember: KIND_ENUMMEMBER,
143+
SymbolKind.Struct: KIND_STRUCT,
144+
SymbolKind.Event: KIND_EVENT,
145+
SymbolKind.Operator: KIND_OPERATOR,
146+
SymbolKind.TypeParameter: KIND_TYPEPARAMETER
147+
}
148+
149+
SYMBOL_KIND_SCOPES = {
150+
SymbolKind.File: "string",
151+
SymbolKind.Module: "entity.name.namespace",
152+
SymbolKind.Namespace: "entity.name.namespace",
153+
SymbolKind.Package: "entity.name.namespace",
154+
SymbolKind.Class: "entity.name.class",
155+
SymbolKind.Method: "entity.name.function",
156+
SymbolKind.Property: "variable.other.member",
157+
SymbolKind.Field: "variable.other.member",
158+
SymbolKind.Constructor: "entity.name.function.constructor",
159+
SymbolKind.Enum: "entity.name.enum",
160+
SymbolKind.Interface: "entity.name.interface",
161+
SymbolKind.Function: "entity.name.function",
162+
SymbolKind.Variable: "variable.other",
163+
SymbolKind.Constant: "variable.other.constant",
164+
SymbolKind.String: "string",
165+
SymbolKind.Number: "constant.numeric",
166+
SymbolKind.Boolean: "constant.language.boolean",
167+
SymbolKind.Array: "meta.sequence",
168+
SymbolKind.Object: "meta.mapping",
169+
SymbolKind.Key: "meta.mapping.key string",
170+
SymbolKind.Null: "constant.language.null",
171+
SymbolKind.EnumMember: "constant.other.enum",
172+
SymbolKind.Struct: "entity.name.struct",
173+
SymbolKind.Event: "entity.name.function",
174+
SymbolKind.Operator: "keyword.operator",
175+
SymbolKind.TypeParameter: "variable.parameter.type"
176+
}
177+
178+
DOCUMENT_HIGHLIGHT_KINDS = {
179+
DocumentHighlightKind.Text: "text",
180+
DocumentHighlightKind.Read: "read",
181+
DocumentHighlightKind.Write: "write"
182+
}
183+
184+
DOCUMENT_HIGHLIGHT_KIND_SCOPES = {
185+
DocumentHighlightKind.Text: "region.bluish markup.highlight.text.lsp",
186+
DocumentHighlightKind.Read: "region.greenish markup.highlight.read.lsp",
187+
DocumentHighlightKind.Write: "region.yellowish markup.highlight.write.lsp"
188+
}
109189

110190
SEMANTIC_TOKENS_MAP = {
111191
"namespace": "variable.other.namespace.lsp",
@@ -877,10 +957,7 @@ def format_completion(
877957
) -> sublime.CompletionItem:
878958
# This is a hot function. Don't do heavy computations or IO in this function.
879959
item_kind = item.get("kind")
880-
if isinstance(item_kind, int) and 1 <= item_kind <= len(COMPLETION_KINDS):
881-
kind = COMPLETION_KINDS[item_kind - 1]
882-
else:
883-
kind = sublime.KIND_AMBIGUOUS
960+
kind = COMPLETION_KINDS.get(item_kind, KIND_UNSPECIFIED) if item_kind else KIND_UNSPECIFIED
884961

885962
if _is_completion_item_deprecated(item):
886963
kind = (kind[0], '!', "⚠ {} - Deprecated".format(kind[2]))

plugin/documents.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
from .core.url import parse_uri
2929
from .core.url import view_to_uri
3030
from .core.views import diagnostic_severity
31+
from .core.views import DOCUMENT_HIGHLIGHT_KIND_SCOPES
32+
from .core.views import DOCUMENT_HIGHLIGHT_KINDS
3133
from .core.views import first_selection_region
3234
from .core.views import format_completion
3335
from .core.views import make_command_link
@@ -53,18 +55,6 @@
5355

5456
SUBLIME_WORD_MASK = 515
5557

56-
_kind2name = {
57-
DocumentHighlightKind.Text: "text",
58-
DocumentHighlightKind.Read: "read",
59-
DocumentHighlightKind.Write: "write"
60-
}
61-
62-
_kind2scope = {
63-
DocumentHighlightKind.Text: "region.bluish markup.highlight.text.lsp",
64-
DocumentHighlightKind.Read: "region.greenish markup.highlight.read.lsp",
65-
DocumentHighlightKind.Write: "region.yellowish markup.highlight.write.lsp"
66-
}
67-
6858
Flags = int
6959
ResolveCompletionsFn = Callable[[List[sublime.CompletionItem], Flags], None]
7060

@@ -617,7 +607,7 @@ def _resolve_visible_code_lenses_async(self) -> None:
617607
# --- textDocument/documentHighlight -------------------------------------------------------------------------------
618608

619609
def _highlights_key(self, kind: int, multiline: bool) -> str:
620-
return "lsp_highlight_{}{}".format(_kind2name[kind], "m" if multiline else "s")
610+
return "lsp_highlight_{}{}".format(DOCUMENT_HIGHLIGHT_KINDS[kind], "m" if multiline else "s")
621611

622612
def _clear_highlight_regions(self) -> None:
623613
for kind in range(1, 4):
@@ -663,7 +653,7 @@ def render_highlights_on_main_thread() -> None:
663653
kind, multiline = tup
664654
key = self._highlights_key(kind, multiline)
665655
flags = flags_multi if multiline else flags_single
666-
self.view.add_regions(key, regions, scope=_kind2scope[kind], flags=flags)
656+
self.view.add_regions(key, regions, scope=DOCUMENT_HIGHLIGHT_KIND_SCOPES[kind], flags=flags)
667657

668658
sublime.set_timeout(render_highlights_on_main_thread)
669659

0 commit comments

Comments
 (0)