ruby-lsp 0.17.16 → 0.18.0
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/README.md +4 -110
- data/VERSION +1 -1
- data/exe/ruby-lsp +10 -8
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +14 -6
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +157 -27
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +31 -12
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -2
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +10 -10
- data/lib/ruby_indexer/test/constant_test.rb +4 -4
- data/lib/ruby_indexer/test/enhancements_test.rb +2 -2
- data/lib/ruby_indexer/test/index_test.rb +41 -0
- data/lib/ruby_indexer/test/method_test.rb +257 -2
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
- data/lib/ruby_lsp/addon.rb +3 -2
- data/lib/ruby_lsp/base_server.rb +21 -1
- data/lib/ruby_lsp/document.rb +5 -3
- data/lib/ruby_lsp/erb_document.rb +29 -10
- data/lib/ruby_lsp/global_state.rb +15 -1
- data/lib/ruby_lsp/listeners/code_lens.rb +34 -5
- data/lib/ruby_lsp/listeners/folding_ranges.rb +1 -1
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +28 -0
- data/lib/ruby_lsp/listeners/signature_help.rb +55 -24
- data/lib/ruby_lsp/rbs_document.rb +5 -4
- data/lib/ruby_lsp/requests/code_action_resolve.rb +0 -15
- data/lib/ruby_lsp/requests/code_actions.rb +0 -10
- data/lib/ruby_lsp/requests/code_lens.rb +1 -11
- data/lib/ruby_lsp/requests/completion.rb +3 -20
- data/lib/ruby_lsp/requests/completion_resolve.rb +0 -8
- data/lib/ruby_lsp/requests/definition.rb +6 -20
- data/lib/ruby_lsp/requests/diagnostics.rb +0 -10
- data/lib/ruby_lsp/requests/document_highlight.rb +7 -14
- data/lib/ruby_lsp/requests/document_link.rb +0 -10
- data/lib/ruby_lsp/requests/document_symbol.rb +0 -17
- data/lib/ruby_lsp/requests/folding_ranges.rb +0 -10
- data/lib/ruby_lsp/requests/formatting.rb +3 -17
- data/lib/ruby_lsp/requests/hover.rb +9 -9
- data/lib/ruby_lsp/requests/inlay_hints.rb +0 -30
- data/lib/ruby_lsp/requests/on_type_formatting.rb +0 -10
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +0 -11
- data/lib/ruby_lsp/requests/request.rb +17 -1
- data/lib/ruby_lsp/requests/selection_ranges.rb +0 -10
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -23
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +0 -11
- data/lib/ruby_lsp/requests/signature_help.rb +5 -20
- data/lib/ruby_lsp/requests/support/common.rb +1 -1
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +2 -0
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +0 -11
- data/lib/ruby_lsp/requests/workspace_symbol.rb +0 -12
- data/lib/ruby_lsp/ruby_document.rb +4 -3
- data/lib/ruby_lsp/server.rb +23 -8
- data/lib/ruby_lsp/setup_bundler.rb +31 -13
- data/lib/ruby_lsp/type_inferrer.rb +6 -2
- data/lib/ruby_lsp/utils.rb +11 -1
- metadata +7 -14
- data/lib/ruby_lsp/check_docs.rb +0 -130
@@ -44,6 +44,7 @@ module RubyLsp
|
|
44
44
|
@group_id_stack = T.let([], T::Array[Integer])
|
45
45
|
# We want to avoid adding code lenses for nested definitions
|
46
46
|
@def_depth = T.let(0, Integer)
|
47
|
+
@spec_id = T.let(0, Integer)
|
47
48
|
|
48
49
|
dispatcher.register(
|
49
50
|
self,
|
@@ -70,6 +71,7 @@ module RubyLsp
|
|
70
71
|
name: class_name,
|
71
72
|
command: generate_test_command(group_stack: @group_stack),
|
72
73
|
kind: :group,
|
74
|
+
id: generate_fully_qualified_id(group_stack: @group_stack),
|
73
75
|
)
|
74
76
|
|
75
77
|
@group_id_stack.push(@group_id)
|
@@ -106,6 +108,7 @@ module RubyLsp
|
|
106
108
|
name: method_name,
|
107
109
|
command: generate_test_command(method_name: method_name, group_stack: @group_stack),
|
108
110
|
kind: :example,
|
111
|
+
id: generate_fully_qualified_id(group_stack: @group_stack, method_name: method_name),
|
109
112
|
)
|
110
113
|
end
|
111
114
|
end
|
@@ -166,19 +169,20 @@ module RubyLsp
|
|
166
169
|
@visibility_stack.push([prev_visibility, prev_visibility])
|
167
170
|
if node.name == DESCRIBE_KEYWORD
|
168
171
|
@group_id_stack.pop
|
172
|
+
@group_stack.pop
|
169
173
|
end
|
170
174
|
end
|
171
175
|
|
172
176
|
private
|
173
177
|
|
174
|
-
sig { params(node: Prism::Node, name: String, command: String, kind: Symbol).void }
|
175
|
-
def add_test_code_lens(node, name:, command:, kind:)
|
178
|
+
sig { params(node: Prism::Node, name: String, command: String, kind: Symbol, id: String).void }
|
179
|
+
def add_test_code_lens(node, name:, command:, kind:, id: name)
|
176
180
|
# don't add code lenses if the test library is not supported or unknown
|
177
181
|
return unless SUPPORTED_TEST_LIBRARIES.include?(@global_state.test_library) && @path
|
178
182
|
|
179
183
|
arguments = [
|
180
184
|
@path,
|
181
|
-
|
185
|
+
id,
|
182
186
|
command,
|
183
187
|
{
|
184
188
|
start_line: node.location.start_line - 1,
|
@@ -186,6 +190,7 @@ module RubyLsp
|
|
186
190
|
end_line: node.location.end_line - 1,
|
187
191
|
end_column: node.location.end_column,
|
188
192
|
},
|
193
|
+
name,
|
189
194
|
]
|
190
195
|
|
191
196
|
grouping_data = { group_id: @group_id_stack.last, kind: kind }
|
@@ -247,7 +252,7 @@ module RubyLsp
|
|
247
252
|
# We know the entire path, do an exact match
|
248
253
|
" --name " + Shellwords.escape(group_stack.join("::")) + "#" + Shellwords.escape(method_name)
|
249
254
|
elsif spec_name
|
250
|
-
" --name " + "
|
255
|
+
" --name " + "\"/^#{Shellwords.escape(group_stack.join("::"))}##{Shellwords.escape(spec_name)}$/\""
|
251
256
|
else
|
252
257
|
# Execute all tests of the selected class and tests in
|
253
258
|
# modules/classes nested inside of that class
|
@@ -282,15 +287,39 @@ module RubyLsp
|
|
282
287
|
|
283
288
|
return unless name
|
284
289
|
|
290
|
+
if kind == :example
|
291
|
+
# Increment spec_id for each example
|
292
|
+
@spec_id += 1
|
293
|
+
else
|
294
|
+
# Reset spec_id when entering a new group
|
295
|
+
@spec_id = 0
|
296
|
+
@group_stack.push(name)
|
297
|
+
end
|
298
|
+
|
285
299
|
if @path
|
300
|
+
method_name = format("test_%04d_%s", @spec_id, name) if kind == :example
|
286
301
|
add_test_code_lens(
|
287
302
|
node,
|
288
303
|
name: name,
|
289
|
-
command: generate_test_command(spec_name:
|
304
|
+
command: generate_test_command(group_stack: @group_stack, spec_name: method_name),
|
290
305
|
kind: kind,
|
306
|
+
id: generate_fully_qualified_id(group_stack: @group_stack, method_name: method_name),
|
291
307
|
)
|
292
308
|
end
|
293
309
|
end
|
310
|
+
|
311
|
+
sig { params(group_stack: T::Array[String], method_name: T.nilable(String)).returns(String) }
|
312
|
+
def generate_fully_qualified_id(group_stack:, method_name: nil)
|
313
|
+
if method_name
|
314
|
+
# For tests, this will be the test class and method name: `Foo::BarTest#test_baz`.
|
315
|
+
# For specs, this will be the nested descriptions and formatted test name: `a::b::c#test_001_foo`.
|
316
|
+
group_stack.join("::") + "#" + method_name
|
317
|
+
else
|
318
|
+
# For tests, this will be the test class: `Foo::BarTest`.
|
319
|
+
# For specs, this will be the nested descriptions: `a::b::c`.
|
320
|
+
group_stack.join("::")
|
321
|
+
end
|
322
|
+
end
|
294
323
|
end
|
295
324
|
end
|
296
325
|
end
|
@@ -242,7 +242,7 @@ module RubyLsp
|
|
242
242
|
body = statements.body
|
243
243
|
return if body.empty?
|
244
244
|
|
245
|
-
add_lines_range(node.location.start_line,
|
245
|
+
add_lines_range(node.location.start_line, body.last.location.end_line)
|
246
246
|
end
|
247
247
|
|
248
248
|
sig { params(node: Prism::Node).void }
|
@@ -41,6 +41,7 @@ module RubyLsp
|
|
41
41
|
:on_block_node_leave,
|
42
42
|
:on_self_node_enter,
|
43
43
|
:on_module_node_enter,
|
44
|
+
:on_local_variable_write_node_enter,
|
44
45
|
:on_local_variable_read_node_enter,
|
45
46
|
:on_block_parameter_node_enter,
|
46
47
|
:on_required_keyword_parameter_node_enter,
|
@@ -49,6 +50,9 @@ module RubyLsp
|
|
49
50
|
:on_optional_parameter_node_enter,
|
50
51
|
:on_required_parameter_node_enter,
|
51
52
|
:on_rest_parameter_node_enter,
|
53
|
+
:on_local_variable_and_write_node_enter,
|
54
|
+
:on_local_variable_operator_write_node_enter,
|
55
|
+
:on_local_variable_or_write_node_enter,
|
52
56
|
:on_local_variable_target_node_enter,
|
53
57
|
:on_block_local_variable_node_enter,
|
54
58
|
:on_match_write_node_enter,
|
@@ -164,6 +168,12 @@ module RubyLsp
|
|
164
168
|
@response_builder.add_token(node.location, :variable, [:default_library])
|
165
169
|
end
|
166
170
|
|
171
|
+
sig { params(node: Prism::LocalVariableWriteNode).void }
|
172
|
+
def on_local_variable_write_node_enter(node)
|
173
|
+
type = @current_scope.type_for(node.name)
|
174
|
+
@response_builder.add_token(node.name_loc, type) if type == :parameter
|
175
|
+
end
|
176
|
+
|
167
177
|
sig { params(node: Prism::LocalVariableReadNode).void }
|
168
178
|
def on_local_variable_read_node_enter(node)
|
169
179
|
return if @inside_implicit_node
|
@@ -177,6 +187,24 @@ module RubyLsp
|
|
177
187
|
@response_builder.add_token(node.location, @current_scope.type_for(node.name))
|
178
188
|
end
|
179
189
|
|
190
|
+
sig { params(node: Prism::LocalVariableAndWriteNode).void }
|
191
|
+
def on_local_variable_and_write_node_enter(node)
|
192
|
+
type = @current_scope.type_for(node.name)
|
193
|
+
@response_builder.add_token(node.name_loc, type) if type == :parameter
|
194
|
+
end
|
195
|
+
|
196
|
+
sig { params(node: Prism::LocalVariableOperatorWriteNode).void }
|
197
|
+
def on_local_variable_operator_write_node_enter(node)
|
198
|
+
type = @current_scope.type_for(node.name)
|
199
|
+
@response_builder.add_token(node.name_loc, type) if type == :parameter
|
200
|
+
end
|
201
|
+
|
202
|
+
sig { params(node: Prism::LocalVariableOrWriteNode).void }
|
203
|
+
def on_local_variable_or_write_node_enter(node)
|
204
|
+
type = @current_scope.type_for(node.name)
|
205
|
+
@response_builder.add_token(node.name_loc, type) if type == :parameter
|
206
|
+
end
|
207
|
+
|
180
208
|
sig { params(node: Prism::LocalVariableTargetNode).void }
|
181
209
|
def on_local_variable_target_node_enter(node)
|
182
210
|
# If we're inside a regex capture, Prism will add LocalVariableTarget nodes for each captured variable.
|
@@ -42,17 +42,46 @@ module RubyLsp
|
|
42
42
|
target_method = methods.first
|
43
43
|
return unless target_method
|
44
44
|
|
45
|
-
|
46
|
-
name = target_method.name
|
45
|
+
signatures = target_method.signatures
|
47
46
|
|
48
47
|
# If the method doesn't have any parameters, there's no need to show signature help
|
49
|
-
return if
|
48
|
+
return if signatures.empty?
|
49
|
+
|
50
|
+
name = target_method.name
|
51
|
+
title = +""
|
52
|
+
|
53
|
+
extra_links = if type.is_a?(TypeInferrer::GuessedType)
|
54
|
+
title << "\n\nGuessed receiver: #{type.name}"
|
55
|
+
"[Learn more about guessed types](#{GUESSED_TYPES_URL})"
|
56
|
+
end
|
50
57
|
|
51
|
-
|
58
|
+
active_signature, active_parameter = determine_active_signature_and_parameter(node, signatures)
|
52
59
|
|
60
|
+
signature_help = Interface::SignatureHelp.new(
|
61
|
+
signatures: generate_signatures(signatures, name, methods, title, extra_links),
|
62
|
+
active_signature: active_signature,
|
63
|
+
active_parameter: active_parameter,
|
64
|
+
)
|
65
|
+
@response_builder.replace(signature_help)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
sig do
|
71
|
+
params(node: Prism::CallNode, signatures: T::Array[RubyIndexer::Entry::Signature]).returns([Integer, Integer])
|
72
|
+
end
|
73
|
+
def determine_active_signature_and_parameter(node, signatures)
|
53
74
|
arguments_node = node.arguments
|
54
75
|
arguments = arguments_node&.arguments || []
|
55
|
-
|
76
|
+
|
77
|
+
# Find the first signature that matches the current arguments. If the user is invoking a method incorrectly and
|
78
|
+
# none of the signatures match, we show the first one
|
79
|
+
active_sig_index = signatures.find_index do |signature|
|
80
|
+
signature.matches?(arguments)
|
81
|
+
end || 0
|
82
|
+
|
83
|
+
parameter_length = [T.must(signatures[active_sig_index]).parameters.length - 1, 0].max
|
84
|
+
active_parameter = (arguments.length - 1).clamp(0, parameter_length)
|
56
85
|
|
57
86
|
# If there are arguments, then we need to check if there's a trailing comma after the end of the last argument
|
58
87
|
# to advance the active parameter to the next one
|
@@ -61,27 +90,29 @@ module RubyLsp
|
|
61
90
|
active_parameter += 1
|
62
91
|
end
|
63
92
|
|
64
|
-
|
65
|
-
|
66
|
-
extra_links = if type.is_a?(TypeInferrer::GuessedType)
|
67
|
-
title << "\n\nGuessed receiver: #{type.name}"
|
68
|
-
"[Learn more about guessed types](#{GUESSED_TYPES_URL})"
|
69
|
-
end
|
93
|
+
[active_sig_index, active_parameter]
|
94
|
+
end
|
70
95
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
96
|
+
sig do
|
97
|
+
params(
|
98
|
+
signatures: T::Array[RubyIndexer::Entry::Signature],
|
99
|
+
method_name: String,
|
100
|
+
methods: T::Array[RubyIndexer::Entry],
|
101
|
+
title: String,
|
102
|
+
extra_links: T.nilable(String),
|
103
|
+
).returns(T::Array[Interface::SignatureInformation])
|
104
|
+
end
|
105
|
+
def generate_signatures(signatures, method_name, methods, title, extra_links)
|
106
|
+
signatures.map do |signature|
|
107
|
+
Interface::SignatureInformation.new(
|
108
|
+
label: "#{method_name}(#{signature.format})",
|
109
|
+
parameters: signature.parameters.map { |param| Interface::ParameterInformation.new(label: param.name) },
|
110
|
+
documentation: Interface::MarkupContent.new(
|
111
|
+
kind: "markdown",
|
112
|
+
value: markdown_from_index_entries(title, methods, extra_links: extra_links),
|
80
113
|
),
|
81
|
-
|
82
|
-
|
83
|
-
)
|
84
|
-
@response_builder.replace(signature_help)
|
114
|
+
)
|
115
|
+
end
|
85
116
|
end
|
86
117
|
end
|
87
118
|
end
|
@@ -14,18 +14,19 @@ module RubyLsp
|
|
14
14
|
super
|
15
15
|
end
|
16
16
|
|
17
|
-
sig { override.returns(
|
18
|
-
def parse
|
19
|
-
return
|
17
|
+
sig { override.returns(T::Boolean) }
|
18
|
+
def parse!
|
19
|
+
return false unless @needs_parsing
|
20
20
|
|
21
21
|
@needs_parsing = false
|
22
22
|
|
23
23
|
_, _, declarations = RBS::Parser.parse_signature(@source)
|
24
24
|
@syntax_error = false
|
25
25
|
@parse_result = declarations
|
26
|
+
true
|
26
27
|
rescue RBS::ParsingError
|
27
28
|
@syntax_error = true
|
28
|
-
|
29
|
+
true
|
29
30
|
end
|
30
31
|
|
31
32
|
sig { override.returns(T::Boolean) }
|
@@ -3,24 +3,9 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
-
# 
|
7
|
-
#
|
8
6
|
# The [code action resolve](https://microsoft.github.io/language-server-protocol/specification#codeAction_resolve)
|
9
7
|
# request is used to to resolve the edit field for a given code action, if it is not already provided in the
|
10
8
|
# textDocument/codeAction response. We can use it for scenarios that require more computation such as refactoring.
|
11
|
-
#
|
12
|
-
# # Example: Extract to variable
|
13
|
-
#
|
14
|
-
# ```ruby
|
15
|
-
# # Before:
|
16
|
-
# 1 + 1 # Select the text and use Refactor: Extract Variable
|
17
|
-
#
|
18
|
-
# # After:
|
19
|
-
# new_variable = 1 + 1
|
20
|
-
# new_variable
|
21
|
-
#
|
22
|
-
# ```
|
23
|
-
#
|
24
9
|
class CodeActionResolve < Request
|
25
10
|
extend T::Sig
|
26
11
|
include Support::Common
|
@@ -3,19 +3,9 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
-
# 
|
7
|
-
#
|
8
6
|
# The [code actions](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeAction)
|
9
7
|
# request informs the editor of RuboCop quick fixes that can be applied. These are accessible by hovering over a
|
10
8
|
# specific diagnostic.
|
11
|
-
#
|
12
|
-
# # Example
|
13
|
-
#
|
14
|
-
# ```ruby
|
15
|
-
# def say_hello
|
16
|
-
# puts "Hello" # --> code action: quick fix indentation
|
17
|
-
# end
|
18
|
-
# ```
|
19
9
|
class CodeActions < Request
|
20
10
|
extend T::Sig
|
21
11
|
|
@@ -7,19 +7,9 @@ require "ruby_lsp/listeners/code_lens"
|
|
7
7
|
|
8
8
|
module RubyLsp
|
9
9
|
module Requests
|
10
|
-
# 
|
11
|
-
#
|
12
10
|
# The
|
13
11
|
# [code lens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens)
|
14
|
-
# request informs the editor of runnable commands such as testing and debugging
|
15
|
-
#
|
16
|
-
# # Example
|
17
|
-
#
|
18
|
-
# ```ruby
|
19
|
-
# # Run | Run in Terminal | Debug
|
20
|
-
# class Test < Minitest::Test
|
21
|
-
# end
|
22
|
-
# ```
|
12
|
+
# request informs the editor of runnable commands such as testing and debugging.
|
23
13
|
class CodeLens < Request
|
24
14
|
extend T::Sig
|
25
15
|
|
@@ -5,27 +5,8 @@ require "ruby_lsp/listeners/completion"
|
|
5
5
|
|
6
6
|
module RubyLsp
|
7
7
|
module Requests
|
8
|
-
# 
|
9
|
-
#
|
10
8
|
# The [completion](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion)
|
11
9
|
# suggests possible completions according to what the developer is typing.
|
12
|
-
#
|
13
|
-
# Currently supported targets:
|
14
|
-
#
|
15
|
-
# - Classes
|
16
|
-
# - Modules
|
17
|
-
# - Constants
|
18
|
-
# - Require paths
|
19
|
-
# - Methods invoked on self only
|
20
|
-
# - Instance variables
|
21
|
-
#
|
22
|
-
# # Example
|
23
|
-
#
|
24
|
-
# ```ruby
|
25
|
-
# require "ruby_lsp/requests" # --> completion: suggests `base_request`, `code_actions`, ...
|
26
|
-
#
|
27
|
-
# RubyLsp::Requests:: # --> completion: suggests `Completion`, `Hover`, ...
|
28
|
-
# ```
|
29
10
|
class Completion < Request
|
30
11
|
extend T::Sig
|
31
12
|
|
@@ -36,7 +17,7 @@ module RubyLsp
|
|
36
17
|
def provider
|
37
18
|
Interface::CompletionOptions.new(
|
38
19
|
resolve_provider: true,
|
39
|
-
trigger_characters: ["/", "\"", "'", ":", "@", "."],
|
20
|
+
trigger_characters: ["/", "\"", "'", ":", "@", ".", "=", "<"],
|
40
21
|
completion_item: {
|
41
22
|
labelDetailsSupport: true,
|
42
23
|
},
|
@@ -60,6 +41,8 @@ module RubyLsp
|
|
60
41
|
# Completion always receives the position immediately after the character that was just typed. Here we adjust it
|
61
42
|
# back by 1, so that we find the right node
|
62
43
|
char_position = document.create_scanner.find_char_position(params[:position]) - 1
|
44
|
+
delegate_request_if_needed!(global_state, document, char_position)
|
45
|
+
|
63
46
|
node_context = RubyDocument.locate(
|
64
47
|
document.parse_result.value,
|
65
48
|
char_position,
|
@@ -3,8 +3,6 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
-
# 
|
7
|
-
#
|
8
6
|
# The [completionItem/resolve](https://microsoft.github.io/language-server-protocol/specification#completionItem_resolve)
|
9
7
|
# request provides additional information about the currently selected completion. Specifically, the `labelDetails`
|
10
8
|
# and `documentation` fields are provided, which are omitted from the completion items returned by
|
@@ -15,12 +13,6 @@ module RubyLsp
|
|
15
13
|
#
|
16
14
|
# At most 10 definitions are included, to ensure low latency during request processing and rendering the completion
|
17
15
|
# item.
|
18
|
-
#
|
19
|
-
# # Example
|
20
|
-
#
|
21
|
-
# ```ruby
|
22
|
-
# A # -> as the user cycles through completion items, the documentation will be resolved and displayed
|
23
|
-
# ```
|
24
16
|
class CompletionResolve < Request
|
25
17
|
extend T::Sig
|
26
18
|
include Requests::Support::Common
|
@@ -5,27 +5,9 @@ require "ruby_lsp/listeners/definition"
|
|
5
5
|
|
6
6
|
module RubyLsp
|
7
7
|
module Requests
|
8
|
-
# 
|
9
|
-
#
|
10
8
|
# The [definition
|
11
9
|
# request](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) jumps to the
|
12
10
|
# definition of the symbol under the cursor.
|
13
|
-
#
|
14
|
-
# Currently supported targets:
|
15
|
-
#
|
16
|
-
# - Classes
|
17
|
-
# - Modules
|
18
|
-
# - Constants
|
19
|
-
# - Require paths
|
20
|
-
# - Methods invoked on self only and on receivers where the type is unknown
|
21
|
-
# - Instance variables
|
22
|
-
#
|
23
|
-
# # Example
|
24
|
-
#
|
25
|
-
# ```ruby
|
26
|
-
# require "some_gem/file" # <- Request go to definition on this string will take you to the file
|
27
|
-
# Product.new # <- Request go to definition on this class name will take you to its declaration.
|
28
|
-
# ```
|
29
11
|
class Definition < Request
|
30
12
|
extend T::Sig
|
31
13
|
extend T::Generic
|
@@ -53,8 +35,12 @@ module RubyLsp
|
|
53
35
|
)
|
54
36
|
@dispatcher = dispatcher
|
55
37
|
|
56
|
-
|
57
|
-
|
38
|
+
char_position = document.create_scanner.find_char_position(position)
|
39
|
+
delegate_request_if_needed!(global_state, document, char_position)
|
40
|
+
|
41
|
+
node_context = RubyDocument.locate(
|
42
|
+
document.parse_result.value,
|
43
|
+
char_position,
|
58
44
|
node_types: [
|
59
45
|
Prism::CallNode,
|
60
46
|
Prism::ConstantReadNode,
|
@@ -3,19 +3,9 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
-
# 
|
7
|
-
#
|
8
6
|
# The
|
9
7
|
# [diagnostics](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics)
|
10
8
|
# request informs the editor of RuboCop offenses for a given file.
|
11
|
-
#
|
12
|
-
# # Example
|
13
|
-
#
|
14
|
-
# ```ruby
|
15
|
-
# def say_hello
|
16
|
-
# puts "Hello" # --> diagnostics: incorrect indentation
|
17
|
-
# end
|
18
|
-
# ```
|
19
9
|
class Diagnostics < Request
|
20
10
|
extend T::Sig
|
21
11
|
|
@@ -5,8 +5,6 @@ require "ruby_lsp/listeners/document_highlight"
|
|
5
5
|
|
6
6
|
module RubyLsp
|
7
7
|
module Requests
|
8
|
-
# 
|
9
|
-
#
|
10
8
|
# The [document highlight](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight)
|
11
9
|
# informs the editor all relevant elements of the currently pointed item for highlighting. For example, when
|
12
10
|
# the cursor is on the `F` of the constant `FOO`, the editor should identify other occurrences of `FOO`
|
@@ -14,29 +12,24 @@ module RubyLsp
|
|
14
12
|
#
|
15
13
|
# For writable elements like constants or variables, their read/write occurrences should be highlighted differently.
|
16
14
|
# This is achieved by sending different "kind" attributes to the editor (2 for read and 3 for write).
|
17
|
-
#
|
18
|
-
# # Example
|
19
|
-
#
|
20
|
-
# ```ruby
|
21
|
-
# FOO = 1 # should be highlighted as "write"
|
22
|
-
#
|
23
|
-
# def foo
|
24
|
-
# FOO # should be highlighted as "read"
|
25
|
-
# end
|
26
|
-
# ```
|
27
15
|
class DocumentHighlight < Request
|
28
16
|
extend T::Sig
|
29
17
|
|
30
18
|
sig do
|
31
19
|
params(
|
20
|
+
global_state: GlobalState,
|
32
21
|
document: T.any(RubyDocument, ERBDocument),
|
33
22
|
position: T::Hash[Symbol, T.untyped],
|
34
23
|
dispatcher: Prism::Dispatcher,
|
35
24
|
).void
|
36
25
|
end
|
37
|
-
def initialize(document, position, dispatcher)
|
26
|
+
def initialize(global_state, document, position, dispatcher)
|
38
27
|
super()
|
39
|
-
|
28
|
+
char_position = document.create_scanner.find_char_position(position)
|
29
|
+
delegate_request_if_needed!(global_state, document, char_position)
|
30
|
+
|
31
|
+
node_context = RubyDocument.locate(document.parse_result.value, char_position)
|
32
|
+
|
40
33
|
@response_builder = T.let(
|
41
34
|
ResponseBuilders::CollectionResponseBuilder[Interface::DocumentHighlight].new,
|
42
35
|
ResponseBuilders::CollectionResponseBuilder[Interface::DocumentHighlight],
|
@@ -5,19 +5,9 @@ require "ruby_lsp/listeners/document_link"
|
|
5
5
|
|
6
6
|
module RubyLsp
|
7
7
|
module Requests
|
8
|
-
# 
|
9
|
-
#
|
10
8
|
# The [document link](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentLink)
|
11
9
|
# makes `# source://PATH_TO_FILE#line` comments in a Ruby/RBI file clickable if the file exists.
|
12
10
|
# When the user clicks the link, it'll open that location.
|
13
|
-
#
|
14
|
-
# # Example
|
15
|
-
#
|
16
|
-
# ```ruby
|
17
|
-
# # source://syntax_tree/3.2.1/lib/syntax_tree.rb#51 <- it will be clickable and will take the user to that location
|
18
|
-
# def format(source, maxwidth = T.unsafe(nil))
|
19
|
-
# end
|
20
|
-
# ```
|
21
11
|
class DocumentLink < Request
|
22
12
|
extend T::Sig
|
23
13
|
|
@@ -5,29 +5,12 @@ require "ruby_lsp/listeners/document_symbol"
|
|
5
5
|
|
6
6
|
module RubyLsp
|
7
7
|
module Requests
|
8
|
-
# 
|
9
|
-
#
|
10
8
|
# The [document
|
11
9
|
# symbol](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol) request
|
12
10
|
# informs the editor of all the important symbols, such as classes, variables, and methods, defined in a file. With
|
13
11
|
# this information, the editor can populate breadcrumbs, file outline and allow for fuzzy symbol searches.
|
14
12
|
#
|
15
13
|
# In VS Code, fuzzy symbol search can be accessed by opening the command palette and inserting an `@` symbol.
|
16
|
-
#
|
17
|
-
# # Example
|
18
|
-
#
|
19
|
-
# ```ruby
|
20
|
-
# class Person # --> document symbol: class
|
21
|
-
# attr_reader :age # --> document symbol: field
|
22
|
-
#
|
23
|
-
# def initialize
|
24
|
-
# @age = 0 # --> document symbol: variable
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# def age # --> document symbol: method
|
28
|
-
# end
|
29
|
-
# end
|
30
|
-
# ```
|
31
14
|
class DocumentSymbol < Request
|
32
15
|
extend T::Sig
|
33
16
|
|
@@ -5,18 +5,8 @@ require "ruby_lsp/listeners/folding_ranges"
|
|
5
5
|
|
6
6
|
module RubyLsp
|
7
7
|
module Requests
|
8
|
-
# 
|
9
|
-
#
|
10
8
|
# The [folding ranges](https://microsoft.github.io/language-server-protocol/specification#textDocument_foldingRange)
|
11
9
|
# request informs the editor of the ranges where and how code can be folded.
|
12
|
-
#
|
13
|
-
# # Example
|
14
|
-
#
|
15
|
-
# ```ruby
|
16
|
-
# def say_hello # <-- folding range start
|
17
|
-
# puts "Hello"
|
18
|
-
# end # <-- folding range end
|
19
|
-
# ```
|
20
10
|
class FoldingRanges < Request
|
21
11
|
extend T::Sig
|
22
12
|
|
@@ -3,25 +3,9 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
-
# 
|
7
|
-
#
|
8
6
|
# The [formatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting)
|
9
7
|
# request uses RuboCop to fix auto-correctable offenses in the document. This requires enabling format on save and
|
10
8
|
# registering the ruby-lsp as the Ruby formatter.
|
11
|
-
#
|
12
|
-
# The `rubyLsp.formatter` setting specifies which formatter to use.
|
13
|
-
# If set to `auto` then it behaves as follows:
|
14
|
-
# * It will use RuboCop if it is part of the bundle.
|
15
|
-
# * If RuboCop is not available, and `syntax_tree` is a direct dependency, it will use that.
|
16
|
-
# * Otherwise, no formatting will be applied.
|
17
|
-
#
|
18
|
-
# # Example
|
19
|
-
#
|
20
|
-
# ```ruby
|
21
|
-
# def say_hello
|
22
|
-
# puts "Hello" # --> formatting: fixes the indentation on save
|
23
|
-
# end
|
24
|
-
# ```
|
25
9
|
class Formatting < Request
|
26
10
|
extend T::Sig
|
27
11
|
|
@@ -58,14 +42,16 @@ module RubyLsp
|
|
58
42
|
formatted_text = @active_formatter.run_formatting(@uri, @document)
|
59
43
|
return unless formatted_text
|
60
44
|
|
45
|
+
lines = @document.source.lines
|
61
46
|
size = @document.source.size
|
47
|
+
|
62
48
|
return if formatted_text.size == size && formatted_text == @document.source
|
63
49
|
|
64
50
|
[
|
65
51
|
Interface::TextEdit.new(
|
66
52
|
range: Interface::Range.new(
|
67
53
|
start: Interface::Position.new(line: 0, character: 0),
|
68
|
-
end: Interface::Position.new(line: size, character:
|
54
|
+
end: Interface::Position.new(line: lines.size, character: 0),
|
69
55
|
),
|
70
56
|
new_text: formatted_text,
|
71
57
|
),
|