ruby-lsp 0.21.1 → 0.21.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c270ba4b6a7348ccb821e1bae776f4bd9ac704973b251791d2104d79861878c1
4
- data.tar.gz: 5d27d76eca727dca7e439aa177db04fb3ec17e1169c19a267ba2cffc8f9e19a3
3
+ metadata.gz: f580352765054aabd1821330dab6fa4ce5fb65746dee3a96640589a511a047f0
4
+ data.tar.gz: 41b51b6a3c13116b64a116f50337df14624088d8c50b2d5675c753b0ae612220
5
5
  SHA512:
6
- metadata.gz: 8502d09966be4e7ec79c276b4d078edc0f4e150c86ff24bb6e6f5b9c28e4f89393760983b7344c108e356a5bc79daa314806c69b81441338465b00f8bb693cc1
7
- data.tar.gz: 0d84c86826022c8e71311bef8070f8b5364cd45f10f242fcb5b8cf96f9dd391a9a45a034b264ee8b2cec236ce69257a1a102d9e769bbdf3b8c0dc9baff8650e9
6
+ metadata.gz: 6801b771e4aec3f493211f8b50c5c6e2998cd7d2ff1061bbc8e7afb83c87e653fcf7dfd23c3b41ec2fa65cd1d1eec3fab840a9188936904c08c6f2745c12c5a8
7
+ data.tar.gz: 9b68fee2853275c1343fa2815c6fe4263e6c90277b5e6567dfb84d4e0dd9d112353d77f18055384d9cb9aeb6a263ce8ec1b4b66f8b1eb2950f800aedf73fba3a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.21.1
1
+ 0.21.3
@@ -10,7 +10,8 @@ module RubyLsp
10
10
  sig { returns(T::Boolean) }
11
11
  attr_reader :supports_watching_files,
12
12
  :supports_request_delegation,
13
- :window_show_message_supports_extra_properties
13
+ :window_show_message_supports_extra_properties,
14
+ :supports_progress
14
15
 
15
16
  sig { void }
16
17
  def initialize
@@ -28,6 +29,9 @@ module RubyLsp
28
29
 
29
30
  # Which resource operations the editor supports, like renaming files
30
31
  @supported_resource_operations = T.let([], T::Array[String])
32
+
33
+ # The editor supports displaying progress requests
34
+ @supports_progress = T.let(false, T::Boolean)
31
35
  end
32
36
 
33
37
  sig { params(capabilities: T::Hash[Symbol, T.untyped]).void }
@@ -50,6 +54,9 @@ module RubyLsp
50
54
  :additionalPropertiesSupport,
51
55
  )
52
56
  @window_show_message_supports_extra_properties = supports_additional_properties || false
57
+
58
+ progress = capabilities.dig(:window, :workDoneProgress)
59
+ @supports_progress = progress if progress
53
60
  end
54
61
 
55
62
  sig { returns(T::Boolean) }
@@ -53,6 +53,7 @@ module RubyLsp
53
53
  T::Boolean,
54
54
  )
55
55
  @client_capabilities = T.let(ClientCapabilities.new, ClientCapabilities)
56
+ @enabled_feature_flags = T.let({}, T::Hash[Symbol, T::Boolean])
56
57
  end
57
58
 
