ruby-lsp 0.13.2 → 0.13.3

Sign up to get free protection for your applications and to get access to all the features.
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 +15 -4
  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: 28e657dce7a85c270d1c647a158fd1a1c5f81dca211844defd817070fd264126
4
+ data.tar.gz: f129245dd0e632916573c0b9dcf04bfaa2c7b942b39aaa6aa1618dd70f13e69e
5
5
  SHA512:
6
- metadata.gz: 9c3ab34cb3e7877105ca21df3f521589d9838bd15e77a3d17cc4df91ca1f93221ef845e514a902a03a63a1f82ad6b5cf90fa4f9a93037fbfb57af5f7a48b0ebe
7
- data.tar.gz: d4867c86eb238abf039f40592d7ff48acd85749fcf9349ab72fdea218ff5201156fc0d511987ed768b1fb2dcc9fd55a76bfac611f3fc565b7b2ba8c8d1054a72
6
+ metadata.gz: 3ab4afce37f672fd0d3c3ecc54c7b30247f893fc4b7b4f10549e13db4ab181c67a9b84da37dea9fbdd195e8d87ca2f2f794cbcce300c68b4709ee0ae3b3171b2
7
+ data.tar.gz: ffdb3a1bdb2d5c4172f74c934da896bd6c19f09158effa137afd0443e79b8c2dfd392989997d5745616db58e1286191a9e35570bd69024779137e7aaf15bb987
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.3
@@ -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