ruby-lsp 0.12.5 → 0.13.1
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp-check +20 -4
- data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +36 -2
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +1 -1
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +132 -13
- data/lib/ruby_indexer/test/configuration_test.rb +10 -0
- data/lib/ruby_indexer/test/index_test.rb +11 -0
- data/lib/ruby_indexer/test/method_test.rb +202 -0
- data/lib/ruby_lsp/addon.rb +9 -13
- data/lib/ruby_lsp/document.rb +3 -0
- data/lib/ruby_lsp/executor.rb +33 -28
- data/lib/ruby_lsp/listener.rb +4 -5
- data/lib/ruby_lsp/requests/code_actions.rb +2 -16
- data/lib/ruby_lsp/requests/code_lens.rb +29 -7
- data/lib/ruby_lsp/requests/completion.rb +11 -8
- data/lib/ruby_lsp/requests/definition.rb +3 -4
- data/lib/ruby_lsp/requests/diagnostics.rb +0 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +2 -3
- data/lib/ruby_lsp/requests/document_link.rb +2 -3
- data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
- data/lib/ruby_lsp/requests/folding_ranges.rb +12 -15
- data/lib/ruby_lsp/requests/formatting.rb +0 -5
- data/lib/ruby_lsp/requests/hover.rb +3 -4
- data/lib/ruby_lsp/requests/inlay_hints.rb +20 -3
- data/lib/ruby_lsp/requests/on_type_formatting.rb +31 -4
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +28 -11
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +92 -21
- data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +1 -1
- data/lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb +3 -8
- data/lib/ruby_lsp/requests/workspace_symbol.rb +2 -0
- data/lib/ruby_lsp/store.rb +21 -0
- data/lib/ruby_lsp/utils.rb +18 -4
- metadata +7 -7
data/lib/ruby_lsp/executor.rb
CHANGED
@@ -41,7 +41,7 @@ module RubyLsp
|
|
41
41
|
when "initialize"
|
42
42
|
initialize_request(request.dig(:params))
|
43
43
|
when "initialized"
|
44
|
-
Addon.load_addons
|
44
|
+
Addon.load_addons(@message_queue)
|
45
45
|
|
46
46
|
errored_addons = Addon.addons.select(&:error?)
|
47
47
|
|
@@ -95,12 +95,13 @@ module RubyLsp
|
|
95
95
|
|
96
96
|
# Run listeners for the document
|
97
97
|
dispatcher = Prism::Dispatcher.new
|
98
|
-
folding_range = Requests::FoldingRanges.new(document.parse_result.comments, dispatcher
|
99
|
-
document_symbol = Requests::DocumentSymbol.new(dispatcher
|
100
|
-
document_link = Requests::DocumentLink.new(uri, document.comments, dispatcher
|
101
|
-
|
98
|
+
folding_range = Requests::FoldingRanges.new(document.parse_result.comments, dispatcher)
|
99
|
+
document_symbol = Requests::DocumentSymbol.new(dispatcher)
|
100
|
+
document_link = Requests::DocumentLink.new(uri, document.comments, dispatcher)
|
101
|
+
lenses_configuration = T.must(@store.features_configuration.dig(:codeLens))
|
102
|
+
code_lens = Requests::CodeLens.new(uri, lenses_configuration, dispatcher)
|
102
103
|
|
103
|
-
semantic_highlighting = Requests::SemanticHighlighting.new(dispatcher
|
104
|
+
semantic_highlighting = Requests::SemanticHighlighting.new(dispatcher)
|
104
105
|
dispatcher.dispatch(document.tree)
|
105
106
|
|
106
107
|
# Store all responses retrieve in this round of visits in the cache and then return the response for the request
|
@@ -265,13 +266,7 @@ module RubyLsp
|
|
265
266
|
target = parent if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode)
|
266
267
|
|
267
268
|
dispatcher = Prism::Dispatcher.new
|
268
|
-
base_listener = Requests::Definition.new(
|
269
|
-
uri,
|
270
|
-
nesting,
|
271
|
-
@index,
|
272
|
-
dispatcher,
|
273
|
-
@message_queue,
|
274
|
-
)
|
269
|
+
base_listener = Requests::Definition.new(uri, nesting, @index, dispatcher)
|
275
270
|
dispatcher.dispatch_once(target)
|
276
271
|
base_listener.response
|
277
272
|
end
|
@@ -297,7 +292,7 @@ module RubyLsp
|
|
297
292
|
|
298
293
|
# Instantiate all listeners
|
299
294
|
dispatcher = Prism::Dispatcher.new
|
300
|
-
hover = Requests::Hover.new(@index, nesting, dispatcher
|
295
|
+
hover = Requests::Hover.new(@index, nesting, dispatcher)
|
301
296
|
|
302
297
|
# Emit events for all listeners
|
303
298
|
dispatcher.dispatch_once(target)
|
@@ -355,6 +350,11 @@ module RubyLsp
|
|
355
350
|
# If formatter is set to `auto` but no supported formatting gem is found, don't attempt to format
|
356
351
|
return if @store.formatter == "none"
|
357
352
|
|
353
|
+
# Do not format files outside of the workspace. For example, if someone is looking at a gem's source code, we
|
354
|
+
# don't want to format it
|
355
|
+
path = uri.to_standardized_path
|
356
|
+
return unless path.nil? || path.start_with?(T.must(@store.workspace_uri.to_standardized_path))
|
357
|
+
|
358
358
|
Requests::Formatting.new(@store.get(uri), formatter: @store.formatter).run
|
359
359
|
end
|
360
360
|
|
@@ -380,7 +380,7 @@ module RubyLsp
|
|
380
380
|
|
381
381
|
target, parent = document.locate_node(position)
|
382
382
|
dispatcher = Prism::Dispatcher.new
|
383
|
-
listener = Requests::DocumentHighlight.new(target, parent, dispatcher
|
383
|
+
listener = Requests::DocumentHighlight.new(target, parent, dispatcher)
|
384
384
|
dispatcher.visit(document.tree)
|
385
385
|
listener.response
|
386
386
|
end
|
@@ -393,7 +393,8 @@ module RubyLsp
|
|
393
393
|
end_line = range.dig(:end, :line)
|
394
394
|
|
395
395
|
dispatcher = Prism::Dispatcher.new
|
396
|
-
|
396
|
+
hints_configurations = T.must(@store.features_configuration.dig(:inlayHint))
|
397
|
+
listener = Requests::InlayHints.new(start_line..end_line, hints_configurations, dispatcher)
|
397
398
|
dispatcher.visit(document.tree)
|
398
399
|
listener.response
|
399
400
|
end
|
@@ -443,6 +444,11 @@ module RubyLsp
|
|
443
444
|
|
444
445
|
sig { params(uri: URI::Generic).returns(T.nilable(Interface::FullDocumentDiagnosticReport)) }
|
445
446
|
def diagnostic(uri)
|
447
|
+
# Do not compute diagnostics for files outside of the workspace. For example, if someone is looking at a gem's
|
448
|
+
# source code, we don't want to show diagnostics for it
|
449
|
+
path = uri.to_standardized_path
|
450
|
+
return unless path.nil? || path.start_with?(T.must(@store.workspace_uri.to_standardized_path))
|
451
|
+
|
446
452
|
response = @store.cache_fetch(uri, "textDocument/diagnostic") do |document|
|
447
453
|
Requests::Diagnostics.new(document).run
|
448
454
|
end
|
@@ -457,11 +463,7 @@ module RubyLsp
|
|
457
463
|
end_line = range.dig(:end, :line)
|
458
464
|
|
459
465
|
dispatcher = Prism::Dispatcher.new
|
460
|
-
listener = Requests::SemanticHighlighting.new(
|
461
|
-
dispatcher,
|
462
|
-
@message_queue,
|
463
|
-
range: start_line..end_line,
|
464
|
-
)
|
466
|
+
listener = Requests::SemanticHighlighting.new(dispatcher, range: start_line..end_line)
|
465
467
|
dispatcher.visit(document.tree)
|
466
468
|
|
467
469
|
Requests::Support::SemanticTokenEncoder.new.encode(listener.response)
|
@@ -513,12 +515,7 @@ module RubyLsp
|
|
513
515
|
return unless target
|
514
516
|
|
515
517
|
dispatcher = Prism::Dispatcher.new
|
516
|
-
listener = Requests::Completion.new(
|
517
|
-
@index,
|
518
|
-
nesting,
|
519
|
-
dispatcher,
|
520
|
-
@message_queue,
|
521
|
-
)
|
518
|
+
listener = Requests::Completion.new(@index, nesting, dispatcher)
|
522
519
|
dispatcher.dispatch_once(target)
|
523
520
|
listener.response
|
524
521
|
end
|
@@ -583,6 +580,9 @@ module RubyLsp
|
|
583
580
|
def initialize_request(options)
|
584
581
|
@store.clear
|
585
582
|
|
583
|
+
workspace_uri = options.dig(:workspaceFolders, 0, :uri)
|
584
|
+
@store.workspace_uri = URI(workspace_uri) if workspace_uri
|
585
|
+
|
586
586
|
encodings = options.dig(:capabilities, :general, :positionEncodings)
|
587
587
|
@store.encoding = if encodings.nil? || encodings.empty?
|
588
588
|
Constant::PositionEncodingKind::UTF16
|
@@ -604,6 +604,11 @@ module RubyLsp
|
|
604
604
|
configured_features = options.dig(:initializationOptions, :enabledFeatures)
|
605
605
|
@store.experimental_features = options.dig(:initializationOptions, :experimentalFeaturesEnabled) || false
|
606
606
|
|
607
|
+
configured_hints = options.dig(:initializationOptions, :featuresConfiguration, :inlayHint)
|
608
|
+
configured_lenses = options.dig(:initializationOptions, :featuresConfiguration, :codeLens)
|
609
|
+
T.must(@store.features_configuration.dig(:inlayHint)).configuration.merge!(configured_hints) if configured_hints
|
610
|
+
T.must(@store.features_configuration.dig(:codeLens)).configuration.merge!(configured_lenses) if configured_lenses
|
611
|
+
|
607
612
|
enabled_features = case configured_features
|
608
613
|
when Array
|
609
614
|
# If the configuration is using an array, then absent features are disabled and present ones are enabled. That's
|
@@ -665,7 +670,7 @@ module RubyLsp
|
|
665
670
|
on_type_formatting_provider = if enabled_features["onTypeFormatting"]
|
666
671
|
Interface::DocumentOnTypeFormattingOptions.new(
|
667
672
|
first_trigger_character: "{",
|
668
|
-
more_trigger_character: ["\n", "|"],
|
673
|
+
more_trigger_character: ["\n", "|", "d"],
|
669
674
|
)
|
670
675
|
end
|
671
676
|
|
data/lib/ruby_lsp/listener.rb
CHANGED
@@ -14,10 +14,9 @@ module RubyLsp
|
|
14
14
|
|
15
15
|
abstract!
|
16
16
|
|
17
|
-
sig { params(dispatcher: Prism::Dispatcher
|
18
|
-
def initialize(dispatcher
|
17
|
+
sig { params(dispatcher: Prism::Dispatcher).void }
|
18
|
+
def initialize(dispatcher)
|
19
19
|
@dispatcher = dispatcher
|
20
|
-
@message_queue = message_queue
|
21
20
|
end
|
22
21
|
|
23
22
|
sig { returns(ResponseType) }
|
@@ -43,8 +42,8 @@ module RubyLsp
|
|
43
42
|
# When inheriting from ExtensibleListener, the `super` of constructor must be called **after** the subclass's own
|
44
43
|
# ivars have been initialized. This is because the constructor of ExtensibleListener calls
|
45
44
|
# `initialize_external_listener` which may depend on the subclass's ivars.
|
46
|
-
sig { params(dispatcher: Prism::Dispatcher
|
47
|
-
def initialize(dispatcher
|
45
|
+
sig { params(dispatcher: Prism::Dispatcher).void }
|
46
|
+
def initialize(dispatcher)
|
48
47
|
super
|
49
48
|
@response_merged = T.let(false, T::Boolean)
|
50
49
|
@external_listeners = T.let(
|
@@ -38,14 +38,8 @@ module RubyLsp
|
|
38
38
|
def run
|
39
39
|
diagnostics = @context[:diagnostics]
|
40
40
|
|
41
|
-
code_actions = diagnostics.
|
42
|
-
|
43
|
-
next if code_action.nil?
|
44
|
-
|
45
|
-
# We want to return only code actions that are within range or that do not have any edits, such as refactor
|
46
|
-
# code actions
|
47
|
-
range = code_action.dig(:edit, :documentChanges, 0, :edits, 0, :range)
|
48
|
-
code_action if diagnostic.dig(:data, :correctable) && cover?(range)
|
41
|
+
code_actions = diagnostics.flat_map do |diagnostic|
|
42
|
+
diagnostic.dig(:data, :code_actions) || []
|
49
43
|
end
|
50
44
|
|
51
45
|
# Only add refactor actions if there's a non empty selection in the editor
|
@@ -55,14 +49,6 @@ module RubyLsp
|
|
55
49
|
|
56
50
|
private
|
57
51
|
|
58
|
-
sig { params(range: T.nilable(Document::RangeShape)).returns(T::Boolean) }
|
59
|
-
def cover?(range)
|
60
|
-
range.nil? ||
|
61
|
-
((@range.dig(:start, :line))..(@range.dig(:end, :line))).cover?(
|
62
|
-
(range.dig(:start, :line))..(range.dig(:end, :line)),
|
63
|
-
)
|
64
|
-
end
|
65
|
-
|
66
52
|
sig { params(range: Document::RangeShape, uri: URI::Generic).returns(Interface::CodeAction) }
|
67
53
|
def refactor_code_action(range, uri)
|
68
54
|
Interface::CodeAction.new(
|
@@ -11,6 +11,10 @@ module RubyLsp
|
|
11
11
|
# [code lens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens)
|
12
12
|
# request informs the editor of runnable commands such as tests
|
13
13
|
#
|
14
|
+
# # Configuration
|
15
|
+
#
|
16
|
+
# To disable gem code lenses, set `rubyLsp.featuresConfiguration.codeLens.gemfileLinks` to `false`.
|
17
|
+
#
|
14
18
|
# # Example
|
15
19
|
#
|
16
20
|
# ```ruby
|
@@ -47,16 +51,25 @@ module RubyLsp
|
|
47
51
|
sig { override.returns(ResponseType) }
|
48
52
|
attr_reader :_response
|
49
53
|
|
50
|
-
sig
|
51
|
-
|
54
|
+
sig do
|
55
|
+
params(
|
56
|
+
uri: URI::Generic,
|
57
|
+
lenses_configuration: RequestConfig,
|
58
|
+
dispatcher: Prism::Dispatcher,
|
59
|
+
).void
|
60
|
+
end
|
61
|
+
def initialize(uri, lenses_configuration, dispatcher)
|
52
62
|
@uri = T.let(uri, URI::Generic)
|
53
63
|
@_response = T.let([], ResponseType)
|
54
64
|
@path = T.let(uri.to_standardized_path, T.nilable(String))
|
55
65
|
# visibility_stack is a stack of [current_visibility, previous_visibility]
|
56
66
|
@visibility_stack = T.let([[:public, :public]], T::Array[T::Array[T.nilable(Symbol)]])
|
57
67
|
@class_stack = T.let([], T::Array[String])
|
68
|
+
@group_id = T.let(1, Integer)
|
69
|
+
@group_id_stack = T.let([], T::Array[Integer])
|
70
|
+
@lenses_configuration = lenses_configuration
|
58
71
|
|
59
|
-
super(dispatcher
|
72
|
+
super(dispatcher)
|
60
73
|
|
61
74
|
dispatcher.register(
|
62
75
|
self,
|
@@ -82,12 +95,16 @@ module RubyLsp
|
|
82
95
|
kind: :group,
|
83
96
|
)
|
84
97
|
end
|
98
|
+
|
99
|
+
@group_id_stack.push(@group_id)
|
100
|
+
@group_id += 1
|
85
101
|
end
|
86
102
|
|
87
103
|
sig { params(node: Prism::ClassNode).void }
|
88
104
|
def on_class_node_leave(node)
|
89
105
|
@visibility_stack.pop
|
90
106
|
@class_stack.pop
|
107
|
+
@group_id_stack.pop
|
91
108
|
end
|
92
109
|
|
93
110
|
sig { params(node: Prism::DefNode).void }
|
@@ -128,6 +145,8 @@ module RubyLsp
|
|
128
145
|
end
|
129
146
|
|
130
147
|
if @path&.include?(GEMFILE_NAME) && name == :gem && arguments
|
148
|
+
return unless @lenses_configuration.enabled?(:gemfileLinks)
|
149
|
+
|
131
150
|
first_argument = arguments.arguments.first
|
132
151
|
return unless first_argument.is_a?(Prism::StringNode)
|
133
152
|
|
@@ -146,7 +165,7 @@ module RubyLsp
|
|
146
165
|
|
147
166
|
sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
|
148
167
|
def initialize_external_listener(addon)
|
149
|
-
addon.create_code_lens_listener(@uri, @dispatcher
|
168
|
+
addon.create_code_lens_listener(@uri, @dispatcher)
|
150
169
|
end
|
151
170
|
|
152
171
|
sig { override.params(other: Listener[ResponseType]).returns(T.self_type) }
|
@@ -174,12 +193,15 @@ module RubyLsp
|
|
174
193
|
},
|
175
194
|
]
|
176
195
|
|
196
|
+
grouping_data = { group_id: @group_id_stack.last, kind: kind }
|
197
|
+
grouping_data[:id] = @group_id if kind == :group
|
198
|
+
|
177
199
|
@_response << create_code_lens(
|
178
200
|
node,
|
179
201
|
title: "Run",
|
180
202
|
command_name: "rubyLsp.runTest",
|
181
203
|
arguments: arguments,
|
182
|
-
data: { type: "test",
|
204
|
+
data: { type: "test", **grouping_data },
|
183
205
|
)
|
184
206
|
|
185
207
|
@_response << create_code_lens(
|
@@ -187,7 +209,7 @@ module RubyLsp
|
|
187
209
|
title: "Run In Terminal",
|
188
210
|
command_name: "rubyLsp.runTestInTerminal",
|
189
211
|
arguments: arguments,
|
190
|
-
data: { type: "test_in_terminal",
|
212
|
+
data: { type: "test_in_terminal", **grouping_data },
|
191
213
|
)
|
192
214
|
|
193
215
|
@_response << create_code_lens(
|
@@ -195,7 +217,7 @@ module RubyLsp
|
|
195
217
|
title: "Debug",
|
196
218
|
command_name: "rubyLsp.debugTest",
|
197
219
|
arguments: arguments,
|
198
|
-
data: { type: "debug",
|
220
|
+
data: { type: "debug", **grouping_data },
|
199
221
|
)
|
200
222
|
end
|
201
223
|
|
@@ -36,11 +36,10 @@ module RubyLsp
|
|
36
36
|
index: RubyIndexer::Index,
|
37
37
|
nesting: T::Array[String],
|
38
38
|
dispatcher: Prism::Dispatcher,
|
39
|
-
message_queue: Thread::Queue,
|
40
39
|
).void
|
41
40
|
end
|
42
|
-
def initialize(index, nesting, dispatcher
|
43
|
-
super(dispatcher
|
41
|
+
def initialize(index, nesting, dispatcher)
|
42
|
+
super(dispatcher)
|
44
43
|
@_response = T.let([], ResponseType)
|
45
44
|
@index = index
|
46
45
|
@nesting = nesting
|
@@ -137,18 +136,22 @@ module RubyLsp
|
|
137
136
|
|
138
137
|
receiver = T.must(receiver_entries.first)
|
139
138
|
|
140
|
-
|
141
|
-
|
142
|
-
entry = entries.find { |e| e.owner&.name == receiver.name }
|
139
|
+
@index.prefix_search(name).each do |entries|
|
140
|
+
entry = entries.find { |e| e.is_a?(RubyIndexer::Entry::Member) && e.owner&.name == receiver.name }
|
143
141
|
next unless entry
|
144
142
|
|
145
|
-
@_response << build_method_completion(entry, node)
|
143
|
+
@_response << build_method_completion(T.cast(entry, RubyIndexer::Entry::Member), node)
|
146
144
|
end
|
147
145
|
end
|
148
146
|
|
149
147
|
private
|
150
148
|
|
151
|
-
sig
|
149
|
+
sig do
|
150
|
+
params(
|
151
|
+
entry: RubyIndexer::Entry::Member,
|
152
|
+
node: Prism::CallNode,
|
153
|
+
).returns(Interface::CompletionItem)
|
154
|
+
end
|
152
155
|
def build_method_completion(entry, node)
|
153
156
|
name = entry.name
|
154
157
|
parameters = entry.parameters
|
@@ -37,16 +37,15 @@ module RubyLsp
|
|
37
37
|
nesting: T::Array[String],
|
38
38
|
index: RubyIndexer::Index,
|
39
39
|
dispatcher: Prism::Dispatcher,
|
40
|
-
message_queue: Thread::Queue,
|
41
40
|
).void
|
42
41
|
end
|
43
|
-
def initialize(uri, nesting, index, dispatcher
|
42
|
+
def initialize(uri, nesting, index, dispatcher)
|
44
43
|
@uri = uri
|
45
44
|
@nesting = nesting
|
46
45
|
@index = index
|
47
46
|
@_response = T.let(nil, ResponseType)
|
48
47
|
|
49
|
-
super(dispatcher
|
48
|
+
super(dispatcher)
|
50
49
|
|
51
50
|
dispatcher.register(
|
52
51
|
self,
|
@@ -58,7 +57,7 @@ module RubyLsp
|
|
58
57
|
|
59
58
|
sig { override.params(addon: Addon).returns(T.nilable(RubyLsp::Listener[ResponseType])) }
|
60
59
|
def initialize_external_listener(addon)
|
61
|
-
addon.create_definition_listener(@uri, @nesting, @index, @dispatcher
|
60
|
+
addon.create_definition_listener(@uri, @nesting, @index, @dispatcher)
|
62
61
|
end
|
63
62
|
|
64
63
|
sig { override.params(other: Listener[ResponseType]).returns(T.self_type) }
|
@@ -32,13 +32,8 @@ module RubyLsp
|
|
32
32
|
def run
|
33
33
|
# Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid
|
34
34
|
return syntax_error_diagnostics if @document.syntax_error?
|
35
|
-
|
36
35
|
return unless defined?(Support::RuboCopDiagnosticsRunner)
|
37
36
|
|
38
|
-
# Don't try to run RuboCop diagnostics for files outside the current working directory
|
39
|
-
path = @uri.to_standardized_path
|
40
|
-
return unless path.nil? || path.start_with?(T.must(WORKSPACE_URI.to_standardized_path))
|
41
|
-
|
42
37
|
Support::RuboCopDiagnosticsRunner.instance.run(@uri, @document).map!(&:to_lsp_diagnostic)
|
43
38
|
end
|
44
39
|
|
@@ -114,11 +114,10 @@ module RubyLsp
|
|
114
114
|
target: T.nilable(Prism::Node),
|
115
115
|
parent: T.nilable(Prism::Node),
|
116
116
|
dispatcher: Prism::Dispatcher,
|
117
|
-
message_queue: Thread::Queue,
|
118
117
|
).void
|
119
118
|
end
|
120
|
-
def initialize(target, parent, dispatcher
|
121
|
-
super(dispatcher
|
119
|
+
def initialize(target, parent, dispatcher)
|
120
|
+
super(dispatcher)
|
122
121
|
|
123
122
|
@_response = T.let([], T::Array[Interface::DocumentHighlight])
|
124
123
|
|
@@ -80,11 +80,10 @@ module RubyLsp
|
|
80
80
|
uri: URI::Generic,
|
81
81
|
comments: T::Array[Prism::Comment],
|
82
82
|
dispatcher: Prism::Dispatcher,
|
83
|
-
message_queue: Thread::Queue,
|
84
83
|
).void
|
85
84
|
end
|
86
|
-
def initialize(uri, comments, dispatcher
|
87
|
-
super(dispatcher
|
85
|
+
def initialize(uri, comments, dispatcher)
|
86
|
+
super(dispatcher)
|
88
87
|
|
89
88
|
# Match the version based on the version in the RBI file name. Notice that the `@` symbol is sanitized to `%40`
|
90
89
|
# in the URI
|
@@ -49,8 +49,8 @@ module RubyLsp
|
|
49
49
|
sig { override.returns(T::Array[Interface::DocumentSymbol]) }
|
50
50
|
attr_reader :_response
|
51
51
|
|
52
|
-
sig { params(dispatcher: Prism::Dispatcher
|
53
|
-
def initialize(dispatcher
|
52
|
+
sig { params(dispatcher: Prism::Dispatcher).void }
|
53
|
+
def initialize(dispatcher)
|
54
54
|
@root = T.let(SymbolHierarchyRoot.new, SymbolHierarchyRoot)
|
55
55
|
@_response = T.let(@root.children, T::Array[Interface::DocumentSymbol])
|
56
56
|
@stack = T.let(
|
@@ -80,7 +80,7 @@ module RubyLsp
|
|
80
80
|
|
81
81
|
sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
|
82
82
|
def initialize_external_listener(addon)
|
83
|
-
addon.create_document_symbol_listener(@dispatcher
|
83
|
+
addon.create_document_symbol_listener(@dispatcher)
|
84
84
|
end
|
85
85
|
|
86
86
|
# Merges responses from other listeners
|
@@ -21,9 +21,9 @@ module RubyLsp
|
|
21
21
|
|
22
22
|
ResponseType = type_member { { fixed: T::Array[Interface::FoldingRange] } }
|
23
23
|
|
24
|
-
sig { params(comments: T::Array[Prism::Comment], dispatcher: Prism::Dispatcher
|
25
|
-
def initialize(comments, dispatcher
|
26
|
-
super(dispatcher
|
24
|
+
sig { params(comments: T::Array[Prism::Comment], dispatcher: Prism::Dispatcher).void }
|
25
|
+
def initialize(comments, dispatcher)
|
26
|
+
super(dispatcher)
|
27
27
|
|
28
28
|
@_response = T.let([], ResponseType)
|
29
29
|
@requires = T.let([], T::Array[Prism::CallNode])
|
@@ -40,6 +40,7 @@ module RubyLsp
|
|
40
40
|
:on_array_node_enter,
|
41
41
|
:on_block_node_enter,
|
42
42
|
:on_case_node_enter,
|
43
|
+
:on_case_match_node_enter,
|
43
44
|
:on_class_node_enter,
|
44
45
|
:on_module_node_enter,
|
45
46
|
:on_for_node_enter,
|
@@ -51,7 +52,6 @@ module RubyLsp
|
|
51
52
|
:on_else_node_enter,
|
52
53
|
:on_ensure_node_enter,
|
53
54
|
:on_begin_node_enter,
|
54
|
-
:on_string_concat_node_enter,
|
55
55
|
:on_def_node_enter,
|
56
56
|
:on_call_node_enter,
|
57
57
|
:on_lambda_node_enter,
|
@@ -91,10 +91,10 @@ module RubyLsp
|
|
91
91
|
|
92
92
|
sig { params(node: Prism::InterpolatedStringNode).void }
|
93
93
|
def on_interpolated_string_node_enter(node)
|
94
|
-
opening_loc = node.opening_loc
|
95
|
-
closing_loc = node.closing_loc
|
94
|
+
opening_loc = node.opening_loc || node.location
|
95
|
+
closing_loc = node.closing_loc || node.parts.last&.location || node.location
|
96
96
|
|
97
|
-
add_lines_range(opening_loc.start_line, closing_loc.start_line - 1)
|
97
|
+
add_lines_range(opening_loc.start_line, closing_loc.start_line - 1)
|
98
98
|
end
|
99
99
|
|
100
100
|
sig { params(node: Prism::ArrayNode).void }
|
@@ -112,6 +112,11 @@ module RubyLsp
|
|
112
112
|
add_simple_range(node)
|
113
113
|
end
|
114
114
|
|
115
|
+
sig { params(node: Prism::CaseMatchNode).void }
|
116
|
+
def on_case_match_node_enter(node)
|
117
|
+
add_simple_range(node)
|
118
|
+
end
|
119
|
+
|
115
120
|
sig { params(node: Prism::ClassNode).void }
|
116
121
|
def on_class_node_enter(node)
|
117
122
|
add_simple_range(node)
|
@@ -167,14 +172,6 @@ module RubyLsp
|
|
167
172
|
add_simple_range(node)
|
168
173
|
end
|
169
174
|
|
170
|
-
sig { params(node: Prism::StringConcatNode).void }
|
171
|
-
def on_string_concat_node_enter(node)
|
172
|
-
left = T.let(node.left, Prism::Node)
|
173
|
-
left = left.left while left.is_a?(Prism::StringConcatNode)
|
174
|
-
|
175
|
-
add_lines_range(left.location.start_line, node.right.location.end_line - 1)
|
176
|
-
end
|
177
|
-
|
178
175
|
sig { params(node: Prism::DefNode).void }
|
179
176
|
def on_def_node_enter(node)
|
180
177
|
params = node.parameters
|
@@ -64,11 +64,6 @@ module RubyLsp
|
|
64
64
|
sig { override.returns(T.nilable(T.all(T::Array[Interface::TextEdit], Object))) }
|
65
65
|
def run
|
66
66
|
return if @formatter == "none"
|
67
|
-
|
68
|
-
# Don't try to format files outside the current working directory
|
69
|
-
path = @uri.to_standardized_path
|
70
|
-
return unless path.nil? || path.start_with?(T.must(WORKSPACE_URI.to_standardized_path))
|
71
|
-
|
72
67
|
return if @document.syntax_error?
|
73
68
|
|
74
69
|
formatted_text = formatted_file
|
@@ -37,15 +37,14 @@ module RubyLsp
|
|
37
37
|
index: RubyIndexer::Index,
|
38
38
|
nesting: T::Array[String],
|
39
39
|
dispatcher: Prism::Dispatcher,
|
40
|
-
message_queue: Thread::Queue,
|
41
40
|
).void
|
42
41
|
end
|
43
|
-
def initialize(index, nesting, dispatcher
|
42
|
+
def initialize(index, nesting, dispatcher)
|
44
43
|
@index = index
|
45
44
|
@nesting = nesting
|
46
45
|
@_response = T.let(nil, ResponseType)
|
47
46
|
|
48
|
-
super(dispatcher
|
47
|
+
super(dispatcher)
|
49
48
|
dispatcher.register(
|
50
49
|
self,
|
51
50
|
:on_constant_read_node_enter,
|
@@ -57,7 +56,7 @@ module RubyLsp
|
|
57
56
|
|
58
57
|
sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
|
59
58
|
def initialize_external_listener(addon)
|
60
|
-
addon.create_hover_listener(@nesting, @index, @dispatcher
|
59
|
+
addon.create_hover_listener(@nesting, @index, @dispatcher)
|
61
60
|
end
|
62
61
|
|
63
62
|
# Merges responses from other hover listeners
|
@@ -9,6 +9,14 @@ module RubyLsp
|
|
9
9
|
# are labels added directly in the code that explicitly show the user something that might
|
10
10
|
# otherwise just be implied.
|
11
11
|
#
|
12
|
+
# # Configuration
|
13
|
+
#
|
14
|
+
# To enable rescue hints, set `rubyLsp.featuresConfiguration.inlayHint.implicitRescue` to `true`.
|
15
|
+
#
|
16
|
+
# To enable hash value hints, set `rubyLsp.featuresConfiguration.inlayHint.implicitHashValue` to `true`.
|
17
|
+
#
|
18
|
+
# To enable all hints, set `rubyLsp.featuresConfiguration.inlayHint.enableAll` to `true`.
|
19
|
+
#
|
12
20
|
# # Example
|
13
21
|
#
|
14
22
|
# ```ruby
|
@@ -39,18 +47,26 @@ module RubyLsp
|
|
39
47
|
sig { override.returns(ResponseType) }
|
40
48
|
attr_reader :_response
|
41
49
|
|
42
|
-
sig
|
43
|
-
|
44
|
-
|
50
|
+
sig do
|
51
|
+
params(
|
52
|
+
range: T::Range[Integer],
|
53
|
+
hints_configuration: RequestConfig,
|
54
|
+
dispatcher: Prism::Dispatcher,
|
55
|
+
).void
|
56
|
+
end
|
57
|
+
def initialize(range, hints_configuration, dispatcher)
|
58
|
+
super(dispatcher)
|
45
59
|
|
46
60
|
@_response = T.let([], ResponseType)
|
47
61
|
@range = range
|
62
|
+
@hints_configuration = hints_configuration
|
48
63
|
|
49
64
|
dispatcher.register(self, :on_rescue_node_enter, :on_implicit_node_enter)
|
50
65
|
end
|
51
66
|
|
52
67
|
sig { params(node: Prism::RescueNode).void }
|
53
68
|
def on_rescue_node_enter(node)
|
69
|
+
return unless @hints_configuration.enabled?(:implicitRescue)
|
54
70
|
return unless node.exceptions.empty?
|
55
71
|
|
56
72
|
loc = node.location
|
@@ -66,6 +82,7 @@ module RubyLsp
|
|
66
82
|
|
67
83
|
sig { params(node: Prism::ImplicitNode).void }
|
68
84
|
def on_implicit_node_enter(node)
|
85
|
+
return unless @hints_configuration.enabled?(:implicitHashValue)
|
69
86
|
return unless visible?(node, @range)
|
70
87
|
|
71
88
|
node_value = node.value
|