58
59
  sig { params(addon_name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
@@ -139,9 +140,17 @@ module RubyLsp
139
140
  @addon_settings.merge!(addon_settings)
140
141
  end
141
142
 
143
+ enabled_flags = options.dig(:initializationOptions, :enabledFeatureFlags)
144
+ @enabled_feature_flags = enabled_flags if enabled_flags
145
+
142
146
  notifications
143
147
  end
144
148
 
149
+ sig { params(flag: Symbol).returns(T.nilable(T::Boolean)) }
150
+ def enabled_feature?(flag)
151
+ @enabled_feature_flags[flag]
152
+ end
153
+
145
154
  sig { returns(String) }
146
155
  def workspace_path
147
156
  T.must(@workspace_uri.to_standardized_path)
@@ -92,14 +92,15 @@ module RubyLsp
92
92
  target: T.nilable(Prism::Node),
93
93
  parent: T.nilable(Prism::Node),
94
94
  dispatcher: Prism::Dispatcher,
95
+ position: T::Hash[Symbol, T.untyped],
95
96
  ).void
96
97
  end
97
- def initialize(response_builder, target, parent, dispatcher)
98
+ def initialize(response_builder, target, parent, dispatcher, position)
98
99
  @response_builder = response_builder
99
100
 
100
101
  return unless target && parent
101
102
 
102
- highlight_target =
103
+ highlight_target, highlight_target_value =
103
104
  case target
104
105
  when Prism::GlobalVariableReadNode, Prism::GlobalVariableAndWriteNode, Prism::GlobalVariableOperatorWriteNode,
105
106
  Prism::GlobalVariableOrWriteNode, Prism::GlobalVariableTargetNode, Prism::GlobalVariableWriteNode,
@@ -116,13 +117,17 @@ module RubyLsp
116
117
  Prism::CallNode, Prism::BlockParameterNode, Prism::RequiredKeywordParameterNode,
117
118
  Prism::RequiredKeywordParameterNode, Prism::KeywordRestParameterNode, Prism::OptionalParameterNode,
118
119
  Prism::RequiredParameterNode, Prism::RestParameterNode
120
+ [target, node_value(target)]
121
+ when Prism::ModuleNode, Prism::ClassNode, Prism::SingletonClassNode, Prism::DefNode, Prism::CaseNode,
122
+ Prism::WhileNode, Prism::UntilNode, Prism::ForNode, Prism::IfNode, Prism::UnlessNode
119
123
  target
120
124
  end
121
125
 
122
126
  @target = T.let(highlight_target, T.nilable(Prism::Node))
123
- @target_value = T.let(node_value(highlight_target), T.nilable(String))
127
+ @target_value = T.let(highlight_target_value, T.nilable(String))
128
+ @target_position = position
124
129
 
125
- if @target && @target_value
130
+ if @target
126
131
  dispatcher.register(
127
132
  self,
128
133
  :on_call_node_enter,
@@ -172,6 +177,13 @@ module RubyLsp
172
177
  :on_global_variable_or_write_node_enter,
173
178
  :on_global_variable_and_write_node_enter,
174
179
  :on_global_variable_operator_write_node_enter,
180
+ :on_singleton_class_node_enter,
181
+ :on_case_node_enter,
182
+ :on_while_node_enter,
183
+ :on_until_node_enter,
184
+ :on_for_node_enter,
185
+ :on_if_node_enter,
186
+ :on_unless_node_enter,
175
187
  )
176
188
  end
177
189
  end
@@ -189,6 +201,8 @@ module RubyLsp
189
201
 
190
202
  sig { params(node: Prism::DefNode).void }
191
203
  def on_def_node_enter(node)
204
+ add_matching_end_highlights(node.def_keyword_loc, node.end_keyword_loc) if @target.is_a?(Prism::DefNode)
205
+
192
206
  return unless matches?(node, [Prism::CallNode, Prism::DefNode])
193
207
 
194
208
  add_highlight(Constant::DocumentHighlightKind::WRITE, node.name_loc)
@@ -252,6 +266,8 @@ module RubyLsp
252
266
 
253
267
  sig { params(node: Prism::ClassNode).void }
254
268
  def on_class_node_enter(node)
269
+ add_matching_end_highlights(node.class_keyword_loc, node.end_keyword_loc) if @target.is_a?(Prism::ClassNode)
270
+
255
271
  return unless matches?(node, CONSTANT_NODES + CONSTANT_PATH_NODES + [Prism::ClassNode])
256
272
 
257
273
  add_highlight(Constant::DocumentHighlightKind::WRITE, node.constant_path.location)
@@ -259,6 +275,8 @@ module RubyLsp
259
275
 
260
276
  sig { params(node: Prism::ModuleNode).void }
261
277
  def on_module_node_enter(node)
278
+ add_matching_end_highlights(node.module_keyword_loc, node.end_keyword_loc) if @target.is_a?(Prism::ModuleNode)
279
+
262
280
  return unless matches?(node, CONSTANT_NODES + CONSTANT_PATH_NODES + [Prism::ModuleNode])
263
281
 
264
282
  add_highlight(Constant::DocumentHighlightKind::WRITE, node.constant_path.location)
@@ -511,6 +529,55 @@ module RubyLsp
511
529
  add_highlight(Constant::DocumentHighlightKind::WRITE, node.name_loc)
512
530
  end
513
531
 
532
+ sig { params(node: Prism::SingletonClassNode).void }
533
+ def on_singleton_class_node_enter(node)
534
+ return unless @target.is_a?(Prism::SingletonClassNode)
535
+
536
+ add_matching_end_highlights(node.class_keyword_loc, node.end_keyword_loc)
537
+ end
538
+
539
+ sig { params(node: Prism::CaseNode).void }
540
+ def on_case_node_enter(node)
541
+ return unless @target.is_a?(Prism::CaseNode)
542
+
543
+ add_matching_end_highlights(node.case_keyword_loc, node.end_keyword_loc)
544
+ end
545
+
546
+ sig { params(node: Prism::WhileNode).void }
547
+ def on_while_node_enter(node)
548
+ return unless @target.is_a?(Prism::WhileNode)
549
+
550
+ add_matching_end_highlights(node.keyword_loc, node.closing_loc)
551
+ end
552
+
553
+ sig { params(node: Prism::UntilNode).void }
554
+ def on_until_node_enter(node)
555
+ return unless @target.is_a?(Prism::UntilNode)
556
+
557
+ add_matching_end_highlights(node.keyword_loc, node.closing_loc)
558
+ end
559
+
560
+ sig { params(node: Prism::ForNode).void }
561
+ def on_for_node_enter(node)
562
+ return unless @target.is_a?(Prism::ForNode)
563
+
564
+ add_matching_end_highlights(node.for_keyword_loc, node.end_keyword_loc)
565
+ end
566
+
567
+ sig { params(node: Prism::IfNode).void }
568
+ def on_if_node_enter(node)
569
+ return unless @target.is_a?(Prism::IfNode)
570
+
571
+ add_matching_end_highlights(node.if_keyword_loc, node.end_keyword_loc)
572
+ end
573
+
574
+ sig { params(node: Prism::UnlessNode).void }
575
+ def on_unless_node_enter(node)
576
+ return unless @target.is_a?(Prism::UnlessNode)
577
+
578
+ add_matching_end_highlights(node.keyword_loc, node.end_keyword_loc)
579
+ end
580
+
514
581
  private
515
582
 
516
583
  sig { params(node: Prism::Node, classes: T::Array[T.class_of(Prism::Node)]).returns(T.nilable(T::Boolean)) }
@@ -550,6 +617,26 @@ module RubyLsp
550
617
  node.constant_path.slice
551
618
  end
552
619
  end
620
+
621
+ sig { params(keyword_loc: T.nilable(Prism::Location), end_loc: T.nilable(Prism::Location)).void }
622
+ def add_matching_end_highlights(keyword_loc, end_loc)
623
+ return unless keyword_loc && end_loc && end_loc.length.positive?
624
+ return unless covers_target_position?(keyword_loc) || covers_target_position?(end_loc)
625
+
626
+ add_highlight(Constant::DocumentHighlightKind::TEXT, keyword_loc)
627
+ add_highlight(Constant::DocumentHighlightKind::TEXT, end_loc)
628
+ end
629
+
630
+ sig { params(location: Prism::Location).returns(T::Boolean) }
631
+ def covers_target_position?(location)
632
+ start_line = location.start_line - 1
633
+ end_line = location.end_line - 1
634
+ start_covered = start_line < @target_position[:line] ||
635
+ (start_line == @target_position[:line] && location.start_column <= @target_position[:character])
636
+ end_covered = end_line > @target_position[:line] ||
637
+ (end_line == @target_position[:line] && location.end_column >= @target_position[:character])
638
+ start_covered && end_covered
639
+ end
553
640
  end
554
641
  end
555
642
  end
@@ -38,7 +38,13 @@ module RubyLsp
38
38
  ResponseBuilders::CollectionResponseBuilder[Interface::DocumentHighlight].new,
39
39
  ResponseBuilders::CollectionResponseBuilder[Interface::DocumentHighlight],
40
40
  )
