ruby-lsp-rails 0.3.27 → 0.3.31
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/lib/ruby-lsp-rails.rb +0 -12
- data/lib/ruby_lsp/ruby_lsp_rails/addon.rb +30 -6
- data/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb +3 -3
- data/lib/ruby_lsp/ruby_lsp_rails/completion.rb +92 -0
- data/lib/ruby_lsp/ruby_lsp_rails/definition.rb +2 -8
- data/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb +3 -1
- data/lib/ruby_lsp/ruby_lsp_rails/server.rb +14 -4
- data/lib/ruby_lsp_rails/version.rb +1 -1
- metadata +8 -11
- data/lib/ruby_lsp_rails/railtie.rb +0 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b1d9f0d516dcad6d833e05e05defd6ba7ea0bbb3fb2b0c48e7edb9709306d854
|
|
4
|
+
data.tar.gz: 41b2f9dec0e1ba1d3d4d92a5eb1b4ad5dfd6b6d8c3e62b69822ac156f3232bfd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4421fb81f4cffaa89abe05244ec8bcc2da8ffa0e27b5f7c310c49747d7b2e20a6eec85b58dfe77f5107bd8281ca9d2e61a5f70b2d100c5938f4a2932deedfd0
|
|
7
|
+
data.tar.gz: aa8476c6f72a66782d9d8b3225944c862f708cd9fc60fd17cf871d9f3332885bd0b7060cbf778710e9213686d5e24c1e415327c14a00a738e28f934dfae156c7
|
data/lib/ruby-lsp-rails.rb
CHANGED
|
@@ -2,15 +2,3 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "ruby_lsp_rails/version"
|
|
5
|
-
require "ruby_lsp_rails/railtie"
|
|
6
|
-
|
|
7
|
-
module RubyLsp
|
|
8
|
-
# # Supported features
|
|
9
|
-
#
|
|
10
|
-
# - [Hover](rdoc-ref:RubyLsp::Rails::Hover)
|
|
11
|
-
# - [CodeLens](rdoc-ref:RubyLsp::Rails::CodeLens)
|
|
12
|
-
# - [DocumentSymbol](rdoc-ref:RubyLsp::Rails::DocumentSymbol)
|
|
13
|
-
# - [Definition](rdoc-ref:RubyLsp::Rails::Definition)
|
|
14
|
-
module Rails
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -13,6 +13,7 @@ require_relative "hover"
|
|
|
13
13
|
require_relative "code_lens"
|
|
14
14
|
require_relative "document_symbol"
|
|
15
15
|
require_relative "definition"
|
|
16
|
+
require_relative "completion"
|
|
16
17
|
require_relative "indexing_enhancement"
|
|
17
18
|
|
|
18
19
|
module RubyLsp
|
|
@@ -119,6 +120,18 @@ module RubyLsp
|
|
|
119
120
|
Definition.new(@rails_runner_client, response_builder, node_context, index, dispatcher)
|
|
120
121
|
end
|
|
121
122
|
|
|
123
|
+
sig do
|
|
124
|
+
override.params(
|
|
125
|
+
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
|
|
126
|
+
node_context: NodeContext,
|
|
127
|
+
dispatcher: Prism::Dispatcher,
|
|
128
|
+
uri: URI::Generic,
|
|
129
|
+
).void
|
|
130
|
+
end
|
|
131
|
+
def create_completion_listener(response_builder, node_context, dispatcher, uri)
|
|
132
|
+
Completion.new(@rails_runner_client, response_builder, node_context, dispatcher, uri)
|
|
133
|
+
end
|
|
134
|
+
|
|
122
135
|
sig { params(changes: T::Array[{ uri: String, type: Integer }]).void }
|
|
123
136
|
def workspace_did_change_watched_files(changes)
|
|
124
137
|
if changes.any? { |c| c[:uri].end_with?("db/schema.rb") || c[:uri].end_with?("structure.sql") }
|
|
@@ -210,12 +223,7 @@ module RubyLsp
|
|
|
210
223
|
id: "workspace/didChangeWatchedFilesRails",
|
|
211
224
|
method: "workspace/didChangeWatchedFiles",
|
|
212
225
|
register_options: Interface::DidChangeWatchedFilesRegistrationOptions.new(
|
|
213
|
-
watchers: [
|
|
214
|
-
Interface::FileSystemWatcher.new(
|
|
215
|
-
glob_pattern: "**/*structure.sql",
|
|
216
|
-
kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE,
|
|
217
|
-
),
|
|
218
|
-
],
|
|
226
|
+
watchers: [structure_sql_file_watcher, fixture_file_watcher],
|
|
219
227
|
),
|
|
220
228
|
),
|
|
221
229
|
],
|
|
@@ -223,6 +231,22 @@ module RubyLsp
|
|
|
223
231
|
)
|
|
224
232
|
end
|
|
225
233
|
|
|
234
|
+
sig { returns(Interface::FileSystemWatcher) }
|
|
235
|
+
def structure_sql_file_watcher
|
|
236
|
+
Interface::FileSystemWatcher.new(
|
|
237
|
+
glob_pattern: "**/*structure.sql",
|
|
238
|
+
kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE,
|
|
239
|
+
)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
sig { returns(Interface::FileSystemWatcher) }
|
|
243
|
+
def fixture_file_watcher
|
|
244
|
+
Interface::FileSystemWatcher.new(
|
|
245
|
+
glob_pattern: "**/fixtures/**/*.{yml,yaml,yml.erb,yaml.erb}",
|
|
246
|
+
kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE,
|
|
247
|
+
)
|
|
248
|
+
end
|
|
249
|
+
|
|
226
250
|
sig { void }
|
|
227
251
|
def offer_to_run_pending_migrations
|
|
228
252
|
return unless @outgoing_queue
|
|
@@ -254,7 +254,7 @@ module RubyLsp
|
|
|
254
254
|
|
|
255
255
|
@response_builder << create_code_lens(
|
|
256
256
|
node,
|
|
257
|
-
title: "Run",
|
|
257
|
+
title: "▶ Run",
|
|
258
258
|
command_name: "rubyLsp.runTask",
|
|
259
259
|
arguments: [command],
|
|
260
260
|
data: { type: "migrate" },
|
|
@@ -283,7 +283,7 @@ module RubyLsp
|
|
|
283
283
|
|
|
284
284
|
@response_builder << create_code_lens(
|
|
285
285
|
node,
|
|
286
|
-
title: "Run",
|
|
286
|
+
title: "▶ Run",
|
|
287
287
|
command_name: "rubyLsp.runTest",
|
|
288
288
|
arguments: arguments,
|
|
289
289
|
data: { type: "test", **grouping_data },
|
|
@@ -291,7 +291,7 @@ module RubyLsp
|
|
|
291
291
|
|
|
292
292
|
@response_builder << create_code_lens(
|
|
293
293
|
node,
|
|
294
|
-
title: "Run In Terminal",
|
|
294
|
+
title: "▶ Run In Terminal",
|
|
295
295
|
command_name: "rubyLsp.runTestInTerminal",
|
|
296
296
|
arguments: arguments,
|
|
297
297
|
data: { type: "test_in_terminal", **grouping_data },
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module RubyLsp
|
|
5
|
+
module Rails
|
|
6
|
+
class Completion
|
|
7
|
+
extend T::Sig
|
|
8
|
+
include Requests::Support::Common
|
|
9
|
+
|
|
10
|
+
sig do
|
|
11
|
+
override.params(
|
|
12
|
+
client: RunnerClient,
|
|
13
|
+
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
|
|
14
|
+
node_context: NodeContext,
|
|
15
|
+
dispatcher: Prism::Dispatcher,
|
|
16
|
+
uri: URI::Generic,
|
|
17
|
+
).void
|
|
18
|
+
end
|
|
19
|
+
def initialize(client, response_builder, node_context, dispatcher, uri)
|
|
20
|
+
@response_builder = response_builder
|
|
21
|
+
@client = client
|
|
22
|
+
@node_context = node_context
|
|
23
|
+
dispatcher.register(
|
|
24
|
+
self,
|
|
25
|
+
:on_call_node_enter,
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
sig { params(node: Prism::CallNode).void }
|
|
30
|
+
def on_call_node_enter(node)
|
|
31
|
+
call_node = @node_context.call_node
|
|
32
|
+
return unless call_node
|
|
33
|
+
|
|
34
|
+
receiver = call_node.receiver
|
|
35
|
+
if call_node.name == :where && receiver.is_a?(Prism::ConstantReadNode)
|
|
36
|
+
handle_active_record_where_completions(node: node, receiver: receiver)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
sig { params(node: Prism::CallNode, receiver: Prism::ConstantReadNode).void }
|
|
43
|
+
def handle_active_record_where_completions(node:, receiver:)
|
|
44
|
+
resolved_class = @client.model(receiver.name.to_s)
|
|
45
|
+
return if resolved_class.nil?
|
|
46
|
+
|
|
47
|
+
arguments = T.must(@node_context.call_node).arguments&.arguments
|
|
48
|
+
indexed_call_node_args = T.let({}, T::Hash[String, Prism::Node])
|
|
49
|
+
|
|
50
|
+
if arguments
|
|
51
|
+
indexed_call_node_args = index_call_node_args(arguments: arguments)
|
|
52
|
+
return if indexed_call_node_args.values.any? { |v| v == node }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
range = range_from_location(node.location)
|
|
56
|
+
|
|
57
|
+
resolved_class[:columns].each do |column|
|
|
58
|
+
next unless column[0].start_with?(node.name.to_s)
|
|
59
|
+
next if indexed_call_node_args.key?(column[0])
|
|
60
|
+
|
|
61
|
+
@response_builder << Interface::CompletionItem.new(
|
|
62
|
+
label: column[0],
|
|
63
|
+
filter_text: column[0],
|
|
64
|
+
label_details: Interface::CompletionItemLabelDetails.new(
|
|
65
|
+
description: "Filter #{receiver.name} records by #{column[0]}",
|
|
66
|
+
),
|
|
67
|
+
text_edit: Interface::TextEdit.new(range: range, new_text: "#{column[0]}: "),
|
|
68
|
+
kind: Constant::CompletionItemKind::FIELD,
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
sig { params(arguments: T::Array[Prism::Node]).returns(T::Hash[String, Prism::Node]) }
|
|
74
|
+
def index_call_node_args(arguments:)
|
|
75
|
+
indexed_call_node_args = {}
|
|
76
|
+
arguments.each do |argument|
|
|
77
|
+
next unless argument.is_a?(Prism::KeywordHashNode)
|
|
78
|
+
|
|
79
|
+
argument.elements.each do |e|
|
|
80
|
+
next unless e.is_a?(Prism::AssocNode)
|
|
81
|
+
|
|
82
|
+
key = e.key
|
|
83
|
+
if key.is_a?(Prism::SymbolNode)
|
|
84
|
+
indexed_call_node_args[key.value] = e.value
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
indexed_call_node_args
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -144,15 +144,9 @@ module RubyLsp
|
|
|
144
144
|
return unless methods
|
|
145
145
|
|
|
146
146
|
methods.each do |target_method|
|
|
147
|
-
location = target_method.location
|
|
148
|
-
file_path = target_method.file_path
|
|
149
|
-
|
|
150
147
|
@response_builder << Interface::Location.new(
|
|
151
|
-
uri:
|
|
152
|
-
range:
|
|
153
|
-
start: Interface::Position.new(line: location.start_line - 1, character: location.start_column),
|
|
154
|
-
end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
|
|
155
|
-
),
|
|
148
|
+
uri: target_method.uri.to_s,
|
|
149
|
+
range: range_from_location(target_method.location),
|
|
156
150
|
)
|
|
157
151
|
end
|
|
158
152
|
end
|
|
@@ -105,6 +105,8 @@ module RubyLsp
|
|
|
105
105
|
while (content = @stderr.gets("\n"))
|
|
106
106
|
log_message(content, type: RubyLsp::Constant::MessageType::LOG)
|
|
107
107
|
end
|
|
108
|
+
rescue IOError
|
|
109
|
+
# The server was shutdown and stderr is already closed
|
|
108
110
|
end,
|
|
109
111
|
Thread,
|
|
110
112
|
)
|
|
@@ -281,7 +283,7 @@ module RubyLsp
|
|
|
281
283
|
json = message.to_json
|
|
282
284
|
|
|
283
285
|
@mutex.synchronize do
|
|
284
|
-
@stdin.write("Content-Length: #{json.
|
|
286
|
+
@stdin.write("Content-Length: #{json.bytesize}\r\n\r\n", json)
|
|
285
287
|
end
|
|
286
288
|
rescue Errno::EPIPE
|
|
287
289
|
# The server connection died
|
|
@@ -4,16 +4,13 @@
|
|
|
4
4
|
require "json"
|
|
5
5
|
require "open3"
|
|
6
6
|
|
|
7
|
-
# NOTE: We should avoid printing to stderr since it causes problems. We never read the standard error pipe from the
|
|
8
|
-
# client, so it will become full and eventually hang or crash. Instead, return a response with an `error` key.
|
|
9
|
-
|
|
10
7
|
module RubyLsp
|
|
11
8
|
module Rails
|
|
12
9
|
module Common
|
|
13
10
|
# Write a message to the client. Can be used for sending notifications to the editor
|
|
14
11
|
def send_message(message)
|
|
15
12
|
json_message = message.to_json
|
|
16
|
-
@stdout.write("Content-Length: #{json_message.
|
|
13
|
+
@stdout.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
# Log a message to the editor's output panel
|
|
@@ -125,6 +122,7 @@ module RubyLsp
|
|
|
125
122
|
|
|
126
123
|
def start
|
|
127
124
|
load_routes
|
|
125
|
+
clear_file_system_resolver_hooks
|
|
128
126
|
send_result({ message: "ok", root: ::Rails.root.to_s })
|
|
129
127
|
|
|
130
128
|
while @running
|
|
@@ -302,6 +300,18 @@ module RubyLsp
|
|
|
302
300
|
routes_reloader.execute_unless_loaded if routes_reloader&.respond_to?(:execute_unless_loaded)
|
|
303
301
|
end
|
|
304
302
|
end
|
|
303
|
+
|
|
304
|
+
# File system resolver hooks spawn file watcher threads which introduce unnecessary overhead since the LSP already
|
|
305
|
+
# watches files. Since the Rails application is already booted by the time we reach this script, we can't no-op
|
|
306
|
+
# the file watcher implementation. Instead, we clear the hooks to prevent the registered file watchers from being
|
|
307
|
+
# instantiated
|
|
308
|
+
def clear_file_system_resolver_hooks
|
|
309
|
+
return unless defined?(::ActionView::PathRegistry)
|
|
310
|
+
|
|
311
|
+
with_notification_error_handling("clear_file_system_resolver_hooks") do
|
|
312
|
+
::ActionView::PathRegistry.file_system_resolver_hooks.clear
|
|
313
|
+
end
|
|
314
|
+
end
|
|
305
315
|
end
|
|
306
316
|
end
|
|
307
317
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-lsp-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.31
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2025-01-23 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: ruby-lsp
|
|
@@ -16,20 +15,20 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.
|
|
18
|
+
version: 0.23.0
|
|
20
19
|
- - "<"
|
|
21
20
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: 0.
|
|
21
|
+
version: 0.24.0
|
|
23
22
|
type: :runtime
|
|
24
23
|
prerelease: false
|
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
25
|
requirements:
|
|
27
26
|
- - ">="
|
|
28
27
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: 0.
|
|
28
|
+
version: 0.23.0
|
|
30
29
|
- - "<"
|
|
31
30
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.
|
|
31
|
+
version: 0.24.0
|
|
33
32
|
description: A Ruby LSP addon that adds extra editor functionality for Rails applications
|
|
34
33
|
email:
|
|
35
34
|
- ruby@shopify.com
|
|
@@ -43,6 +42,7 @@ files:
|
|
|
43
42
|
- lib/ruby-lsp-rails.rb
|
|
44
43
|
- lib/ruby_lsp/ruby_lsp_rails/addon.rb
|
|
45
44
|
- lib/ruby_lsp/ruby_lsp_rails/code_lens.rb
|
|
45
|
+
- lib/ruby_lsp/ruby_lsp_rails/completion.rb
|
|
46
46
|
- lib/ruby_lsp/ruby_lsp_rails/definition.rb
|
|
47
47
|
- lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb
|
|
48
48
|
- lib/ruby_lsp/ruby_lsp_rails/hover.rb
|
|
@@ -53,7 +53,6 @@ files:
|
|
|
53
53
|
- lib/ruby_lsp/ruby_lsp_rails/support/associations.rb
|
|
54
54
|
- lib/ruby_lsp/ruby_lsp_rails/support/callbacks.rb
|
|
55
55
|
- lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb
|
|
56
|
-
- lib/ruby_lsp_rails/railtie.rb
|
|
57
56
|
- lib/ruby_lsp_rails/version.rb
|
|
58
57
|
- lib/tasks/ruby_lsp_rails_tasks.rake
|
|
59
58
|
homepage: https://github.com/Shopify/ruby-lsp-rails
|
|
@@ -65,7 +64,6 @@ metadata:
|
|
|
65
64
|
source_code_uri: https://github.com/Shopify/ruby-lsp-rails
|
|
66
65
|
changelog_uri: https://github.com/Shopify/ruby-lsp-rails/releases
|
|
67
66
|
documentation_uri: https://shopify.github.io/ruby-lsp/rails-add-on.html
|
|
68
|
-
post_install_message:
|
|
69
67
|
rdoc_options: []
|
|
70
68
|
require_paths:
|
|
71
69
|
- lib
|
|
@@ -80,8 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
80
78
|
- !ruby/object:Gem::Version
|
|
81
79
|
version: '0'
|
|
82
80
|
requirements: []
|
|
83
|
-
rubygems_version: 3.
|
|
84
|
-
signing_key:
|
|
81
|
+
rubygems_version: 3.6.2
|
|
85
82
|
specification_version: 4
|
|
86
83
|
summary: A Ruby LSP addon for Rails
|
|
87
84
|
test_files: []
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# typed: strict
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "rails"
|
|
5
|
-
|
|
6
|
-
module RubyLsp
|
|
7
|
-
module Rails
|
|
8
|
-
class Railtie < ::Rails::Railtie
|
|
9
|
-
config.ruby_lsp_rails = ActiveSupport::OrderedOptions.new
|
|
10
|
-
|
|
11
|
-
initializer "ruby_lsp_rails.setup" do |_app|
|
|
12
|
-
config.after_initialize do |_app|
|
|
13
|
-
unless config.ruby_lsp_rails.server.nil?
|
|
14
|
-
ActiveSupport::Deprecation.new.warn("The `ruby_lsp_rails.server` configuration option is no longer " \
|
|
15
|
-
"needed and will be removed in a future release.")
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|