ruby-lsp 0.13.2 → 0.13.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -0
- data/VERSION +1 -1
- data/lib/ruby_lsp/check_docs.rb +3 -3
- data/lib/ruby_lsp/document.rb +12 -0
- data/lib/ruby_lsp/executor.rb +77 -266
- data/lib/ruby_lsp/listener.rb +1 -50
- data/lib/ruby_lsp/listeners/code_lens.rb +233 -0
- data/lib/ruby_lsp/listeners/completion.rb +275 -0
- data/lib/ruby_lsp/listeners/definition.rb +158 -0
- data/lib/ruby_lsp/listeners/document_highlight.rb +556 -0
- data/lib/ruby_lsp/listeners/document_link.rb +162 -0
- data/lib/ruby_lsp/listeners/document_symbol.rb +223 -0
- data/lib/ruby_lsp/listeners/folding_ranges.rb +271 -0
- data/lib/ruby_lsp/listeners/hover.rb +152 -0
- data/lib/ruby_lsp/listeners/inlay_hints.rb +80 -0
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +430 -0
- data/lib/ruby_lsp/listeners/signature_help.rb +74 -0
- data/lib/ruby_lsp/requests/code_action_resolve.rb +4 -4
- data/lib/ruby_lsp/requests/code_actions.rb +13 -4
- data/lib/ruby_lsp/requests/code_lens.rb +21 -221
- data/lib/ruby_lsp/requests/completion.rb +64 -244
- data/lib/ruby_lsp/requests/definition.rb +34 -147
- data/lib/ruby_lsp/requests/diagnostics.rb +17 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +12 -536
- data/lib/ruby_lsp/requests/document_link.rb +11 -132
- data/lib/ruby_lsp/requests/document_symbol.rb +23 -210
- data/lib/ruby_lsp/requests/folding_ranges.rb +16 -252
- data/lib/ruby_lsp/requests/formatting.rb +4 -4
- data/lib/ruby_lsp/requests/hover.rb +48 -92
- data/lib/ruby_lsp/requests/inlay_hints.rb +23 -56
- data/lib/ruby_lsp/requests/on_type_formatting.rb +16 -4
- data/lib/ruby_lsp/requests/request.rb +17 -0
- data/lib/ruby_lsp/requests/selection_ranges.rb +4 -3
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +21 -408
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +4 -4
- data/lib/ruby_lsp/requests/signature_help.rb +43 -51
- data/lib/ruby_lsp/requests/support/common.rb +3 -2
- data/lib/ruby_lsp/requests/support/dependency_detector.rb +2 -0
- data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +2 -2
- data/lib/ruby_lsp/requests/workspace_symbol.rb +5 -4
- data/lib/ruby_lsp/requests.rb +1 -1
- data/lib/ruby_lsp/utils.rb +8 -0
- metadata +17 -6
- data/lib/ruby_lsp/requests/base_request.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 675bc1c9ddbcb8c05d591e184e2cf77914a6fcfa4af5db6178864063a910e0bd
|
4
|
+
data.tar.gz: 3f14554ce578fe5457ad90f2500b5267fded390e17b58142a2a174928630c53c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55fabbd6b161a499b378eead24ba073a7729d7772d702585b995efc3667c761a39544bb09c289c0ef16fa3300b907a7573173bbe7966b6656cddf912c60b7fd7
|
7
|
+
data.tar.gz: 85c9e57ae099be6fc957cf6a0ad63e07b6eb5e207770b3ea5cbd0cd328383ca9f76314c16f03f1a2707ce78991a6ce20dc382fb17ce4ed8ce1e7e4fdd6c5d5bb
|
data/README.md
CHANGED
@@ -46,6 +46,36 @@ See the [documentation](https://shopify.github.io/ruby-lsp) for more in-depth de
|
|
46
46
|
For creating rich themes for Ruby using the semantic highlighting information, see the [semantic highlighting
|
47
47
|
documentation](SEMANTIC_HIGHLIGHTING.md).
|
48
48
|
|
49
|
+
### Configuring code indexing
|
50
|
+
|
51
|
+
By default, the Ruby LSP indexes all Ruby files defined in the current project and all of its dependencies, including
|
52
|
+
default gems, except for
|
53
|
+
|
54
|
+
- Gems that only appear under the `:development` group
|
55
|
+
- All Ruby files under `test/**/*.rb`
|
56
|
+
|
57
|
+
By creating a `.index.yml` file, these configurations can be overridden and tuned.
|
58
|
+
|
59
|
+
```yaml
|
60
|
+
# Exclude files based on a given pattern. Often used to exclude test files or fixtures
|
61
|
+
excluded_patterns:
|
62
|
+
- "**/spec/**/*.rb"
|
63
|
+
|
64
|
+
# Include files based on a given pattern. Can be used to index Ruby files that use different extensions
|
65
|
+
included_patterns:
|
66
|
+
- "**/bin/*"
|
67
|
+
|
68
|
+
# Exclude gems by name. If a gem is never referenced in the project's code and is only used as a tool, excluding it will
|
69
|
+
# speed up indexing and reduce the amount of results in features like definition or completion
|
70
|
+
excluded_gems:
|
71
|
+
- rubocop
|
72
|
+
- pathname
|
73
|
+
|
74
|
+
# Include gems by name. Normally used to include development gems that are excluded by default
|
75
|
+
included_gems:
|
76
|
+
- prism
|
77
|
+
```
|
78
|
+
|
49
79
|
### Addons
|
50
80
|
|
51
81
|
The Ruby LSP provides an addon system that allows other gems to enhance the base functionality with more editor
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.13.
|
1
|
+
0.13.4
|
data/lib/ruby_lsp/check_docs.rb
CHANGED
@@ -51,15 +51,15 @@ module RubyLsp
|
|
51
51
|
|
52
52
|
# Find all classes that inherit from BaseRequest or Listener, which are the ones we want to make sure are
|
53
53
|
# documented
|
54
|
-
features = ObjectSpace.each_object(Class).
|
54
|
+
features = ObjectSpace.each_object(Class).select do |k|
|
55
55
|
klass = T.unsafe(k)
|
56
|
-
klass
|
56
|
+
klass < Requests::Request
|
57
57
|
end
|
58
58
|
|
59
59
|
missing_docs = T.let(Hash.new { |h, k| h[k] = [] }, T::Hash[String, T::Array[String]])
|
60
60
|
|
61
61
|
features.each do |klass|
|
62
|
-
class_name = T.
|
62
|
+
class_name = T.unsafe(klass).name
|
63
63
|
file_path, line_number = Module.const_source_location(class_name)
|
64
64
|
next unless file_path && line_number
|
65
65
|
|
data/lib/ruby_lsp/document.rb
CHANGED
@@ -173,6 +173,18 @@ module RubyLsp
|
|
173
173
|
[closest, parent, nesting.map { |n| n.constant_path.location.slice }]
|
174
174
|
end
|
175
175
|
|
176
|
+
sig { returns(T::Boolean) }
|
177
|
+
def sorbet_sigil_is_true_or_higher
|
178
|
+
parse_result.magic_comments.any? do |comment|
|
179
|
+
comment.key == "typed" && ["true", "strict", "strong"].include?(comment.value)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
sig { returns(T::Boolean) }
|
184
|
+
def typechecker_enabled?
|
185
|
+
DependencyDetector.instance.typechecker && sorbet_sigil_is_true_or_higher
|
186
|
+
end
|
187
|
+
|
176
188
|
class Scanner
|
177
189
|
extend T::Sig
|
178
190
|
|
data/lib/ruby_lsp/executor.rb
CHANGED
@@ -94,7 +94,7 @@ module RubyLsp
|
|
94
94
|
cached_response = document.cache_get(request[:method])
|
95
95
|
return cached_response if cached_response
|
96
96
|
|
97
|
-
# Run
|
97
|
+
# Run requests for the document
|
98
98
|
dispatcher = Prism::Dispatcher.new
|
99
99
|
folding_range = Requests::FoldingRanges.new(document.parse_result.comments, dispatcher)
|
100
100
|
document_symbol = Requests::DocumentSymbol.new(dispatcher)
|
@@ -107,13 +107,13 @@ module RubyLsp
|
|
107
107
|
|
108
108
|
# Store all responses retrieve in this round of visits in the cache and then return the response for the request
|
109
109
|
# we actually received
|
110
|
-
document.cache_set("textDocument/foldingRange", folding_range.
|
111
|
-
document.cache_set("textDocument/documentSymbol", document_symbol.
|
112
|
-
document.cache_set("textDocument/documentLink", document_link.
|
113
|
-
document.cache_set("textDocument/codeLens", code_lens.
|
110
|
+
document.cache_set("textDocument/foldingRange", folding_range.perform)
|
111
|
+
document.cache_set("textDocument/documentSymbol", document_symbol.perform)
|
112
|
+
document.cache_set("textDocument/documentLink", document_link.perform)
|
113
|
+
document.cache_set("textDocument/codeLens", code_lens.perform)
|
114
114
|
document.cache_set(
|
115
115
|
"textDocument/semanticTokens/full",
|
116
|
-
Requests::Support::SemanticTokenEncoder.new.encode(semantic_highlighting.
|
116
|
+
Requests::Support::SemanticTokenEncoder.new.encode(semantic_highlighting.perform),
|
117
117
|
)
|
118
118
|
document.cache_get(request[:method])
|
119
119
|
when "textDocument/semanticTokens/range"
|
@@ -143,13 +143,30 @@ module RubyLsp
|
|
143
143
|
nil
|
144
144
|
end
|
145
145
|
when "textDocument/documentHighlight"
|
146
|
-
|
146
|
+
dispatcher = Prism::Dispatcher.new
|
147
|
+
document = @store.get(uri)
|
148
|
+
request = Requests::DocumentHighlight.new(document, request.dig(:params, :position), dispatcher)
|
149
|
+
dispatcher.dispatch(document.tree)
|
150
|
+
request.perform
|
147
151
|
when "textDocument/onTypeFormatting"
|
148
152
|
on_type_formatting(uri, request.dig(:params, :position), request.dig(:params, :ch))
|
149
153
|
when "textDocument/hover"
|
150
|
-
|
154
|
+
dispatcher = Prism::Dispatcher.new
|
155
|
+
document = @store.get(uri)
|
156
|
+
Requests::Hover.new(
|
157
|
+
document,
|
158
|
+
@index,
|
159
|
+
request.dig(:params, :position),
|
160
|
+
dispatcher,
|
161
|
+
document.typechecker_enabled?,
|
162
|
+
).perform
|
151
163
|
when "textDocument/inlayHint"
|
152
|
-
|
164
|
+
hints_configurations = T.must(@store.features_configuration.dig(:inlayHint))
|
165
|
+
dispatcher = Prism::Dispatcher.new
|
166
|
+
document = @store.get(uri)
|
167
|
+
request = Requests::InlayHints.new(document, request.dig(:params, :range), hints_configurations, dispatcher)
|
168
|
+
dispatcher.visit(document.tree)
|
169
|
+
request.perform
|
153
170
|
when "textDocument/codeAction"
|
154
171
|
code_action(uri, request.dig(:params, :range), request.dig(:params, :context))
|
155
172
|
when "codeAction/resolve"
|
@@ -169,11 +186,36 @@ module RubyLsp
|
|
169
186
|
nil
|
170
187
|
end
|
171
188
|
when "textDocument/completion"
|
172
|
-
|
173
|
-
|
174
|
-
|
189
|
+
dispatcher = Prism::Dispatcher.new
|
190
|
+
document = @store.get(uri)
|
191
|
+
Requests::Completion.new(
|
192
|
+
document,
|
193
|
+
@index,
|
194
|
+
request.dig(:params, :position),
|
195
|
+
document.typechecker_enabled?,
|
196
|
+
dispatcher,
|
197
|
+
).perform
|
175
198
|
when "textDocument/signatureHelp"
|
176
|
-
|
199
|
+
dispatcher = Prism::Dispatcher.new
|
200
|
+
document = @store.get(uri)
|
201
|
+
|
202
|
+
Requests::SignatureHelp.new(
|
203
|
+
document,
|
204
|
+
@index,
|
205
|
+
request.dig(:params, :position),
|
206
|
+
request.dig(:params, :context),
|
207
|
+
dispatcher,
|
208
|
+
).perform
|
209
|
+
when "textDocument/definition"
|
210
|
+
dispatcher = Prism::Dispatcher.new
|
211
|
+
document = @store.get(uri)
|
212
|
+
Requests::Definition.new(
|
213
|
+
document,
|
214
|
+
@index,
|
215
|
+
request.dig(:params, :position),
|
216
|
+
dispatcher,
|
217
|
+
document.typechecker_enabled?,
|
218
|
+
).perform
|
177
219
|
when "workspace/didChangeWatchedFiles"
|
178
220
|
did_change_watched_files(request.dig(:params, :changes))
|
179
221
|
when "workspace/symbol"
|
@@ -243,96 +285,14 @@ module RubyLsp
|
|
243
285
|
end
|
244
286
|
end
|
245
287
|
|
246
|
-
sig do
|
247
|
-
params(
|
248
|
-
uri: URI::Generic,
|
249
|
-
position: T::Hash[Symbol, T.untyped],
|
250
|
-
context: T::Hash[Symbol, T.untyped],
|
251
|
-
).returns(T.any(T.nilable(Interface::SignatureHelp), T::Hash[Symbol, T.untyped]))
|
252
|
-
end
|
253
|
-
def signature_help(uri, position, context)
|
254
|
-
current_signature = context[:activeSignatureHelp]
|
255
|
-
document = @store.get(uri)
|
256
|
-
target, parent, nesting = document.locate_node(
|
257
|
-
{ line: position[:line], character: position[:character] - 2 },
|
258
|
-
node_types: [Prism::CallNode],
|
259
|
-
)
|
260
|
-
|
261
|
-
# If we're typing a nested method call (e.g.: `foo(bar)`), then we may end up locating `bar` as the target method
|
262
|
-
# call incorrectly. To correct that, we check if there's an active signature with the same name as the parent node
|
263
|
-
# and then replace the target
|
264
|
-
if current_signature && parent.is_a?(Prism::CallNode)
|
265
|
-
active_signature = current_signature[:activeSignature] || 0
|
266
|
-
|
267
|
-
if current_signature.dig(:signatures, active_signature, :label)&.start_with?(parent.message)
|
268
|
-
target = parent
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
dispatcher = Prism::Dispatcher.new
|
273
|
-
listener = Requests::SignatureHelp.new(context, nesting, @index, dispatcher)
|
274
|
-
dispatcher.dispatch_once(target)
|
275
|
-
listener.response
|
276
|
-
end
|
277
|
-
|
278
288
|
sig { params(query: T.nilable(String)).returns(T::Array[Interface::WorkspaceSymbol]) }
|
279
289
|
def workspace_symbol(query)
|
280
|
-
Requests::WorkspaceSymbol.new(query, @index).
|
290
|
+
Requests::WorkspaceSymbol.new(query, @index).perform
|
281
291
|
end
|
282
292
|
|
283
293
|
sig { params(uri: URI::Generic, range: T.nilable(T::Hash[Symbol, T.untyped])).returns({ ast: String }) }
|
284
294
|
def show_syntax_tree(uri, range)
|
285
|
-
{ ast: Requests::ShowSyntaxTree.new(@store.get(uri), range).
|
286
|
-
end
|
287
|
-
|
288
|
-
sig do
|
289
|
-
params(
|
290
|
-
uri: URI::Generic,
|
291
|
-
position: T::Hash[Symbol, T.untyped],
|
292
|
-
).returns(T.nilable(T.any(T::Array[Interface::Location], Interface::Location)))
|
293
|
-
end
|
294
|
-
def definition(uri, position)
|
295
|
-
document = @store.get(uri)
|
296
|
-
target, parent, nesting = document.locate_node(
|
297
|
-
position,
|
298
|
-
node_types: [Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode],
|
299
|
-
)
|
300
|
-
|
301
|
-
target = parent if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode)
|
302
|
-
|
303
|
-
dispatcher = Prism::Dispatcher.new
|
304
|
-
base_listener = Requests::Definition.new(uri, nesting, @index, dispatcher)
|
305
|
-
dispatcher.dispatch_once(target)
|
306
|
-
base_listener.response
|
307
|
-
end
|
308
|
-
|
309
|
-
sig do
|
310
|
-
params(
|
311
|
-
uri: URI::Generic,
|
312
|
-
position: T::Hash[Symbol, T.untyped],
|
313
|
-
).returns(T.nilable(Interface::Hover))
|
314
|
-
end
|
315
|
-
def hover(uri, position)
|
316
|
-
document = @store.get(uri)
|
317
|
-
target, parent, nesting = document.locate_node(
|
318
|
-
position,
|
319
|
-
node_types: Requests::Hover::ALLOWED_TARGETS,
|
320
|
-
)
|
321
|
-
|
322
|
-
if (Requests::Hover::ALLOWED_TARGETS.include?(parent.class) &&
|
323
|
-
!Requests::Hover::ALLOWED_TARGETS.include?(target.class)) ||
|
324
|
-
(parent.is_a?(Prism::ConstantPathNode) && target.is_a?(Prism::ConstantReadNode))
|
325
|
-
target = parent
|
326
|
-
end
|
327
|
-
|
328
|
-
# Instantiate all listeners
|
329
|
-
dispatcher = Prism::Dispatcher.new
|
330
|
-
hover = Requests::Hover.new(@index, nesting, dispatcher)
|
331
|
-
|
332
|
-
# Emit events for all listeners
|
333
|
-
dispatcher.dispatch_once(target)
|
334
|
-
|
335
|
-
hover.response
|
295
|
+
{ ast: Requests::ShowSyntaxTree.new(@store.get(uri), range).perform }
|
336
296
|
end
|
337
297
|
|
338
298
|
sig do
|
@@ -363,7 +323,7 @@ module RubyLsp
|
|
363
323
|
end
|
364
324
|
def selection_range(uri, positions)
|
365
325
|
ranges = @store.cache_fetch(uri, "textDocument/selectionRange") do |document|
|
366
|
-
Requests::SelectionRanges.new(document).
|
326
|
+
Requests::SelectionRanges.new(document).perform
|
367
327
|
end
|
368
328
|
|
369
329
|
# Per the selection range request spec (https://microsoft.github.io/language-server-protocol/specification#textDocument_selectionRange),
|
@@ -390,7 +350,7 @@ module RubyLsp
|
|
390
350
|
path = uri.to_standardized_path
|
391
351
|
return unless path.nil? || path.start_with?(T.must(@store.workspace_uri.to_standardized_path))
|
392
352
|
|
393
|
-
Requests::Formatting.new(@store.get(uri), formatter: @store.formatter).
|
353
|
+
Requests::Formatting.new(@store.get(uri), formatter: @store.formatter).perform
|
394
354
|
end
|
395
355
|
|
396
356
|
sig do
|
@@ -401,42 +361,7 @@ module RubyLsp
|
|
401
361
|
).returns(T::Array[Interface::TextEdit])
|
402
362
|
end
|
403
363
|
def on_type_formatting(uri, position, character)
|
404
|
-
Requests::OnTypeFormatting.new(@store.get(uri), position, character).
|
405
|
-
end
|
406
|
-
|
407
|
-
sig do
|
408
|
-
params(
|
409
|
-
uri: URI::Generic,
|
410
|
-
position: T::Hash[Symbol, T.untyped],
|
411
|
-
).returns(T.nilable(T::Array[Interface::DocumentHighlight]))
|
412
|
-
end
|
413
|
-
def document_highlight(uri, position)
|
414
|
-
document = @store.get(uri)
|
415
|
-
|
416
|
-
target, parent = document.locate_node(position)
|
417
|
-
dispatcher = Prism::Dispatcher.new
|
418
|
-
listener = Requests::DocumentHighlight.new(target, parent, dispatcher)
|
419
|
-
dispatcher.visit(document.tree)
|
420
|
-
listener.response
|
421
|
-
end
|
422
|
-
|
423
|
-
sig do
|
424
|
-
params(
|
425
|
-
uri: URI::Generic,
|
426
|
-
range: T::Hash[Symbol, T.untyped],
|
427
|
-
).returns(T.nilable(T::Array[Interface::InlayHint]))
|
428
|
-
end
|
429
|
-
def inlay_hint(uri, range)
|
430
|
-
document = @store.get(uri)
|
431
|
-
|
432
|
-
start_line = range.dig(:start, :line)
|
433
|
-
end_line = range.dig(:end, :line)
|
434
|
-
|
435
|
-
dispatcher = Prism::Dispatcher.new
|
436
|
-
hints_configurations = T.must(@store.features_configuration.dig(:inlayHint))
|
437
|
-
listener = Requests::InlayHints.new(start_line..end_line, hints_configurations, dispatcher)
|
438
|
-
dispatcher.visit(document.tree)
|
439
|
-
listener.response
|
364
|
+
Requests::OnTypeFormatting.new(@store.get(uri), position, character).perform
|
440
365
|
end
|
441
366
|
|
442
367
|
sig do
|
@@ -449,14 +374,14 @@ module RubyLsp
|
|
449
374
|
def code_action(uri, range, context)
|
450
375
|
document = @store.get(uri)
|
451
376
|
|
452
|
-
Requests::CodeActions.new(document, range, context).
|
377
|
+
Requests::CodeActions.new(document, range, context).perform
|
453
378
|
end
|
454
379
|
|
455
380
|
sig { params(params: T::Hash[Symbol, T.untyped]).returns(Interface::CodeAction) }
|
456
381
|
def code_action_resolve(params)
|
457
382
|
uri = URI(params.dig(:data, :uri))
|
458
383
|
document = @store.get(uri)
|
459
|
-
result = Requests::CodeActionResolve.new(document, params).
|
384
|
+
result = Requests::CodeActionResolve.new(document, params).perform
|
460
385
|
|
461
386
|
case result
|
462
387
|
when Requests::CodeActionResolve::Error::EmptySelection
|
@@ -490,7 +415,7 @@ module RubyLsp
|
|
490
415
|
return unless path.nil? || path.start_with?(T.must(@store.workspace_uri.to_standardized_path))
|
491
416
|
|
492
417
|
response = @store.cache_fetch(uri, "textDocument/diagnostic") do |document|
|
493
|
-
Requests::Diagnostics.new(document).
|
418
|
+
Requests::Diagnostics.new(document).perform
|
494
419
|
end
|
495
420
|
|
496
421
|
Interface::FullDocumentDiagnosticReport.new(kind: "full", items: response) if response
|
@@ -503,61 +428,10 @@ module RubyLsp
|
|
503
428
|
end_line = range.dig(:end, :line)
|
504
429
|
|
505
430
|
dispatcher = Prism::Dispatcher.new
|
506
|
-
|
431
|
+
request = Requests::SemanticHighlighting.new(dispatcher, range: start_line..end_line)
|
507
432
|
dispatcher.visit(document.tree)
|
508
433
|
|
509
|
-
Requests::Support::SemanticTokenEncoder.new.encode(
|
510
|
-
end
|
511
|
-
|
512
|
-
sig do
|
513
|
-
params(
|
514
|
-
uri: URI::Generic,
|
515
|
-
position: T::Hash[Symbol, T.untyped],
|
516
|
-
).returns(T.nilable(T::Array[Interface::CompletionItem]))
|
517
|
-
end
|
518
|
-
def completion(uri, position)
|
519
|
-
document = @store.get(uri)
|
520
|
-
|
521
|
-
# Completion always receives the position immediately after the character that was just typed. Here we adjust it
|
522
|
-
# back by 1, so that we find the right node
|
523
|
-
char_position = document.create_scanner.find_char_position(position) - 1
|
524
|
-
matched, parent, nesting = document.locate(
|
525
|
-
document.tree,
|
526
|
-
char_position,
|
527
|
-
node_types: [Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode],
|
528
|
-
)
|
529
|
-
return unless matched && parent
|
530
|
-
|
531
|
-
target = case matched
|
532
|
-
when Prism::CallNode
|
533
|
-
message = matched.message
|
534
|
-
|
535
|
-
if message == "require"
|
536
|
-
args = matched.arguments&.arguments
|
537
|
-
return if args.nil? || args.is_a?(Prism::ForwardingArgumentsNode)
|
538
|
-
|
539
|
-
argument = args.first
|
540
|
-
return unless argument.is_a?(Prism::StringNode)
|
541
|
-
return unless (argument.location.start_offset..argument.location.end_offset).cover?(char_position)
|
542
|
-
|
543
|
-
argument
|
544
|
-
else
|
545
|
-
matched
|
546
|
-
end
|
547
|
-
when Prism::ConstantReadNode, Prism::ConstantPathNode
|
548
|
-
if parent.is_a?(Prism::ConstantPathNode) && matched.is_a?(Prism::ConstantReadNode)
|
549
|
-
parent
|
550
|
-
else
|
551
|
-
matched
|
552
|
-
end
|
553
|
-
end
|
554
|
-
|
555
|
-
return unless target
|
556
|
-
|
557
|
-
dispatcher = Prism::Dispatcher.new
|
558
|
-
listener = Requests::Completion.new(@index, nesting, dispatcher)
|
559
|
-
dispatcher.dispatch_once(target)
|
560
|
-
listener.response
|
434
|
+
Requests::Support::SemanticTokenEncoder.new.encode(request.perform)
|
561
435
|
end
|
562
436
|
|
563
437
|
sig { params(id: String, title: String, percentage: Integer).void }
|
@@ -663,81 +537,18 @@ module RubyLsp
|
|
663
537
|
Hash.new(true)
|
664
538
|
end
|
665
539
|
|
666
|
-
document_symbol_provider = if enabled_features["documentSymbols"]
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
code_lens_provider = if enabled_features["codeLens"]
|
680
|
-
Interface::CodeLensOptions.new(resolve_provider: false)
|
681
|
-
end
|
682
|
-
|
683
|
-
hover_provider = if enabled_features["hover"]
|
684
|
-
Interface::HoverClientCapabilities.new(dynamic_registration: false)
|
685
|
-
end
|
686
|
-
|
687
|
-
folding_ranges_provider = if enabled_features["foldingRanges"]
|
688
|
-
Interface::FoldingRangeClientCapabilities.new(line_folding_only: true)
|
689
|
-
end
|
690
|
-
|
691
|
-
semantic_tokens_provider = if enabled_features["semanticHighlighting"]
|
692
|
-
Interface::SemanticTokensRegistrationOptions.new(
|
693
|
-
document_selector: { scheme: "file", language: "ruby" },
|
694
|
-
legend: Interface::SemanticTokensLegend.new(
|
695
|
-
token_types: Requests::SemanticHighlighting::TOKEN_TYPES.keys,
|
696
|
-
token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS.keys,
|
697
|
-
),
|
698
|
-
range: true,
|
699
|
-
full: { delta: false },
|
700
|
-
)
|
701
|
-
end
|
702
|
-
|
703
|
-
diagnostics_provider = if enabled_features["diagnostics"]
|
704
|
-
{
|
705
|
-
interFileDependencies: false,
|
706
|
-
workspaceDiagnostics: false,
|
707
|
-
}
|
708
|
-
end
|
709
|
-
|
710
|
-
on_type_formatting_provider = if enabled_features["onTypeFormatting"]
|
711
|
-
Interface::DocumentOnTypeFormattingOptions.new(
|
712
|
-
first_trigger_character: "{",
|
713
|
-
more_trigger_character: ["\n", "|", "d"],
|
714
|
-
)
|
715
|
-
end
|
716
|
-
|
717
|
-
code_action_provider = if enabled_features["codeActions"]
|
718
|
-
Interface::CodeActionOptions.new(resolve_provider: true)
|
719
|
-
end
|
720
|
-
|
721
|
-
inlay_hint_provider = if enabled_features["inlayHint"]
|
722
|
-
Interface::InlayHintOptions.new(resolve_provider: false)
|
723
|
-
end
|
724
|
-
|
725
|
-
completion_provider = if enabled_features["completion"]
|
726
|
-
Interface::CompletionOptions.new(
|
727
|
-
resolve_provider: false,
|
728
|
-
trigger_characters: ["/"],
|
729
|
-
completion_item: {
|
730
|
-
labelDetailsSupport: true,
|
731
|
-
},
|
732
|
-
)
|
733
|
-
end
|
734
|
-
|
735
|
-
signature_help_provider = if enabled_features["signatureHelp"]
|
736
|
-
# Identifier characters are automatically included, such as A-Z, a-z, 0-9, _, * or :
|
737
|
-
Interface::SignatureHelpOptions.new(
|
738
|
-
trigger_characters: ["(", " ", ","],
|
739
|
-
)
|
740
|
-
end
|
540
|
+
document_symbol_provider = Requests::DocumentSymbol.provider if enabled_features["documentSymbols"]
|
541
|
+
document_link_provider = Requests::DocumentLink.provider if enabled_features["documentLink"]
|
542
|
+
code_lens_provider = Requests::CodeLens.provider if enabled_features["codeLens"]
|
543
|
+
hover_provider = Requests::Hover.provider if enabled_features["hover"]
|
544
|
+
folding_ranges_provider = Requests::FoldingRanges.provider if enabled_features["foldingRanges"]
|
545
|
+
semantic_tokens_provider = Requests::SemanticHighlighting.provider if enabled_features["semanticHighlighting"]
|
546
|
+
diagnostics_provider = Requests::Diagnostics.provider if enabled_features["diagnostics"]
|
547
|
+
on_type_formatting_provider = Requests::OnTypeFormatting.provider if enabled_features["onTypeFormatting"]
|
548
|
+
code_action_provider = Requests::CodeActions.provider if enabled_features["codeActions"]
|
549
|
+
inlay_hint_provider = Requests::InlayHints.provider if enabled_features["inlayHint"]
|
550
|
+
completion_provider = Requests::Completion.provider if enabled_features["completion"]
|
551
|
+
signature_help_provider = Requests::SignatureHelp.provider if enabled_features["signatureHelp"]
|
741
552
|
|
742
553
|
# Dynamically registered capabilities
|
743
554
|
file_watching_caps = options.dig(:capabilities, :workspace, :didChangeWatchedFiles)
|
data/lib/ruby_lsp/listener.rb
CHANGED
@@ -16,6 +16,7 @@ module RubyLsp
|
|
16
16
|
|
17
17
|
sig { params(dispatcher: Prism::Dispatcher).void }
|
18
18
|
def initialize(dispatcher)
|
19
|
+
super()
|
19
20
|
@dispatcher = dispatcher
|
20
21
|
end
|
21
22
|
|
@@ -29,54 +30,4 @@ module RubyLsp
|
|
29
30
|
sig { abstract.returns(ResponseType) }
|
30
31
|
def _response; end
|
31
32
|
end
|
32
|
-
|
33
|
-
# ExtensibleListener is an abstract class to be used by requests that accept addons.
|
34
|
-
class ExtensibleListener < Listener
|
35
|
-
extend T::Sig
|
36
|
-
extend T::Generic
|
37
|
-
|
38
|
-
ResponseType = type_member
|
39
|
-
|
40
|
-
abstract!
|
41
|
-
|
42
|
-
# When inheriting from ExtensibleListener, the `super` of constructor must be called **after** the subclass's own
|
43
|
-
# ivars have been initialized. This is because the constructor of ExtensibleListener calls
|
44
|
-
# `initialize_external_listener` which may depend on the subclass's ivars.
|
45
|
-
sig { params(dispatcher: Prism::Dispatcher).void }
|
46
|
-
def initialize(dispatcher)
|
47
|
-
super
|
48
|
-
@response_merged = T.let(false, T::Boolean)
|
49
|
-
@external_listeners = T.let(
|
50
|
-
Addon.addons.filter_map do |ext|
|
51
|
-
initialize_external_listener(ext)
|
52
|
-
end,
|
53
|
-
T::Array[RubyLsp::Listener[ResponseType]],
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Merge responses from all external listeners into the base listener's response. We do this to return a single
|
58
|
-
# response to the editor including the results of all addons
|
59
|
-
sig { void }
|
60
|
-
def merge_external_listeners_responses!
|
61
|
-
@external_listeners.each { |l| merge_response!(l) }
|
62
|
-
end
|
63
|
-
|
64
|
-
sig { returns(ResponseType) }
|
65
|
-
def response
|
66
|
-
merge_external_listeners_responses! unless @response_merged
|
67
|
-
super
|
68
|
-
end
|
69
|
-
|
70
|
-
sig do
|
71
|
-
abstract.params(addon: RubyLsp::Addon).returns(T.nilable(RubyLsp::Listener[ResponseType]))
|
72
|
-
end
|
73
|
-
def initialize_external_listener(addon); end
|
74
|
-
|
75
|
-
# Does nothing by default. Requests that accept addons should override this method to define how to merge responses
|
76
|
-
# coming from external listeners
|
77
|
-
sig { abstract.params(other: Listener[T.untyped]).returns(T.self_type) }
|
78
|
-
def merge_response!(other)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
private_constant(:ExtensibleListener)
|
82
33
|
end
|