41
- Listeners::DocumentHighlight.new(@response_builder, node_context.node, node_context.parent, dispatcher)
41
+ Listeners::DocumentHighlight.new(
42
+ @response_builder,
43
+ node_context.node,
44
+ node_context.parent,
45
+ dispatcher,
46
+ position,
47
+ )
42
48
  end
43
49
 
44
50
  sig { override.returns(T::Array[Interface::DocumentHighlight]) }
@@ -81,8 +81,6 @@ module RubyLsp
81
81
  workspace_did_change_watched_files(message)
82
82
  when "workspace/symbol"
83
83
  workspace_symbol(message)
84
- when "window/showMessageRequest"
85
- window_show_message_request(message)
86
84
  when "rubyLsp/textDocument/showSyntaxTree"
87
85
  text_document_show_syntax_tree(message)
88
86
  when "rubyLsp/workspace/dependencies"
@@ -108,6 +106,8 @@ module RubyLsp
108
106
  )
109
107
  when "$/cancelRequest"
110
108
  @mutex.synchronize { @cancelled_requests << message[:params][:id] }
109
+ when nil
110
+ process_response(message) if message[:result]
111
111
  end
112
112
  rescue DelegateRequestError
113
113
  send_message(Error.new(id: message[:id], code: DelegateRequestError::CODE, message: "DELEGATE_REQUEST"))
