ruby-lsp 0.16.3 → 0.16.5
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/lib/ruby_indexer/lib/ruby_indexer/entry.rb +28 -8
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +26 -0
- data/lib/ruby_indexer/ruby_indexer.rb +1 -0
- data/lib/ruby_lsp/base_server.rb +4 -2
- data/lib/ruby_lsp/global_state.rb +50 -30
- data/lib/ruby_lsp/listeners/definition.rb +10 -3
- data/lib/ruby_lsp/requests/diagnostics.rb +7 -4
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +6 -3
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +0 -3
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +0 -3
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +36 -13
- data/lib/ruby_lsp/server.rb +6 -8
- data/lib/ruby_lsp/utils.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcd4426f17d6d429be733a9adcdf799e23c29689ad5fb69f9b9f7b3cd334bf9b
|
4
|
+
data.tar.gz: 071d5c37e1acf83c07a5b48e85a3bc4a18fb63a20b54ff191158799cf4320803
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9edc44ec74f5f5d9b5f15fb7d22501126eb8f6bec3d9a69b3061946b369ecb0e453e45e9a0dc9df1482117dc738f7bd66005e2dcd0cd46e3aaad6f6658283766
|
7
|
+
data.tar.gz: c4f9ddb4da9373544b2456632a0fb76bdbca5e5ddf5e874b0e6ab4f6aae13ad8b17ef9482873b37ae33bc7ec797faebde76bf5a6e9d86e6a4ddf798b4eb9f0df
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.16.
|
1
|
+
0.16.5
|
@@ -11,7 +11,7 @@ module RubyIndexer
|
|
11
11
|
sig { returns(String) }
|
12
12
|
attr_reader :file_path
|
13
13
|
|
14
|
-
sig { returns(
|
14
|
+
sig { returns(RubyIndexer::Location) }
|
15
15
|
attr_reader :location
|
16
16
|
|
17
17
|
sig { returns(T::Array[String]) }
|
@@ -20,13 +20,33 @@ module RubyIndexer
|
|
20
20
|
sig { returns(Symbol) }
|
21
21
|
attr_accessor :visibility
|
22
22
|
|
23
|
-
sig
|
23
|
+
sig do
|
24
|
+
params(
|
25
|
+
name: String,
|
26
|
+
file_path: String,
|
27
|
+
location: T.any(Prism::Location, RubyIndexer::Location),
|
28
|
+
comments: T::Array[String],
|
29
|
+
).void
|
30
|
+
end
|
24
31
|
def initialize(name, file_path, location, comments)
|
25
32
|
@name = name
|
26
33
|
@file_path = file_path
|
27
|
-
@location = location
|
28
34
|
@comments = comments
|
29
35
|
@visibility = T.let(:public, Symbol)
|
36
|
+
|
37
|
+
@location = T.let(
|
38
|
+
if location.is_a?(Prism::Location)
|
39
|
+
Location.new(
|
40
|
+
location.start_line,
|
41
|
+
location.end_line,
|
42
|
+
location.start_column,
|
43
|
+
location.end_column,
|
44
|
+
)
|
45
|
+
else
|
46
|
+
location
|
47
|
+
end,
|
48
|
+
RubyIndexer::Location,
|
49
|
+
)
|
30
50
|
end
|
31
51
|
|
32
52
|
sig { returns(String) }
|
@@ -50,7 +70,7 @@ module RubyIndexer
|
|
50
70
|
params(
|
51
71
|
name: String,
|
52
72
|
file_path: String,
|
53
|
-
location: Prism::Location,
|
73
|
+
location: T.any(Prism::Location, RubyIndexer::Location),
|
54
74
|
comments: T::Array[String],
|
55
75
|
).void
|
56
76
|
end
|
@@ -81,7 +101,7 @@ module RubyIndexer
|
|
81
101
|
params(
|
82
102
|
name: String,
|
83
103
|
file_path: String,
|
84
|
-
location: Prism::Location,
|
104
|
+
location: T.any(Prism::Location, RubyIndexer::Location),
|
85
105
|
comments: T::Array[String],
|
86
106
|
parent_class: T.nilable(String),
|
87
107
|
).void
|
@@ -181,7 +201,7 @@ module RubyIndexer
|
|
181
201
|
params(
|
182
202
|
name: String,
|
183
203
|
file_path: String,
|
184
|
-
location: Prism::Location,
|
204
|
+
location: T.any(Prism::Location, RubyIndexer::Location),
|
185
205
|
comments: T::Array[String],
|
186
206
|
owner: T.nilable(Entry::Namespace),
|
187
207
|
).void
|
@@ -219,7 +239,7 @@ module RubyIndexer
|
|
219
239
|
params(
|
220
240
|
name: String,
|
221
241
|
file_path: String,
|
222
|
-
location: Prism::Location,
|
242
|
+
location: T.any(Prism::Location, RubyIndexer::Location),
|
223
243
|
comments: T::Array[String],
|
224
244
|
parameters_node: T.nilable(Prism::ParametersNode),
|
225
245
|
owner: T.nilable(Entry::Namespace),
|
@@ -349,7 +369,7 @@ module RubyIndexer
|
|
349
369
|
nesting: T::Array[String],
|
350
370
|
name: String,
|
351
371
|
file_path: String,
|
352
|
-
location: Prism::Location,
|
372
|
+
location: T.any(Prism::Location, RubyIndexer::Location),
|
353
373
|
comments: T::Array[String],
|
354
374
|
).void
|
355
375
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyIndexer
|
5
|
+
class Location
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
sig { returns(Integer) }
|
9
|
+
attr_reader :start_line, :end_line, :start_column, :end_column
|
10
|
+
|
11
|
+
sig do
|
12
|
+
params(
|
13
|
+
start_line: Integer,
|
14
|
+
end_line: Integer,
|
15
|
+
start_column: Integer,
|
16
|
+
end_column: Integer,
|
17
|
+
).void
|
18
|
+
end
|
19
|
+
def initialize(start_line, end_line, start_column, end_column)
|
20
|
+
@start_line = start_line
|
21
|
+
@end_line = end_line
|
22
|
+
@start_column = start_column
|
23
|
+
@end_column = end_column
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -10,6 +10,7 @@ require "ruby_indexer/lib/ruby_indexer/index"
|
|
10
10
|
require "ruby_indexer/lib/ruby_indexer/entry"
|
11
11
|
require "ruby_indexer/lib/ruby_indexer/configuration"
|
12
12
|
require "ruby_indexer/lib/ruby_indexer/prefix_tree"
|
13
|
+
require "ruby_indexer/lib/ruby_indexer/location"
|
13
14
|
|
14
15
|
module RubyIndexer
|
15
16
|
@configuration = T.let(Configuration.new, Configuration)
|
data/lib/ruby_lsp/base_server.rb
CHANGED
@@ -59,9 +59,11 @@ module RubyLsp
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
#
|
63
|
-
#
|
62
|
+
# The following requests need to be executed in the main thread directly to avoid concurrency issues. Everything
|
63
|
+
# else is pushed into the incoming queue
|
64
64
|
case method
|
65
|
+
when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange"
|
66
|
+
process_message(message)
|
65
67
|
when "shutdown"
|
66
68
|
$stderr.puts("Shutting down Ruby LSP...")
|
67
69
|
|
@@ -20,16 +20,21 @@ module RubyLsp
|
|
20
20
|
sig { returns(Encoding) }
|
21
21
|
attr_reader :encoding
|
22
22
|
|
23
|
+
sig { returns(T::Boolean) }
|
24
|
+
attr_reader :supports_watching_files
|
25
|
+
|
23
26
|
sig { void }
|
24
27
|
def initialize
|
25
28
|
@workspace_uri = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
|
26
29
|
@encoding = T.let(Encoding::UTF_8, Encoding)
|
27
30
|
|
28
31
|
@formatter = T.let("auto", String)
|
29
|
-
@
|
30
|
-
@
|
32
|
+
@linters = T.let([], T::Array[String])
|
33
|
+
@test_library = T.let("minitest", String)
|
34
|
+
@typechecker = T.let(true, T::Boolean)
|
31
35
|
@index = T.let(RubyIndexer::Index.new, RubyIndexer::Index)
|
32
36
|
@supported_formatters = T.let({}, T::Hash[String, Requests::Support::Formatter])
|
37
|
+
@supports_watching_files = T.let(false, T::Boolean)
|
33
38
|
end
|
34
39
|
|
35
40
|
sig { params(identifier: String, instance: Requests::Support::Formatter).void }
|
@@ -42,14 +47,25 @@ module RubyLsp
|
|
42
47
|
@supported_formatters[@formatter]
|
43
48
|
end
|
44
49
|
|
50
|
+
sig { returns(T::Array[Requests::Support::Formatter]) }
|
51
|
+
def active_linters
|
52
|
+
@linters.filter_map { |name| @supported_formatters[name] }
|
53
|
+
end
|
54
|
+
|
45
55
|
sig { params(options: T::Hash[Symbol, T.untyped]).void }
|
46
56
|
def apply_options(options)
|
57
|
+
dependencies = gather_dependencies
|
47
58
|
workspace_uri = options.dig(:workspaceFolders, 0, :uri)
|
48
59
|
@workspace_uri = URI(workspace_uri) if workspace_uri
|
49
60
|
|
50
61
|
specified_formatter = options.dig(:initializationOptions, :formatter)
|
51
62
|
@formatter = specified_formatter if specified_formatter
|
52
|
-
@formatter = detect_formatter if @formatter == "auto"
|
63
|
+
@formatter = detect_formatter(dependencies) if @formatter == "auto"
|
64
|
+
|
65
|
+
specified_linters = options.dig(:initializationOptions, :linters)
|
66
|
+
@linters = specified_linters || detect_linters(dependencies)
|
67
|
+
@test_library = detect_test_library(dependencies)
|
68
|
+
@typechecker = detect_typechecker(dependencies)
|
53
69
|
|
54
70
|
encodings = options.dig(:capabilities, :general, :positionEncodings)
|
55
71
|
@encoding = if !encodings || encodings.empty?
|
@@ -61,6 +77,11 @@ module RubyLsp
|
|
61
77
|
else
|
62
78
|
Encoding::UTF_32
|
63
79
|
end
|
80
|
+
|
81
|
+
file_watching_caps = options.dig(:capabilities, :workspace, :didChangeWatchedFiles)
|
82
|
+
if file_watching_caps&.dig(:dynamicRegistration) && file_watching_caps&.dig(:relativePatternSupport)
|
83
|
+
@supports_watching_files = true
|
84
|
+
end
|
64
85
|
end
|
65
86
|
|
66
87
|
sig { returns(String) }
|
@@ -80,28 +101,32 @@ module RubyLsp
|
|
80
101
|
end
|
81
102
|
end
|
82
103
|
|
83
|
-
sig { params(gem_pattern: Regexp).returns(T::Boolean) }
|
84
|
-
def direct_dependency?(gem_pattern)
|
85
|
-
dependencies.any?(gem_pattern)
|
86
|
-
end
|
87
|
-
|
88
104
|
private
|
89
105
|
|
90
|
-
sig { returns(String) }
|
91
|
-
def detect_formatter
|
106
|
+
sig { params(dependencies: T::Array[String]).returns(String) }
|
107
|
+
def detect_formatter(dependencies)
|
92
108
|
# NOTE: Intentionally no $ at end, since we want to match rubocop-shopify, etc.
|
93
|
-
if
|
109
|
+
if dependencies.any?(/^rubocop/)
|
94
110
|
"rubocop"
|
95
|
-
elsif
|
111
|
+
elsif dependencies.any?(/^syntax_tree$/)
|
96
112
|
"syntax_tree"
|
97
113
|
else
|
98
114
|
"none"
|
99
115
|
end
|
100
116
|
end
|
101
117
|
|
102
|
-
|
103
|
-
|
104
|
-
|
118
|
+
# Try to detect if there are linters in the project's dependencies. For auto-detection, we always only consider a
|
119
|
+
# single linter. To have multiple linters running, the user must configure them manually
|
120
|
+
sig { params(dependencies: T::Array[String]).returns(T::Array[String]) }
|
121
|
+
def detect_linters(dependencies)
|
122
|
+
linters = []
|
123
|
+
linters << "rubocop" if dependencies.any?(/^rubocop/)
|
124
|
+
linters
|
125
|
+
end
|
126
|
+
|
127
|
+
sig { params(dependencies: T::Array[String]).returns(String) }
|
128
|
+
def detect_test_library(dependencies)
|
129
|
+
if dependencies.any?(/^rspec/)
|
105
130
|
"rspec"
|
106
131
|
# A Rails app may have a dependency on minitest, but we would instead want to use the Rails test runner provided
|
107
132
|
# by ruby-lsp-rails. A Rails app doesn't need to depend on the rails gem itself, individual components like
|
@@ -110,23 +135,23 @@ module RubyLsp
|
|
110
135
|
elsif File.exist?(File.join(workspace_path, "bin/rails"))
|
111
136
|
"rails"
|
112
137
|
# NOTE: Intentionally ends with $ to avoid mis-matching minitest-reporters, etc. in a Rails app.
|
113
|
-
elsif
|
138
|
+
elsif dependencies.any?(/^minitest$/)
|
114
139
|
"minitest"
|
115
|
-
elsif
|
140
|
+
elsif dependencies.any?(/^test-unit/)
|
116
141
|
"test-unit"
|
117
142
|
else
|
118
143
|
"unknown"
|
119
144
|
end
|
120
145
|
end
|
121
146
|
|
122
|
-
sig { returns(T::Boolean) }
|
123
|
-
def detect_typechecker
|
147
|
+
sig { params(dependencies: T::Array[String]).returns(T::Boolean) }
|
148
|
+
def detect_typechecker(dependencies)
|
124
149
|
return false if ENV["RUBY_LSP_BYPASS_TYPECHECKER"]
|
125
150
|
|
126
151
|
# We can't read the env from within `Bundle.with_original_env` so we need to set it here.
|
127
152
|
ruby_lsp_env_is_test = (ENV["RUBY_LSP_ENV"] == "test")
|
128
153
|
Bundler.with_original_env do
|
129
|
-
sorbet_static_detected =
|
154
|
+
sorbet_static_detected = dependencies.any?(/^sorbet-static/)
|
130
155
|
# Don't show message while running tests, since it's noisy
|
131
156
|
if sorbet_static_detected && !ruby_lsp_env_is_test
|
132
157
|
$stderr.puts("Ruby LSP detected this is a Sorbet project so will defer to Sorbet LSP for some functionality")
|
@@ -138,16 +163,11 @@ module RubyLsp
|
|
138
163
|
end
|
139
164
|
|
140
165
|
sig { returns(T::Array[String]) }
|
141
|
-
def
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
rescue Bundler::GemfileNotFound
|
147
|
-
[]
|
148
|
-
end,
|
149
|
-
T.nilable(T::Array[String]),
|
150
|
-
)
|
166
|
+
def gather_dependencies
|
167
|
+
Bundler.with_original_env { Bundler.default_gemfile }
|
168
|
+
Bundler.locked_gems.dependencies.keys + gemspec_dependencies
|
169
|
+
rescue Bundler::GemfileNotFound
|
170
|
+
[]
|
151
171
|
end
|
152
172
|
|
153
173
|
sig { returns(T::Array[String]) }
|
@@ -7,6 +7,8 @@ module RubyLsp
|
|
7
7
|
extend T::Sig
|
8
8
|
include Requests::Support::Common
|
9
9
|
|
10
|
+
MAX_NUMBER_OF_DEFINITION_CANDIDATES_WITHOUT_RECEIVER = 10
|
11
|
+
|
10
12
|
sig do
|
11
13
|
params(
|
12
14
|
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::Location],
|
@@ -64,12 +66,17 @@ module RubyLsp
|
|
64
66
|
|
65
67
|
sig { params(node: Prism::CallNode).void }
|
66
68
|
def handle_method_definition(node)
|
67
|
-
return unless self_receiver?(node)
|
68
|
-
|
69
69
|
message = node.message
|
70
70
|
return unless message
|
71
71
|
|
72
|
-
methods =
|
72
|
+
methods = if self_receiver?(node)
|
73
|
+
@index.resolve_method(message, @nesting.join("::"))
|
74
|
+
else
|
75
|
+
# If the method doesn't have a receiver, then we provide a few candidates to jump to
|
76
|
+
# But we don't want to provide too many candidates, as it can be overwhelming
|
77
|
+
@index[message]&.take(MAX_NUMBER_OF_DEFINITION_CANDIDATES_WITHOUT_RECEIVER)
|
78
|
+
end
|
79
|
+
|
73
80
|
return unless methods
|
74
81
|
|
75
82
|
methods.each do |target_method|
|
@@ -34,7 +34,7 @@ module RubyLsp
|
|
34
34
|
sig { params(global_state: GlobalState, document: Document).void }
|
35
35
|
def initialize(global_state, document)
|
36
36
|
super()
|
37
|
-
@
|
37
|
+
@active_linters = T.let(global_state.active_linters, T::Array[Support::Formatter])
|
38
38
|
@document = document
|
39
39
|
@uri = T.let(document.uri, URI::Generic)
|
40
40
|
end
|
@@ -45,10 +45,13 @@ module RubyLsp
|
|
45
45
|
diagnostics.concat(syntax_error_diagnostics, syntax_warning_diagnostics)
|
46
46
|
|
47
47
|
# Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid
|
48
|
-
return diagnostics if @document.syntax_error? ||
|
48
|
+
return diagnostics if @document.syntax_error? || @active_linters.empty?
|
49
|
+
|
50
|
+
@active_linters.each do |linter|
|
51
|
+
linter_diagnostics = linter.run_diagnostic(@uri, @document)
|
52
|
+
diagnostics.concat(linter_diagnostics) if linter_diagnostics
|
53
|
+
end
|
49
54
|
|
50
|
-
formatter_diagnostics = @active_formatter.run_diagnostic(@uri, @document)
|
51
|
-
diagnostics.concat(formatter_diagnostics) if formatter_diagnostics
|
52
55
|
diagnostics
|
53
56
|
end
|
54
57
|
|
@@ -40,10 +40,13 @@ module RubyLsp
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
sig { params(dispatcher: Prism::Dispatcher, range: T.nilable(T::Range[Integer])).void }
|
44
|
-
def initialize(dispatcher, range: nil)
|
43
|
+
sig { params(global_state: GlobalState, dispatcher: Prism::Dispatcher, range: T.nilable(T::Range[Integer])).void }
|
44
|
+
def initialize(global_state, dispatcher, range: nil)
|
45
45
|
super()
|
46
|
-
@response_builder = T.let(
|
46
|
+
@response_builder = T.let(
|
47
|
+
ResponseBuilders::SemanticHighlighting.new(global_state.encoding),
|
48
|
+
ResponseBuilders::SemanticHighlighting,
|
49
|
+
)
|
47
50
|
Listeners::SemanticHighlighting.new(dispatcher, @response_builder, range: range)
|
48
51
|
|
49
52
|
Addon.addons.each do |addon|
|
@@ -3,15 +3,12 @@
|
|
3
3
|
|
4
4
|
return unless defined?(RubyLsp::Requests::Support::RuboCopRunner)
|
5
5
|
|
6
|
-
require "singleton"
|
7
|
-
|
8
6
|
module RubyLsp
|
9
7
|
module Requests
|
10
8
|
module Support
|
11
9
|
class RuboCopFormatter
|
12
10
|
extend T::Sig
|
13
11
|
include Formatter
|
14
|
-
include Singleton
|
15
12
|
|
16
13
|
sig { void }
|
17
14
|
def initialize
|
@@ -8,15 +8,12 @@ rescue LoadError
|
|
8
8
|
return
|
9
9
|
end
|
10
10
|
|
11
|
-
require "singleton"
|
12
|
-
|
13
11
|
module RubyLsp
|
14
12
|
module Requests
|
15
13
|
module Support
|
16
14
|
# :nodoc:
|
17
15
|
class SyntaxTreeFormatter
|
18
16
|
extend T::Sig
|
19
|
-
include Singleton
|
20
17
|
include Support::Formatter
|
21
18
|
|
22
19
|
sig { void }
|
@@ -55,19 +55,21 @@ module RubyLsp
|
|
55
55
|
|
56
56
|
ResponseType = type_member { { fixed: Interface::SemanticTokens } }
|
57
57
|
|
58
|
-
sig { void }
|
59
|
-
def initialize
|
60
|
-
super
|
58
|
+
sig { params(encoding: Encoding).void }
|
59
|
+
def initialize(encoding)
|
60
|
+
super()
|
61
|
+
@encoding = encoding
|
61
62
|
@stack = T.let([], T::Array[SemanticToken])
|
62
63
|
end
|
63
64
|
|
64
65
|
sig { params(location: Prism::Location, type: Symbol, modifiers: T::Array[Symbol]).void }
|
65
66
|
def add_token(location, type, modifiers = [])
|
66
|
-
length = location.
|
67
|
+
length = location.end_code_units_offset(@encoding) - location.start_code_units_offset(@encoding)
|
67
68
|
modifiers_indices = modifiers.filter_map { |modifier| TOKEN_MODIFIERS[modifier] }
|
68
69
|
@stack.push(
|
69
70
|
SemanticToken.new(
|
70
|
-
|
71
|
+
start_line: location.start_line,
|
72
|
+
start_code_unit_column: location.start_code_units_column(@encoding),
|
71
73
|
length: length,
|
72
74
|
type: T.must(TOKEN_TYPES[type]),
|
73
75
|
modifier: modifiers_indices,
|
@@ -75,6 +77,15 @@ module RubyLsp
|
|
75
77
|
)
|
76
78
|
end
|
77
79
|
|
80
|
+
sig { params(location: Prism::Location).returns(T::Boolean) }
|
81
|
+
def last_token_matches?(location)
|
82
|
+
token = @stack.last
|
83
|
+
return false unless token
|
84
|
+
|
85
|
+
token.start_line == location.start_line &&
|
86
|
+
token.start_code_unit_column == location.start_code_units_column(@encoding)
|
87
|
+
end
|
88
|
+
|
78
89
|
sig { returns(T.nilable(SemanticToken)) }
|
79
90
|
def last
|
80
91
|
@stack.last
|
@@ -88,8 +99,11 @@ module RubyLsp
|
|
88
99
|
class SemanticToken
|
89
100
|
extend T::Sig
|
90
101
|
|
91
|
-
sig { returns(
|
92
|
-
attr_reader :
|
102
|
+
sig { returns(Integer) }
|
103
|
+
attr_reader :start_line
|
104
|
+
|
105
|
+
sig { returns(Integer) }
|
106
|
+
attr_reader :start_code_unit_column
|
93
107
|
|
94
108
|
sig { returns(Integer) }
|
95
109
|
attr_reader :length
|
@@ -100,9 +114,18 @@ module RubyLsp
|
|
100
114
|
sig { returns(T::Array[Integer]) }
|
101
115
|
attr_reader :modifier
|
102
116
|
|
103
|
-
sig
|
104
|
-
|
105
|
-
|
117
|
+
sig do
|
118
|
+
params(
|
119
|
+
start_line: Integer,
|
120
|
+
start_code_unit_column: Integer,
|
121
|
+
length: Integer,
|
122
|
+
type: Integer,
|
123
|
+
modifier: T::Array[Integer],
|
124
|
+
).void
|
125
|
+
end
|
126
|
+
def initialize(start_line:, start_code_unit_column:, length:, type:, modifier:)
|
127
|
+
@start_line = start_line
|
128
|
+
@start_code_unit_column = start_code_unit_column
|
106
129
|
@length = length
|
107
130
|
@type = type
|
108
131
|
@modifier = modifier
|
@@ -146,7 +169,7 @@ module RubyLsp
|
|
146
169
|
# Enumerable#sort_by is not deterministic when the compared values are equal.
|
147
170
|
# When that happens, we need to use the index as a tie breaker to ensure
|
148
171
|
# that the order of the tokens is always the same.
|
149
|
-
[token.
|
172
|
+
[token.start_line, token.start_code_unit_column, index]
|
150
173
|
end
|
151
174
|
|
152
175
|
delta = sorted_tokens.flat_map do |token|
|
@@ -167,8 +190,8 @@ module RubyLsp
|
|
167
190
|
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
|
168
191
|
sig { params(token: SemanticToken).returns(T::Array[Integer]) }
|
169
192
|
def compute_delta(token)
|
170
|
-
row = token.
|
171
|
-
column = token.
|
193
|
+
row = token.start_line - 1
|
194
|
+
column = token.start_code_unit_column
|
172
195
|
|
173
196
|
begin
|
174
197
|
delta_line = row - @current_row
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -187,11 +187,8 @@ module RubyLsp
|
|
187
187
|
|
188
188
|
send_message(Result.new(id: message[:id], response: response))
|
189
189
|
|
190
|
-
# Dynamically registered capabilities
|
191
|
-
file_watching_caps = options.dig(:capabilities, :workspace, :didChangeWatchedFiles)
|
192
|
-
|
193
190
|
# Not every client supports dynamic registration or file watching
|
194
|
-
if
|
191
|
+
if global_state.supports_watching_files
|
195
192
|
send_message(
|
196
193
|
Request.new(
|
197
194
|
id: @current_request_id,
|
@@ -248,10 +245,10 @@ module RubyLsp
|
|
248
245
|
end
|
249
246
|
|
250
247
|
if defined?(Requests::Support::RuboCopFormatter)
|
251
|
-
@global_state.register_formatter("rubocop", Requests::Support::RuboCopFormatter.
|
248
|
+
@global_state.register_formatter("rubocop", Requests::Support::RuboCopFormatter.new)
|
252
249
|
end
|
253
250
|
if defined?(Requests::Support::SyntaxTreeFormatter)
|
254
|
-
@global_state.register_formatter("syntax_tree", Requests::Support::SyntaxTreeFormatter.
|
251
|
+
@global_state.register_formatter("syntax_tree", Requests::Support::SyntaxTreeFormatter.new)
|
255
252
|
end
|
256
253
|
|
257
254
|
perform_initial_indexing(indexing_config)
|
@@ -337,7 +334,7 @@ module RubyLsp
|
|
337
334
|
document_link = Requests::DocumentLink.new(uri, document.comments, dispatcher)
|
338
335
|
code_lens = Requests::CodeLens.new(@global_state, uri, dispatcher)
|
339
336
|
|
340
|
-
semantic_highlighting = Requests::SemanticHighlighting.new(dispatcher)
|
337
|
+
semantic_highlighting = Requests::SemanticHighlighting.new(@global_state, dispatcher)
|
341
338
|
dispatcher.dispatch(document.tree)
|
342
339
|
|
343
340
|
# Store all responses retrieve in this round of visits in the cache and then return the response for the request
|
@@ -369,7 +366,7 @@ module RubyLsp
|
|
369
366
|
end_line = range.dig(:end, :line)
|
370
367
|
|
371
368
|
dispatcher = Prism::Dispatcher.new
|
372
|
-
request = Requests::SemanticHighlighting.new(dispatcher, range: start_line..end_line)
|
369
|
+
request = Requests::SemanticHighlighting.new(@global_state, dispatcher, range: start_line..end_line)
|
373
370
|
dispatcher.visit(document.tree)
|
374
371
|
|
375
372
|
response = request.perform
|
@@ -613,6 +610,7 @@ module RubyLsp
|
|
613
610
|
uri = URI(change[:uri])
|
614
611
|
file_path = uri.to_standardized_path
|
615
612
|
next if file_path.nil? || File.directory?(file_path)
|
613
|
+
next unless file_path.end_with?(".rb")
|
616
614
|
|
617
615
|
load_path_entry = $LOAD_PATH.find { |load_path| file_path.start_with?(load_path) }
|
618
616
|
indexable = RubyIndexer::IndexablePath.new(load_path_entry, file_path)
|
data/lib/ruby_lsp/utils.rb
CHANGED
@@ -75,7 +75,7 @@ module RubyLsp
|
|
75
75
|
class Request < Message
|
76
76
|
extend T::Sig
|
77
77
|
|
78
|
-
sig { params(id: Integer, method: String, params: Object).void }
|
78
|
+
sig { params(id: T.any(Integer, String), method: String, params: Object).void }
|
79
79
|
def initialize(id:, method:, params:)
|
80
80
|
@id = id
|
81
81
|
super(method: method, params: params)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.16.
|
4
|
+
version: 0.16.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
@@ -30,20 +30,20 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.23.0
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '0.
|
36
|
+
version: '0.28'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
43
|
+
version: 0.23.0
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '0.
|
46
|
+
version: '0.28'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sorbet-runtime
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- lib/ruby_indexer/lib/ruby_indexer/entry.rb
|
84
84
|
- lib/ruby_indexer/lib/ruby_indexer/index.rb
|
85
85
|
- lib/ruby_indexer/lib/ruby_indexer/indexable_path.rb
|
86
|
+
- lib/ruby_indexer/lib/ruby_indexer/location.rb
|
86
87
|
- lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb
|
87
88
|
- lib/ruby_indexer/ruby_indexer.rb
|
88
89
|
- lib/ruby_indexer/test/classes_and_modules_test.rb
|
@@ -177,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
178
|
- !ruby/object:Gem::Version
|
178
179
|
version: '0'
|
179
180
|
requirements: []
|
180
|
-
rubygems_version: 3.5.
|
181
|
+
rubygems_version: 3.5.9
|
181
182
|
signing_key:
|
182
183
|
specification_version: 4
|
183
184
|
summary: An opinionated language server for Ruby
|