-
Notifications
You must be signed in to change notification settings - Fork 183
/
Copy pathselection_ranges.rb
53 lines (47 loc) · 1.67 KB
/
selection_ranges.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# typed: strict
# frozen_string_literal: true
module RubyLsp
module Requests
# 
#
# The [selection ranges](https://microsoft.github.io/language-server-protocol/specification#textDocument_selectionRange)
# request informs the editor of ranges that the user may want to select based on the location(s)
# of their cursor(s).
#
# Trigger this request with: Ctrl + Shift + -> or Ctrl + Shift + <-
#
# Note that if using VSCode Neovim, you will need to be in Insert mode for this to work correctly.
#
# # Example
#
# ```ruby
# def foo # --> The next selection range encompasses the entire method definition.
# puts "Hello, world!" # --> Cursor is on this line
# end
# ```
class SelectionRanges < Request
extend T::Sig
include Support::Common
sig { params(document: T.any(RubyDocument, ERBDocument)).void }
def initialize(document)
super()
@document = document
@ranges = T.let([], T::Array[Support::SelectionRange])
@stack = T.let([], T::Array[Support::SelectionRange])
end
sig { override.returns(T.all(T::Array[Support::SelectionRange], Object)) }
def perform
# [node, parent]
queue = [[@document.parse_result.value, nil]]
until queue.empty?
node, parent = queue.shift
next unless node
range = Support::SelectionRange.new(range: range_from_location(node.location), parent: parent)
T.unsafe(queue).unshift(*node.child_nodes.map { |child| [child, range] })
@ranges.unshift(range)
end
@ranges
end
end
end
end