Skip to content

Commit 846374a

Browse files
committed
refactor capabilites
1 parent 5ab947e commit 846374a

File tree

3 files changed

+252
-87
lines changed

3 files changed

+252
-87
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
defmodule ElixirLS.LanguageServer.ClientCapabilities do
2+
@moduledoc """
3+
Utilities for checking client capabilities from LSP client capabilities.
4+
5+
This module provides a centralized way to store and access client capabilities
6+
using persistent_term for efficient access across the application.
7+
"""
8+
9+
@capabilities_key :language_server_client_capabilities
10+
11+
@doc """
12+
Stores the client capabilities in persistent_term for global access.
13+
"""
14+
def store(client_capabilities) do
15+
:persistent_term.put(@capabilities_key, client_capabilities)
16+
end
17+
18+
@doc """
19+
Retrieves the stored client capabilities from persistent_term.
20+
Returns nil if no capabilities have been stored.
21+
"""
22+
def get do
23+
:persistent_term.get(@capabilities_key, nil)
24+
end
25+
26+
@doc """
27+
Checks if the client supports hierarchical document symbols.
28+
"""
29+
def hierarchical_document_symbol_support? do
30+
case get() do
31+
%GenLSP.Structures.ClientCapabilities{
32+
text_document: %GenLSP.Structures.TextDocumentClientCapabilities{
33+
document_symbol: %GenLSP.Structures.DocumentSymbolClientCapabilities{
34+
hierarchical_document_symbol_support: hierarchical_document_symbol_support
35+
}
36+
}
37+
} ->
38+
hierarchical_document_symbol_support
39+
40+
_ ->
41+
false
42+
end
43+
end
44+
45+
@doc """
46+
Checks if the client supports snippets in completion items.
47+
"""
48+
def snippets_supported? do
49+
case get() do
50+
%GenLSP.Structures.ClientCapabilities{
51+
text_document: %GenLSP.Structures.TextDocumentClientCapabilities{
52+
completion: %GenLSP.Structures.CompletionClientCapabilities{
53+
completion_item: %{snippet_support: snippet_support}
54+
}
55+
}
56+
} ->
57+
snippet_support
58+
59+
_ ->
60+
false
61+
end
62+
end
63+
64+
@doc """
65+
Checks if the client supports deprecated completion items.
66+
67+
Note: deprecated as of Language Server Protocol Specification - 3.15
68+
"""
69+
def deprecated_supported? do
70+
case get() do
71+
%GenLSP.Structures.ClientCapabilities{
72+
text_document: %GenLSP.Structures.TextDocumentClientCapabilities{
73+
completion: %GenLSP.Structures.CompletionClientCapabilities{
74+
completion_item: %{deprecated_support: deprecated_support}
75+
}
76+
}
77+
} ->
78+
deprecated_support
79+
80+
_ ->
81+
false
82+
end
83+
end
84+
85+
@doc """
86+
Returns the list of supported completion item tags, or empty list if not supported.
87+
"""
88+
def tags_supported do
89+
case get() do
90+
%GenLSP.Structures.ClientCapabilities{
91+
text_document: %GenLSP.Structures.TextDocumentClientCapabilities{
92+
completion: %GenLSP.Structures.CompletionClientCapabilities{
93+
completion_item: %{tag_support: %{value_set: value_set}}
94+
}
95+
}
96+
} ->
97+
value_set
98+
99+
_ ->
100+
[]
101+
end
102+
end
103+
104+
@doc """
105+
Checks if the client supports signature help.
106+
"""
107+
def signature_help_supported? do
108+
case get() do
109+
%GenLSP.Structures.ClientCapabilities{
110+
text_document: %GenLSP.Structures.TextDocumentClientCapabilities{
111+
signature_help: %GenLSP.Structures.SignatureHelpClientCapabilities{}
112+
}
113+
} ->
114+
true
115+
116+
_ ->
117+
false
118+
end
119+
end
120+
121+
@doc """
122+
Checks if the client supports dynamic registration for workspace/didChangeConfiguration.
123+
"""
124+
def supports_dynamic_configuration_change_registration? do
125+
case get() do
126+
%GenLSP.Structures.ClientCapabilities{
127+
workspace: %GenLSP.Structures.WorkspaceClientCapabilities{
128+
did_change_configuration: %GenLSP.Structures.DidChangeConfigurationClientCapabilities{
129+
dynamic_registration: dynamic_registration
130+
}
131+
}
132+
} ->
133+
dynamic_registration
134+
135+
_ ->
136+
false
137+
end
138+
end
139+
140+
@doc """
141+
Checks if the client supports dynamic registration for workspace/didChangeWatchedFiles.
142+
"""
143+
def supports_dynamic_file_watcher_registration? do
144+
case get() do
145+
%GenLSP.Structures.ClientCapabilities{
146+
workspace: %GenLSP.Structures.WorkspaceClientCapabilities{
147+
did_change_watched_files: %GenLSP.Structures.DidChangeWatchedFilesClientCapabilities{
148+
dynamic_registration: dynamic_registration
149+
}
150+
}
151+
} ->
152+
dynamic_registration
153+
154+
_ ->
155+
false
156+
end
157+
end
158+
159+
@doc """
160+
Checks if the client supports workspace/configuration requests.
161+
"""
162+
def supports_configuration? do
163+
case get() do
164+
%GenLSP.Structures.ClientCapabilities{
165+
workspace: %GenLSP.Structures.WorkspaceClientCapabilities{
166+
configuration: configuration
167+
}
168+
} ->
169+
configuration
170+
171+
_ ->
172+
false
173+
end
174+
end
175+
176+
@doc """
177+
Checks if the client supports workspace symbol tags.
178+
"""
179+
def workspace_symbol_tag_support? do
180+
case get() do
181+
%GenLSP.Structures.ClientCapabilities{
182+
workspace: %GenLSP.Structures.WorkspaceClientCapabilities{
183+
symbol: %{tag_support: tag_support}
184+
}
185+
}
186+
when tag_support != nil ->
187+
true
188+
189+
_ ->
190+
false
191+
end
192+
end
193+
end

apps/language_server/lib/language_server/providers/workspace_symbols.ex

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
66
"""
77
use GenServer
88

9+
alias ElixirLS.LanguageServer.ClientCapabilities
910
alias ElixirLS.LanguageServer.ErlangSourceFile
1011
alias ElixirLS.LanguageServer.SourceFile
1112
alias ElixirLS.LanguageServer.Providers.SymbolUtils
@@ -132,21 +133,9 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
132133

133134
@impl GenServer
134135
def handle_cast({:notify_settings_stored, project_dir}, state) do
135-
# as of LSP 3.17 only one tag is defined and clients are required to silently ignore unknown tags
136+
# as of LSP 3.18 only one tag is defined and clients are required to silently ignore unknown tags
136137
# so there's no need to pass the list
137-
tag_support =
138-
case :persistent_term.get(:language_server_client_capabilities) do
139-
%GenLSP.Structures.ClientCapabilities{
140-
workspace: %GenLSP.Structures.WorkspaceClientCapabilities{
141-
symbol: %{tag_support: tag_support}
142-
}
143-
}
144-
when tag_support != nil ->
145-
true
146-
147-
_ ->
148-
false
149-
end
138+
tag_support = ClientCapabilities.workspace_symbol_tag_support?()
150139

151140
{:noreply, %{state | project_dir: project_dir, tag_support: tag_support}}
152141
end

0 commit comments

Comments
 (0)