ruby-lsp 0.12.5 → 0.13.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|