@@ -140,6 +140,15 @@ module RubyLsp
140
140
  send_log_message("Error processing #{message[:method]}: #{e.full_message}", type: Constant::MessageType::ERROR)
141
141
  end
142
142
 
143
+ # Process responses to requests that were sent to the client
144
+ sig { params(message: T::Hash[Symbol, T.untyped]).void }
145
+ def process_response(message)
146
+ case message.dig(:result, :method)
147
+ when "window/showMessageRequest"
148
+ window_show_message_request(message)
149
+ end
150
+ end
151
+
143
152
  sig { params(include_project_addons: T::Boolean).void }
144
153
  def load_addons(include_project_addons: true)
145
154
  # If invoking Bundler.setup failed, then the load path will not be configured properly and trying to load add-ons
@@ -188,8 +197,6 @@ module RubyLsp
188
197
  client_name = options.dig(:clientInfo, :name)
189
198
  @store.client_name = client_name if client_name
190
199
 
191
- progress = options.dig(:capabilities, :window, :workDoneProgress)
192
- @store.supports_progress = progress.nil? ? true : progress
193
200
  configured_features = options.dig(:initializationOptions, :enabledFeatures)
194
201
 
195
202
  configured_hints = options.dig(:initializationOptions, :featuresConfiguration, :inlayHint)
@@ -1105,7 +1112,7 @@ module RubyLsp
1105
1112
 
1106
1113
  sig { params(id: String, title: String, percentage: Integer).void }
1107
1114
  def begin_progress(id, title, percentage: 0)
1108
- return unless @store.supports_progress
1115
+ return unless @global_state.client_capabilities.supports_progress
1109
1116
 
1110
1117
  send_message(Request.new(
1111
1118
  id: @current_request_id,
@@ -1113,52 +1120,21 @@ module RubyLsp
1113
1120
  params: Interface::WorkDoneProgressCreateParams.new(token: id),
1114
1121
  ))
1115
1122
 
1116
- send_message(Notification.new(
1117
- method: "$/progress",
1118
- params: Interface::ProgressParams.new(
1119
- token: id,
1120
- value: Interface::WorkDoneProgressBegin.new(
1121
- kind: "begin",
1122
- title: title,
1123
- percentage: percentage,
1124
- message: "#{percentage}% completed",
1125
- ),
1126
- ),
1127
- ))
1123
+ send_message(Notification.progress_begin(id, title, percentage: percentage, message: "#{percentage}% completed"))
1128
1124
  end
1129
1125
 
1130
1126
  sig { params(id: String, percentage: Integer).void }
1131
1127
  def progress(id, percentage)
1132
- return unless @store.supports_progress
1128
+ return unless @global_state.client_capabilities.supports_progress
1133
1129
 
1134
- send_message(
1135
- Notification.new(
1136
- method: "$/progress",
1137
- params: Interface::ProgressParams.new(
1138
- token: id,
1139
- value: Interface::WorkDoneProgressReport.new(
1140
- kind: "report",
1141
- percentage: percentage,
1142
- message: "#{percentage}% completed",
1143
- ),
1144
- ),
1145
- ),
1146
- )
1130
+ send_message(Notification.progress_report(id, percentage: percentage, message: "#{percentage}% completed"))
1147
1131
  end
