ruby-lsp 0.13.2 → 0.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -0
  3. data/VERSION +1 -1
  4. data/lib/ruby_lsp/check_docs.rb +3 -3
  5. data/lib/ruby_lsp/document.rb +12 -0
  6. data/lib/ruby_lsp/executor.rb +77 -266
  7. data/lib/ruby_lsp/listener.rb +1 -50
  8. data/lib/ruby_lsp/listeners/code_lens.rb +233 -0
  9. data/lib/ruby_lsp/listeners/completion.rb +275 -0
  10. data/lib/ruby_lsp/listeners/definition.rb +158 -0
  11. data/lib/ruby_lsp/listeners/document_highlight.rb +556 -0
  12. data/lib/ruby_lsp/listeners/document_link.rb +162 -0
  13. data/lib/ruby_lsp/listeners/document_symbol.rb +223 -0
  14. data/lib/ruby_lsp/listeners/folding_ranges.rb +271 -0
  15. data/lib/ruby_lsp/listeners/hover.rb +152 -0
  16. data/lib/ruby_lsp/listeners/inlay_hints.rb +80 -0
  17. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +430 -0
  18. data/lib/ruby_lsp/listeners/signature_help.rb +74 -0
  19. data/lib/ruby_lsp/requests/code_action_resolve.rb +4 -4
  20. data/lib/ruby_lsp/requests/code_actions.rb +13 -4
  21. data/lib/ruby_lsp/requests/code_lens.rb +21 -221
  22. data/lib/ruby_lsp/requests/completion.rb +64 -244
  23. data/lib/ruby_lsp/requests/definition.rb +34 -147
  24. data/lib/ruby_lsp/requests/diagnostics.rb +17 -5
  25. data/lib/ruby_lsp/requests/document_highlight.rb +12 -536
  26. data/lib/ruby_lsp/requests/document_link.rb +11 -132
  27. data/lib/ruby_lsp/requests/document_symbol.rb +23 -210
  28. data/lib/ruby_lsp/requests/folding_ranges.rb +16 -252
  29. data/lib/ruby_lsp/requests/formatting.rb +4 -4
  30. data/lib/ruby_lsp/requests/hover.rb +48 -92
  31. data/lib/ruby_lsp/requests/inlay_hints.rb +23 -56
  32. data/lib/ruby_lsp/requests/on_type_formatting.rb +16 -4
  33. data/lib/ruby_lsp/requests/request.rb +17 -0
  34. data/lib/ruby_lsp/requests/selection_ranges.rb +4 -3
  35. data/lib/ruby_lsp/requests/semantic_highlighting.rb +21 -408
  36. data/lib/ruby_lsp/requests/show_syntax_tree.rb +4 -4
  37. data/lib/ruby_lsp/requests/signature_help.rb +43 -51
  38. data/lib/ruby_lsp/requests/support/common.rb +3 -2
  39. data/lib/ruby_lsp/requests/support/dependency_detector.rb +2 -0
  40. data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +2 -2
  41. data/lib/ruby_lsp/requests/workspace_symbol.rb +5 -4
  42. data/lib/ruby_lsp/requests.rb +1 -1
  43. data/lib/ruby_lsp/utils.rb +8 -0
  44. metadata +17 -6
  45. 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: 2329129b74c75a0bb4113d1f1489463f666b74ef495d0ac65bad675fbd83d1d3
4
- data.tar.gz: 2f31f495b9ca0b1a9f909758dabce816411d0b64a006577c93c7a80a253791e5
3
+ metadata.gz: 675bc1c9ddbcb8c05d591e184e2cf77914a6fcfa4af5db6178864063a910e0bd
4
+ data.tar.gz: 3f14554ce578fe5457ad90f2500b5267fded390e17b58142a2a174928630c53c
5
5
  SHA512:
6
- metadata.gz: 9c3ab34cb3e7877105ca21df3f521589d9838bd15e77a3d17cc4df91ca1f93221ef845e514a902a03a63a1f82ad6b5cf90fa4f9a93037fbfb57af5f7a48b0ebe
7
- data.tar.gz: d4867c86eb238abf039f40592d7ff48acd85749fcf9349ab72fdea218ff5201156fc0d511987ed768b1fb2dcc9fd55a76bfac611f3fc565b7b2ba8c8d1054a72
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.2
1
+ 0.13.4
@@ -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).filter_map do |k|
54
+ features = ObjectSpace.each_object(Class).select do |k|
55
55
  klass = T.unsafe(k)
56
- klass if klass < Requests::BaseRequest || (klass < Listener && klass != ExtensibleListener)
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.must(klass.name)
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
 
@@ -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
 
@@ -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 listeners for the document
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.response)
111
- document.cache_set("textDocument/documentSymbol", document_symbol.response)
112
- document.cache_set("textDocument/documentLink", document_link.response)
113
- document.cache_set("textDocument/codeLens", code_lens.response)
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.response),
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
- document_highlight(uri, request.dig(:params, :position))
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
- hover(uri, request.dig(:params, :position))
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
- inlay_hint(uri, request.dig(:params, :range))
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
- completion(uri, request.dig(:params, :position))
173
- when "textDocument/definition"
174
- definition(uri, request.dig(:params, :position))
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
- signature_help(uri, request.dig(:params, :position), request.dig(:params, :context))
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).run
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).run }
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).run
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).run
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).run
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).run
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).run
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).run
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
- listener = Requests::SemanticHighlighting.new(dispatcher, range: start_line..end_line)
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(listener.response)
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
- Interface::DocumentSymbolClientCapabilities.new(
668
- hierarchical_document_symbol_support: true,
669
- symbol_kind: {
670
- value_set: (Constant::SymbolKind::FILE..Constant::SymbolKind::TYPE_PARAMETER).to_a,
671
- },
672
- )
673
- end
674
-
675
- document_link_provider = if enabled_features["documentLink"]
676
- Interface::DocumentLinkOptions.new(resolve_provider: false)
677
- end
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)
@@ -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