ruby-lsp 0.16.1 → 0.16.3
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_lsp/document.rb +6 -6
- data/lib/ruby_lsp/global_state.rb +43 -8
- data/lib/ruby_lsp/listeners/code_lens.rb +9 -4
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +1 -1
- data/lib/ruby_lsp/server.rb +22 -27
- data/lib/ruby_lsp/setup_bundler.rb +13 -1
- data/lib/ruby_lsp/store.rb +3 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 906f8ef7ff4c3c0da126b61e41772b36989c93e391575099121c7a31184de81c
|
4
|
+
data.tar.gz: 67eb8cd92613348b9b2bf7163b458ed0ba7772e4c0304c01b80e3b0c4e8b34c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6b28979f399686bf62943bb49036ed26411a11439120f8ddf52f7c86310ecc8964d32de8fffe98c12686021f8d2b019c49347de4ced546a1a2e4e1b47726bfd
|
7
|
+
data.tar.gz: 3339ddda6a9450cf4449a0336a38ec4bdd95b4d81e9b2aa834bfd87db11f3bb2d0caf02e5ad4d0366f040d4718046e36744750e46ef9638b78a4235f0dfad1b7
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.16.
|
1
|
+
0.16.3
|
data/lib/ruby_lsp/document.rb
CHANGED
@@ -20,13 +20,13 @@ module RubyLsp
|
|
20
20
|
sig { returns(URI::Generic) }
|
21
21
|
attr_reader :uri
|
22
22
|
|
23
|
-
sig { returns(
|
23
|
+
sig { returns(Encoding) }
|
24
24
|
attr_reader :encoding
|
25
25
|
|
26
|
-
sig { params(source: String, version: Integer, uri: URI::Generic, encoding:
|
27
|
-
def initialize(source:, version:, uri:, encoding:
|
26
|
+
sig { params(source: String, version: Integer, uri: URI::Generic, encoding: Encoding).void }
|
27
|
+
def initialize(source:, version:, uri:, encoding: Encoding::UTF_8)
|
28
28
|
@cache = T.let({}, T::Hash[String, T.untyped])
|
29
|
-
@encoding = T.let(encoding,
|
29
|
+
@encoding = T.let(encoding, Encoding)
|
30
30
|
@source = T.let(source, String)
|
31
31
|
@version = T.let(version, Integer)
|
32
32
|
@uri = T.let(uri, URI::Generic)
|
@@ -187,7 +187,7 @@ module RubyLsp
|
|
187
187
|
# After character 0xFFFF, UTF-16 considers characters to have length 2 and we have to account for that
|
188
188
|
SURROGATE_PAIR_START = T.let(0xFFFF, Integer)
|
189
189
|
|
190
|
-
sig { params(source: String, encoding:
|
190
|
+
sig { params(source: String, encoding: Encoding).void }
|
191
191
|
def initialize(source, encoding)
|
192
192
|
@current_line = T.let(0, Integer)
|
193
193
|
@pos = T.let(0, Integer)
|
@@ -209,7 +209,7 @@ module RubyLsp
|
|
209
209
|
# need to adjust for surrogate pairs
|
210
210
|
requested_position = @pos + position[:character]
|
211
211
|
|
212
|
-
if @encoding ==
|
212
|
+
if @encoding == Encoding::UTF_16LE
|
213
213
|
requested_position -= utf_16_character_position_correction(@pos, requested_position)
|
214
214
|
end
|
215
215
|
|
@@ -17,11 +17,15 @@ module RubyLsp
|
|
17
17
|
sig { returns(RubyIndexer::Index) }
|
18
18
|
attr_reader :index
|
19
19
|
|
20
|
+
sig { returns(Encoding) }
|
21
|
+
attr_reader :encoding
|
22
|
+
|
20
23
|
sig { void }
|
21
24
|
def initialize
|
22
25
|
@workspace_uri = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
|
26
|
+
@encoding = T.let(Encoding::UTF_8, Encoding)
|
23
27
|
|
24
|
-
@formatter = T.let(
|
28
|
+
@formatter = T.let("auto", String)
|
25
29
|
@test_library = T.let(detect_test_library, String)
|
26
30
|
@typechecker = T.let(detect_typechecker, T::Boolean)
|
27
31
|
@index = T.let(RubyIndexer::Index.new, RubyIndexer::Index)
|
@@ -42,6 +46,21 @@ module RubyLsp
|
|
42
46
|
def apply_options(options)
|
43
47
|
workspace_uri = options.dig(:workspaceFolders, 0, :uri)
|
44
48
|
@workspace_uri = URI(workspace_uri) if workspace_uri
|
49
|
+
|
50
|
+
specified_formatter = options.dig(:initializationOptions, :formatter)
|
51
|
+
@formatter = specified_formatter if specified_formatter
|
52
|
+
@formatter = detect_formatter if @formatter == "auto"
|
53
|
+
|
54
|
+
encodings = options.dig(:capabilities, :general, :positionEncodings)
|
55
|
+
@encoding = if !encodings || encodings.empty?
|
56
|
+
Encoding::UTF_16LE
|
57
|
+
elsif encodings.include?(Constant::PositionEncodingKind::UTF8)
|
58
|
+
Encoding::UTF_8
|
59
|
+
elsif encodings.include?(Constant::PositionEncodingKind::UTF16)
|
60
|
+
Encoding::UTF_16LE
|
61
|
+
else
|
62
|
+
Encoding::UTF_32
|
63
|
+
end
|
45
64
|
end
|
46
65
|
|
47
66
|
sig { returns(String) }
|
@@ -49,6 +68,25 @@ module RubyLsp
|
|
49
68
|
T.must(@workspace_uri.to_standardized_path)
|
50
69
|
end
|
51
70
|
|
71
|
+
sig { returns(String) }
|
72
|
+
def encoding_name
|
73
|
+
case @encoding
|
74
|
+
when Encoding::UTF_8
|
75
|
+
Constant::PositionEncodingKind::UTF8
|
76
|
+
when Encoding::UTF_16LE
|
77
|
+
Constant::PositionEncodingKind::UTF16
|
78
|
+
else
|
79
|
+
Constant::PositionEncodingKind::UTF32
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
sig { params(gem_pattern: Regexp).returns(T::Boolean) }
|
84
|
+
def direct_dependency?(gem_pattern)
|
85
|
+
dependencies.any?(gem_pattern)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
52
90
|
sig { returns(String) }
|
53
91
|
def detect_formatter
|
54
92
|
# NOTE: Intentionally no $ at end, since we want to match rubocop-shopify, etc.
|
@@ -66,8 +104,10 @@ module RubyLsp
|
|
66
104
|
if direct_dependency?(/^rspec/)
|
67
105
|
"rspec"
|
68
106
|
# A Rails app may have a dependency on minitest, but we would instead want to use the Rails test runner provided
|
69
|
-
# by ruby-lsp-rails.
|
70
|
-
|
107
|
+
# by ruby-lsp-rails. A Rails app doesn't need to depend on the rails gem itself, individual components like
|
108
|
+
# activestorage may be added to the gemfile so that other components aren't downloaded. Check for the presence
|
109
|
+
# of bin/rails to support these cases.
|
110
|
+
elsif File.exist?(File.join(workspace_path, "bin/rails"))
|
71
111
|
"rails"
|
72
112
|
# NOTE: Intentionally ends with $ to avoid mis-matching minitest-reporters, etc. in a Rails app.
|
73
113
|
elsif direct_dependency?(/^minitest$/)
|
@@ -79,11 +119,6 @@ module RubyLsp
|
|
79
119
|
end
|
80
120
|
end
|
81
121
|
|
82
|
-
sig { params(gem_pattern: Regexp).returns(T::Boolean) }
|
83
|
-
def direct_dependency?(gem_pattern)
|
84
|
-
dependencies.any?(gem_pattern)
|
85
|
-
end
|
86
|
-
|
87
122
|
sig { returns(T::Boolean) }
|
88
123
|
def detect_typechecker
|
89
124
|
return false if ENV["RUBY_LSP_BYPASS_TYPECHECKER"]
|
@@ -68,17 +68,22 @@ module RubyLsp
|
|
68
68
|
command: generate_test_command(group_stack: @group_stack),
|
69
69
|
kind: :group,
|
70
70
|
)
|
71
|
-
end
|
72
71
|
|
73
|
-
|
74
|
-
|
72
|
+
@group_id_stack.push(@group_id)
|
73
|
+
@group_id += 1
|
74
|
+
end
|
75
75
|
end
|
76
76
|
|
77
77
|
sig { params(node: Prism::ClassNode).void }
|
78
78
|
def on_class_node_leave(node)
|
79
79
|
@visibility_stack.pop
|
80
80
|
@group_stack.pop
|
81
|
-
|
81
|
+
|
82
|
+
class_name = node.constant_path.slice
|
83
|
+
|
84
|
+
if @path && class_name.end_with?("Test")
|
85
|
+
@group_id_stack.pop
|
86
|
+
end
|
82
87
|
end
|
83
88
|
|
84
89
|
sig { params(node: Prism::DefNode).void }
|
@@ -163,7 +163,7 @@ module RubyLsp
|
|
163
163
|
|
164
164
|
sig { params(line: String).returns(Integer) }
|
165
165
|
def length_of_line(line)
|
166
|
-
if @document.encoding ==
|
166
|
+
if @document.encoding == Encoding::UTF_16LE
|
167
167
|
line_length = 0
|
168
168
|
line.codepoints.each do |codepoint|
|
169
169
|
line_length += 1
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -118,19 +118,8 @@ module RubyLsp
|
|
118
118
|
client_name = options.dig(:clientInfo, :name)
|
119
119
|
@store.client_name = client_name if client_name
|
120
120
|
|
121
|
-
encodings = options.dig(:capabilities, :general, :positionEncodings)
|
122
|
-
@store.encoding = if encodings.nil? || encodings.empty?
|
123
|
-
Constant::PositionEncodingKind::UTF16
|
124
|
-
elsif encodings.include?(Constant::PositionEncodingKind::UTF8)
|
125
|
-
Constant::PositionEncodingKind::UTF8
|
126
|
-
else
|
127
|
-
encodings.first
|
128
|
-
end
|
129
|
-
|
130
121
|
progress = options.dig(:capabilities, :window, :workDoneProgress)
|
131
122
|
@store.supports_progress = progress.nil? ? true : progress
|
132
|
-
formatter = options.dig(:initializationOptions, :formatter) || "auto"
|
133
|
-
|
134
123
|
configured_features = options.dig(:initializationOptions, :enabledFeatures)
|
135
124
|
@store.experimental_features = options.dig(:initializationOptions, :experimentalFeaturesEnabled) || false
|
136
125
|
|
@@ -170,14 +159,14 @@ module RubyLsp
|
|
170
159
|
change: Constant::TextDocumentSyncKind::INCREMENTAL,
|
171
160
|
open_close: true,
|
172
161
|
),
|
173
|
-
position_encoding: @
|
162
|
+
position_encoding: @global_state.encoding_name,
|
174
163
|
selection_range_provider: enabled_features["selectionRanges"],
|
175
164
|
hover_provider: hover_provider,
|
176
165
|
document_symbol_provider: document_symbol_provider,
|
177
166
|
document_link_provider: document_link_provider,
|
178
167
|
folding_range_provider: folding_ranges_provider,
|
179
168
|
semantic_tokens_provider: semantic_tokens_provider,
|
180
|
-
document_formatting_provider: enabled_features["formatting"] && formatter != "none",
|
169
|
+
document_formatting_provider: enabled_features["formatting"] && @global_state.formatter != "none",
|
181
170
|
document_highlight_provider: enabled_features["documentHighlights"],
|
182
171
|
code_action_provider: code_action_provider,
|
183
172
|
document_on_type_formatting_provider: on_type_formatting_provider,
|
@@ -271,25 +260,31 @@ module RubyLsp
|
|
271
260
|
|
272
261
|
sig { params(message: T::Hash[Symbol, T.untyped]).void }
|
273
262
|
def text_document_did_open(message)
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
263
|
+
@mutex.synchronize do
|
264
|
+
text_document = message.dig(:params, :textDocument)
|
265
|
+
@store.set(
|
266
|
+
uri: text_document[:uri],
|
267
|
+
source: text_document[:text],
|
268
|
+
version: text_document[:version],
|
269
|
+
encoding: @global_state.encoding,
|
270
|
+
)
|
271
|
+
end
|
279
272
|
end
|
280
273
|
|
281
274
|
sig { params(message: T::Hash[Symbol, T.untyped]).void }
|
282
275
|
def text_document_did_close(message)
|
283
|
-
|
284
|
-
|
276
|
+
@mutex.synchronize do
|
277
|
+
uri = message.dig(:params, :textDocument, :uri)
|
278
|
+
@store.delete(uri)
|
285
279
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
280
|
+
# Clear diagnostics for the closed file, so that they no longer appear in the problems tab
|
281
|
+
send_message(
|
282
|
+
Notification.new(
|
283
|
+
method: "textDocument/publishDiagnostics",
|
284
|
+
params: Interface::PublishDiagnosticsParams.new(uri: uri.to_s, diagnostics: []),
|
285
|
+
),
|
286
|
+
)
|
287
|
+
end
|
293
288
|
end
|
294
289
|
|
295
290
|
sig { params(message: T::Hash[Symbol, T.untyped]).void }
|
@@ -19,6 +19,7 @@ module RubyLsp
|
|
19
19
|
extend T::Sig
|
20
20
|
|
21
21
|
class BundleNotLocked < StandardError; end
|
22
|
+
class BundleInstallFailure < StandardError; end
|
22
23
|
|
23
24
|
FOUR_HOURS = T.let(4 * 60 * 60, Integer)
|
24
25
|
|
@@ -49,6 +50,7 @@ module RubyLsp
|
|
49
50
|
@last_updated_path = T.let(@custom_dir + "last_updated", Pathname)
|
50
51
|
|
51
52
|
@dependencies = T.let(load_dependencies, T::Hash[String, T.untyped])
|
53
|
+
@retry = T.let(false, T::Boolean)
|
52
54
|
end
|
53
55
|
|
54
56
|
# Sets up the custom bundle and returns the `BUNDLE_GEMFILE`, `BUNDLE_PATH` and `BUNDLE_APP_CONFIG` that should be
|
@@ -224,7 +226,17 @@ module RubyLsp
|
|
224
226
|
# Add bundle update
|
225
227
|
$stderr.puts("Ruby LSP> Running bundle install for the custom bundle. This may take a while...")
|
226
228
|
$stderr.puts("Ruby LSP> Command: #{command}")
|
227
|
-
|
229
|
+
|
230
|
+
# Try to run the bundle install or update command. If that fails, it normally means that the custom lockfile is in
|
231
|
+
# a bad state that no longer reflects the top level one. In that case, we can remove the whole directory, try
|
232
|
+
# another time and give up if it fails again
|
233
|
+
if !system(env, command) && !@retry && @custom_dir.exist?
|
234
|
+
@retry = true
|
235
|
+
@custom_dir.rmtree
|
236
|
+
$stderr.puts("Ruby LSP> Running bundle install failed. Trying to re-generate the custom bundle from scratch")
|
237
|
+
return setup!
|
238
|
+
end
|
239
|
+
|
228
240
|
[bundle_gemfile.to_s, expanded_path, env["BUNDLE_APP_CONFIG"]]
|
229
241
|
end
|
230
242
|
|
data/lib/ruby_lsp/store.rb
CHANGED
@@ -5,9 +5,6 @@ module RubyLsp
|
|
5
5
|
class Store
|
6
6
|
extend T::Sig
|
7
7
|
|
8
|
-
sig { returns(String) }
|
9
|
-
attr_accessor :encoding
|
10
|
-
|
11
8
|
sig { returns(T::Boolean) }
|
12
9
|
attr_accessor :supports_progress
|
13
10
|
|
@@ -23,7 +20,6 @@ module RubyLsp
|
|
23
20
|
sig { void }
|
24
21
|
def initialize
|
25
22
|
@state = T.let({}, T::Hash[String, Document])
|
26
|
-
@encoding = T.let(Constant::PositionEncodingKind::UTF8, String)
|
27
23
|
@supports_progress = T.let(true, T::Boolean)
|
28
24
|
@experimental_features = T.let(false, T::Boolean)
|
29
25
|
@features_configuration = T.let(
|
@@ -49,9 +45,9 @@ module RubyLsp
|
|
49
45
|
T.must(@state[uri.to_s])
|
50
46
|
end
|
51
47
|
|
52
|
-
sig { params(uri: URI::Generic, source: String, version: Integer).void }
|
53
|
-
def set(uri:, source:, version:)
|
54
|
-
document = RubyDocument.new(source: source, version: version, uri: uri, encoding:
|
48
|
+
sig { params(uri: URI::Generic, source: String, version: Integer, encoding: Encoding).void }
|
49
|
+
def set(uri:, source:, version:, encoding: Encoding::UTF_8)
|
50
|
+
document = RubyDocument.new(source: source, version: version, uri: uri, encoding: encoding)
|
55
51
|
@state[uri.to_s] = document
|
56
52
|
end
|
57
53
|
|
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.3
|
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-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|