1148
1132
 
1149
1133
  sig { params(id: String).void }
1150
1134
  def end_progress(id)
1151
- return unless @store.supports_progress
1135
+ return unless @global_state.client_capabilities.supports_progress
1152
1136
 
1153
- send_message(
1154
- Notification.new(
1155
- method: "$/progress",
1156
- params: Interface::ProgressParams.new(
1157
- token: id,
1158
- value: Interface::WorkDoneProgressEnd.new(kind: "end"),
1159
- ),
1160
- ),
1161
- )
1137
+ send_message(Notification.progress_end(id))
1162
1138
  rescue ClosedQueueError
1163
1139
  # If the server was killed and the message queue is already closed, there's no way to end the progress
1164
1140
  # notification
@@ -1226,11 +1202,14 @@ module RubyLsp
1226
1202
 
1227
1203
  sig { params(message: T::Hash[Symbol, T.untyped]).void }
1228
1204
  def window_show_message_request(message)
1229
- addon_name = message[:addon_name]
1205
+ result = message[:result]
1206
+ return unless result
1207
+
1208
+ addon_name = result[:addon_name]
1230
1209
  addon = Addon.addons.find { |addon| addon.name == addon_name }
1231
1210
  return unless addon
1232
1211
 
1233
- addon.handle_window_show_message_response(message[:title])
1212
+ addon.handle_window_show_message_response(result[:title])
1234
1213
  end
1235
1214
  end
1236
1215
  end
@@ -7,9 +7,6 @@ module RubyLsp
7
7
 
8
8
  class NonExistingDocumentError < StandardError; end
9
9
 
10
- sig { returns(T::Boolean) }
11
- attr_accessor :supports_progress
12
-
13
10
  sig { returns(T::Hash[Symbol, RequestConfig]) }
14
11
  attr_accessor :features_configuration
15
12
 
@@ -19,7 +16,6 @@ module RubyLsp
19
16
  sig { void }
20
17
  def initialize
21
18
  @state = T.let({}, T::Hash[String, Document[T.untyped]])
22
- @supports_progress = T.let(true, T::Boolean)
23
19
  @features_configuration = T.let(
24
20
  {
25
21
  inlayHint: RequestConfig.new({
@@ -87,6 +87,61 @@ module RubyLsp
87
87
  params: data,
88
88
  )
89
89
  end
90
+
91
+ sig do
92
+ params(
93
+ id: String,
94
+ title: String,
95
+ percentage: T.nilable(Integer),
96
+ message: T.nilable(String),
97
+ ).returns(Notification)
98
+ end
99
+ def progress_begin(id, title, percentage: nil, message: nil)
100
+ new(
101
+ method: "$/progress",
102
+ params: Interface::ProgressParams.new(
103
+ token: id,
104
+ value: Interface::WorkDoneProgressBegin.new(
105
+ kind: "begin",
106
+ title: title,
107
+ percentage: percentage,
108
+ message: message,
109
+ ),
110
+ ),
111
+ )
112
+ end
113
+
114
+ sig do
115
+ params(
116
+ id: String,
117
+ percentage: T.nilable(Integer),
118
+ message: T.nilable(String),
119
+ ).returns(Notification)
120
+ end
121
+ def progress_report(id, percentage: nil, message: nil)
122
+ new(
123
+ method: "$/progress",
124
+ params: Interface::ProgressParams.new(
125
+ token: id,
126
+ value: Interface::WorkDoneProgressReport.new(
127
+ kind: "report",
128
+ percentage: percentage,
129
+ message: message,
130
+ ),
131
+ ),
132
+ )
133
+ end
134
+
135
+ sig { params(id: String).returns(Notification) }
136
+ def progress_end(id)
137
+ Notification.new(
138
+ method: "$/progress",
139
+ params: Interface::ProgressParams.new(
140
+ token: id,
141
+ value: Interface::WorkDoneProgressEnd.new(kind: "end"),
142
+ ),
143
+ )
144
+ end
90
145
  end
91
146
 
92
147
  extend T::Sig
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.21.1
4
+ version: 0.21.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-10-31 00:00:00.000000000 Z
11
+ date: 2024-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: language_server-protocol