@@ -92,14 +92,15 @@ class DocumentHighlight
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 @@ def initialize(response_builder, target, parent, dispatcher)
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 @@ def initialize(response_builder, target, parent, dispatcher)
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 @@ def on_call_node_enter(node)
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,13 +266,17 @@ def on_required_parameter_node_enter(node)
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 )
258
274
end
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 @@ def on_global_variable_operator_write_node_enter(node)
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 @@ def node_value(node)
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
0 commit comments