ruby-lsp 0.23.6 → 0.23.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp +3 -3
- data/exe/ruby-lsp-launcher +24 -7
- data/lib/ruby_lsp/requests/code_actions.rb +1 -1
- data/lib/ruby_lsp/requests/diagnostics.rb +1 -1
- data/lib/ruby_lsp/requests/folding_ranges.rb +2 -6
- data/lib/ruby_lsp/requests/formatting.rb +2 -6
- data/lib/ruby_lsp/requests/on_type_formatting.rb +1 -1
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/server.rb +35 -0
- data/lib/ruby_lsp/setup_bundler.rb +18 -0
- data/lib/ruby_lsp/utils.rb +2 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46b72d1b9ba142496f64035b6b1ad54d096c0a28ae52311612bd118bc49e2956
|
4
|
+
data.tar.gz: 525dc46dcfc71ee57da51955a4034ceace3bbdd1eca7942b542ab2cd32d42ad4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '06690b76d284ca6abc05fc0e836af32a54c0a3cedea1fd53071648330a3b3b6e6d1a59ef205127f54a88e8cd3ca07c3840f25f1293e37737d705b2ea41719cb1'
|
7
|
+
data.tar.gz: bd6104ef180f122d0bb9d6d751213c43f0d19d0f203deb50e5d94583ff0aaf85559a040ca0371fc24506ff11a0d2742c14f1277226cc34d3a09d02730d46aed7
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
[![Build Status](https://github.com/Shopify/ruby-lsp/workflows/CI/badge.svg)](https://github.com/Shopify/ruby-lsp/actions/workflows/ci.yml)
|
6
6
|
[![Ruby LSP extension](https://img.shields.io/badge/VS%20Code-Ruby%20LSP-success?logo=visual-studio-code)](https://marketplace.visualstudio.com/items?itemName=Shopify.ruby-lsp)
|
7
|
-
[![Ruby DX Slack](https://img.shields.io/badge/Slack-Ruby%20DX-success?logo=slack)](https://join.slack.com/t/ruby-dx/shared_invite/zt-
|
7
|
+
[![Ruby DX Slack](https://img.shields.io/badge/Slack-Ruby%20DX-success?logo=slack)](https://join.slack.com/t/ruby-dx/shared_invite/zt-2yd77ayis-yAiVc1TX_kH0mHMBbi89dA)
|
8
8
|
|
9
9
|
# Ruby LSP
|
10
10
|
|
@@ -13,7 +13,7 @@ for Ruby, used to improve rich features in editors. It is a part of a wider goal
|
|
13
13
|
experience to Ruby developers using modern standards for cross-editor features, documentation and debugging.
|
14
14
|
|
15
15
|
Want to discuss Ruby developer experience? Consider joining the public
|
16
|
-
[Ruby DX Slack workspace](https://join.slack.com/t/ruby-dx/shared_invite/zt-
|
16
|
+
[Ruby DX Slack workspace](https://join.slack.com/t/ruby-dx/shared_invite/zt-2yd77ayis-yAiVc1TX_kH0mHMBbi89dA).
|
17
17
|
|
18
18
|
## Getting Started
|
19
19
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.23.
|
1
|
+
0.23.7
|
data/exe/ruby-lsp
CHANGED
@@ -64,9 +64,9 @@ if ENV["BUNDLE_GEMFILE"].nil?
|
|
64
64
|
# which gives us the opportunity to control which specs are activated and enter degraded mode if any gems failed to
|
65
65
|
# install rather than failing to boot the server completely
|
66
66
|
if options[:launcher]
|
67
|
-
|
68
|
-
|
69
|
-
exit exec(
|
67
|
+
flags = []
|
68
|
+
flags << "--debug" if options[:debug]
|
69
|
+
exit exec(Gem.ruby, File.expand_path("ruby-lsp-launcher", __dir__), *flags)
|
70
70
|
end
|
71
71
|
|
72
72
|
require_relative "../lib/ruby_lsp/setup_bundler"
|
data/exe/ruby-lsp-launcher
CHANGED
@@ -8,14 +8,24 @@
|
|
8
8
|
|
9
9
|
setup_error = nil
|
10
10
|
install_error = nil
|
11
|
+
reboot = false
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
workspace_uri = ARGV.first
|
14
|
+
|
15
|
+
raw_initialize = if workspace_uri && !workspace_uri.start_with?("--")
|
16
|
+
# If there's an argument without `--`, then it's the server asking to compose the bundle and passing to this
|
17
|
+
# executable the workspace URI. We can't require gems at this point, so we built a fake initialize request manually
|
18
|
+
reboot = true
|
19
|
+
"{\"params\":{\"workspaceFolders\":[{\"uri\":\"#{workspace_uri}\"}]}}"
|
20
|
+
else
|
21
|
+
# Read the initialize request before even starting the server. We need to do this to figure out the workspace URI.
|
22
|
+
# Editors are not required to spawn the language server process on the same directory as the workspace URI, so we need
|
23
|
+
# to ensure that we're setting up the bundle in the right place
|
24
|
+
$stdin.binmode
|
25
|
+
headers = $stdin.gets("\r\n\r\n")
|
26
|
+
content_length = headers[/Content-Length: (\d+)/i, 1].to_i
|
27
|
+
$stdin.read(content_length)
|
28
|
+
end
|
19
29
|
|
20
30
|
# Compose the Ruby LSP bundle in a forked process so that we can require gems without polluting the main process
|
21
31
|
# `$LOAD_PATH` and `Gem.loaded_specs`. Windows doesn't support forking, so we need a separate path to support it
|
@@ -91,6 +101,13 @@ rescue StandardError => e
|
|
91
101
|
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
92
102
|
end
|
93
103
|
|
104
|
+
# When performing a lockfile re-boot, this executable is invoked to set up the composed bundle ahead of time. In this
|
105
|
+
# flow, we are not booting the LSP yet, just checking if the bundle is valid before rebooting
|
106
|
+
if reboot
|
107
|
+
# Use the exit status to signal to the server if composing the bundle succeeded
|
108
|
+
exit(install_error || setup_error ? 1 : 0)
|
109
|
+
end
|
110
|
+
|
94
111
|
# Now that the bundle is set up, we can begin actually launching the server. Note that `Bundler.setup` will have already
|
95
112
|
# configured the load path using the version of the Ruby LSP present in the composed bundle. Do not push any Ruby LSP
|
96
113
|
# paths into the load path manually or we may end up requiring the wrong version of the gem
|
@@ -19,7 +19,7 @@ module RubyLsp
|
|
19
19
|
sig { returns(Interface::CodeActionRegistrationOptions) }
|
20
20
|
def provider
|
21
21
|
Interface::CodeActionRegistrationOptions.new(
|
22
|
-
document_selector:
|
22
|
+
document_selector: nil,
|
23
23
|
resolve_provider: true,
|
24
24
|
)
|
25
25
|
end
|
@@ -15,7 +15,7 @@ module RubyLsp
|
|
15
15
|
sig { returns(Interface::DiagnosticRegistrationOptions) }
|
16
16
|
def provider
|
17
17
|
Interface::DiagnosticRegistrationOptions.new(
|
18
|
-
document_selector:
|
18
|
+
document_selector: nil,
|
19
19
|
inter_file_dependencies: false,
|
20
20
|
workspace_diagnostics: false,
|
21
21
|
)
|
@@ -13,13 +13,9 @@ module RubyLsp
|
|
13
13
|
class << self
|
14
14
|
extend T::Sig
|
15
15
|
|
16
|
-
sig { returns(
|
16
|
+
sig { returns(TrueClass) }
|
17
17
|
def provider
|
18
|
-
|
19
|
-
document_selector: [
|
20
|
-
Interface::DocumentFilter.new(language: "ruby"),
|
21
|
-
],
|
22
|
-
)
|
18
|
+
true
|
23
19
|
end
|
24
20
|
end
|
25
21
|
|
@@ -14,13 +14,9 @@ module RubyLsp
|
|
14
14
|
class << self
|
15
15
|
extend T::Sig
|
16
16
|
|
17
|
-
sig { returns(
|
17
|
+
sig { returns(TrueClass) }
|
18
18
|
def provider
|
19
|
-
|
20
|
-
document_selector: [
|
21
|
-
Interface::DocumentFilter.new(language: "ruby"),
|
22
|
-
],
|
23
|
-
)
|
19
|
+
true
|
24
20
|
end
|
25
21
|
end
|
26
22
|
|
@@ -14,7 +14,7 @@ module RubyLsp
|
|
14
14
|
sig { returns(Interface::DocumentOnTypeFormattingRegistrationOptions) }
|
15
15
|
def provider
|
16
16
|
Interface::DocumentOnTypeFormattingRegistrationOptions.new(
|
17
|
-
document_selector:
|
17
|
+
document_selector: nil,
|
18
18
|
first_trigger_character: "{",
|
19
19
|
more_trigger_character: ["\n", "|", "d"],
|
20
20
|
)
|
@@ -17,7 +17,7 @@ module RubyLsp
|
|
17
17
|
sig { returns(Interface::SemanticTokensRegistrationOptions) }
|
18
18
|
def provider
|
19
19
|
Interface::SemanticTokensRegistrationOptions.new(
|
20
|
-
document_selector:
|
20
|
+
document_selector: nil,
|
21
21
|
legend: Interface::SemanticTokensLegend.new(
|
22
22
|
token_types: ResponseBuilders::SemanticHighlighting::TOKEN_TYPES.keys,
|
23
23
|
token_modifiers: ResponseBuilders::SemanticHighlighting::TOKEN_MODIFIERS.keys,
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -106,6 +106,8 @@ module RubyLsp
|
|
106
106
|
end,
|
107
107
|
),
|
108
108
|
)
|
109
|
+
when "rubyLsp/composeBundle"
|
110
|
+
compose_bundle(message)
|
109
111
|
when "$/cancelRequest"
|
110
112
|
@global_state.synchronize { @cancelled_requests << message[:params][:id] }
|
111
113
|
when nil
|
@@ -283,6 +285,7 @@ module RubyLsp
|
|
283
285
|
document_range_formatting_provider: true,
|
284
286
|
experimental: {
|
285
287
|
addon_detection: true,
|
288
|
+
compose_bundle: true,
|
286
289
|
},
|
287
290
|
),
|
288
291
|
serverInfo: {
|
@@ -1282,5 +1285,37 @@ module RubyLsp
|
|
1282
1285
|
|
1283
1286
|
addon.handle_window_show_message_response(result[:title])
|
1284
1287
|
end
|
1288
|
+
|
1289
|
+
sig { params(message: T::Hash[Symbol, T.untyped]).void }
|
1290
|
+
def compose_bundle(message)
|
1291
|
+
already_composed_path = File.join(@global_state.workspace_path, ".ruby-lsp", "bundle_is_composed")
|
1292
|
+
command = "#{Gem.ruby} #{File.expand_path("../../exe/ruby-lsp-launcher", __dir__)} #{@global_state.workspace_uri}"
|
1293
|
+
id = message[:id]
|
1294
|
+
|
1295
|
+
begin
|
1296
|
+
Bundler::LockfileParser.new(Bundler.default_lockfile.read)
|
1297
|
+
rescue Bundler::LockfileError => e
|
1298
|
+
send_message(Error.new(id: id, code: BUNDLE_COMPOSE_FAILED_CODE, message: e.message))
|
1299
|
+
return
|
1300
|
+
end
|
1301
|
+
|
1302
|
+
# We compose the bundle in a thread so that the LSP continues to work while we're checking for its validity. Once
|
1303
|
+
# we return the response back to the editor, then the restart is triggered
|
1304
|
+
Thread.new do
|
1305
|
+
send_log_message("Recomposing the bundle ahead of restart")
|
1306
|
+
pid = Process.spawn(command)
|
1307
|
+
_, status = Process.wait2(pid)
|
1308
|
+
|
1309
|
+
if status&.exitstatus == 0
|
1310
|
+
# Create a signal for the restart that it can skip composing the bundle and launch directly
|
1311
|
+
FileUtils.touch(already_composed_path)
|
1312
|
+
send_message(Result.new(id: id, response: { success: true }))
|
1313
|
+
else
|
1314
|
+
# This special error code makes the extension avoid restarting in case we already know that the composed
|
1315
|
+
# bundle is not valid
|
1316
|
+
send_message(Error.new(id: id, code: BUNDLE_COMPOSE_FAILED_CODE, message: "Failed to compose bundle"))
|
1317
|
+
end
|
1318
|
+
end
|
1319
|
+
end
|
1285
1320
|
end
|
1286
1321
|
end
|
@@ -57,6 +57,7 @@ module RubyLsp
|
|
57
57
|
@lockfile_hash_path = T.let(@custom_dir + "main_lockfile_hash", Pathname)
|
58
58
|
@last_updated_path = T.let(@custom_dir + "last_updated", Pathname)
|
59
59
|
@error_path = T.let(@custom_dir + "install_error", Pathname)
|
60
|
+
@already_composed_path = T.let(@custom_dir + "bundle_is_composed", Pathname)
|
60
61
|
|
61
62
|
dependencies, bundler_version = load_dependencies
|
62
63
|
@dependencies = T.let(dependencies, T::Hash[String, T.untyped])
|
@@ -71,6 +72,23 @@ module RubyLsp
|
|
71
72
|
def setup!
|
72
73
|
raise BundleNotLocked if !@launcher && @gemfile&.exist? && !@lockfile&.exist?
|
73
74
|
|
75
|
+
# If the bundle was composed ahead of time using our custom `rubyLsp/composeBundle` request, then we can skip the
|
76
|
+
# entire process and just return the composed environment
|
77
|
+
if @already_composed_path.exist?
|
78
|
+
$stderr.puts("Ruby LSP> Composed bundle was set up ahead of time. Skipping...")
|
79
|
+
@already_composed_path.delete
|
80
|
+
|
81
|
+
env = bundler_settings_as_env
|
82
|
+
env["BUNDLE_GEMFILE"] = @custom_gemfile.exist? ? @custom_gemfile.to_s : @gemfile.to_s
|
83
|
+
|
84
|
+
if env["BUNDLE_PATH"]
|
85
|
+
env["BUNDLE_PATH"] = File.expand_path(env["BUNDLE_PATH"], @project_path)
|
86
|
+
end
|
87
|
+
|
88
|
+
env["BUNDLER_VERSION"] = @bundler_version.to_s if @bundler_version
|
89
|
+
return env
|
90
|
+
end
|
91
|
+
|
74
92
|
# Automatically create and ignore the .ruby-lsp folder for users
|
75
93
|
@custom_dir.mkpath unless @custom_dir.exist?
|
76
94
|
ignore_file = @custom_dir + ".gitignore"
|
data/lib/ruby_lsp/utils.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-28 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: language_server-protocol
|
@@ -218,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
218
218
|
- !ruby/object:Gem::Version
|
219
219
|
version: '0'
|
220
220
|
requirements: []
|
221
|
-
rubygems_version: 3.6.
|
221
|
+
rubygems_version: 3.6.3
|
222
222
|
specification_version: 4
|
223
223
|
summary: An opinionated language server for Ruby
|
224
224
|
test_files: []
|