Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/ruby_lsp/requests/base_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def run; end
# Syntax Tree implements `visit_all` using `map` instead of `each` for users who want to use the pattern
# `result = visitor.visit(tree)`. However, we don't use that pattern and should avoid producing a new array for
# every single node visited
sig { params(nodes: T::Array[T.nilable(SyntaxTree::Node)]).void }
sig { params(nodes: T::Array[T.nilable(YARP::Node)]).void }
def visit_all(nodes)
nodes.each { |node| visit(node) }
end
Expand Down
105 changes: 65 additions & 40 deletions lib/ruby_lsp/requests/selection_ranges.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,41 +25,37 @@ class SelectionRanges < BaseRequest

NODES_THAT_CAN_BE_PARENTS = T.let(
[
SyntaxTree::Assign,
SyntaxTree::ArrayLiteral,
SyntaxTree::Begin,
SyntaxTree::BlockNode,
SyntaxTree::CallNode,
SyntaxTree::Case,
SyntaxTree::ClassDeclaration,
SyntaxTree::Command,
SyntaxTree::DefNode,
SyntaxTree::Elsif,
SyntaxTree::Else,
SyntaxTree::EmbDoc,
SyntaxTree::Ensure,
SyntaxTree::For,
SyntaxTree::HashLiteral,
SyntaxTree::Heredoc,
SyntaxTree::HeredocBeg,
SyntaxTree::HshPtn,
SyntaxTree::IfNode,
SyntaxTree::In,
SyntaxTree::Lambda,
SyntaxTree::MethodAddBlock,
SyntaxTree::ModuleDeclaration,
SyntaxTree::Params,
SyntaxTree::Rescue,
SyntaxTree::RescueEx,
SyntaxTree::StringConcat,
SyntaxTree::StringLiteral,
SyntaxTree::UnlessNode,
SyntaxTree::UntilNode,
SyntaxTree::VCall,
SyntaxTree::When,
SyntaxTree::WhileNode,
YARP::ArgumentsNode,
YARP::ArrayNode,
YARP::AssocNode,
YARP::BeginNode,
YARP::BlockNode,
YARP::CallNode,
YARP::CaseNode,
YARP::ClassNode,
YARP::DefNode,
YARP::ElseNode,
YARP::EnsureNode,
YARP::ForNode,
YARP::HashNode,
YARP::HashPatternNode,
YARP::IfNode,
YARP::InNode,
YARP::InterpolatedStringNode,
YARP::KeywordHashNode,
YARP::LambdaNode,
YARP::LocalVariableWriteNode,
YARP::ModuleNode,
YARP::ParametersNode,
YARP::RescueNode,
YARP::StringConcatNode,
YARP::StringNode,
YARP::UnlessNode,
YARP::UntilNode,
YARP::WhenNode,
YARP::WhileNode,
].freeze,
T::Array[T.class_of(SyntaxTree::Node)],
T::Array[T.class_of(YARP::Node)],
)

sig { params(document: Document).void }
Expand All @@ -72,19 +68,23 @@ def initialize(document)

sig { override.returns(T.all(T::Array[Support::SelectionRange], Object)) }
def run
visit(@document.tree) if @document.parsed?
visit(@document.tree)
@ranges.reverse!
end

private

sig { override.params(node: T.nilable(SyntaxTree::Node)).void }
sig { override.params(node: T.nilable(YARP::Node)).void }
def visit(node)
return if node.nil?

range = create_selection_range(node.location, @stack.last)

range = if node.is_a?(YARP::InterpolatedStringNode)
create_heredoc_selection_range(node, @stack.last)
else
create_selection_range(node.location, @stack.last)
end
@ranges << range

return if node.child_nodes.empty?

@stack << range if NODES_THAT_CAN_BE_PARENTS.include?(node.class)
Expand All @@ -94,11 +94,36 @@ def visit(node)

sig do
params(
location: SyntaxTree::Location,
node: YARP::InterpolatedStringNode,
parent: T.nilable(Support::SelectionRange),
).returns(Support::SelectionRange)
end
def create_heredoc_selection_range(node, parent)
opening_loc = node.opening_loc
closing_loc = node.closing_loc

RubyLsp::Requests::Support::SelectionRange.new(
range: Interface::Range.new(
start: Interface::Position.new(
line: opening_loc.start_line - 1,
character: opening_loc.start_column,
),
end: Interface::Position.new(
line: closing_loc.end_line - 1,
character: closing_loc.end_column,
),
),
parent: parent,
)
end

sig do
params(
location: YARP::Location,
parent: T.nilable(Support::SelectionRange),
).returns(Support::SelectionRange)
end
def create_selection_range(location, parent = nil)
def create_selection_range(location, parent)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the unnecessary nil default for parent since we always pass something.

RubyLsp::Requests::Support::SelectionRange.new(
range: Interface::Range.new(
start: Interface::Position.new(
Expand Down
9 changes: 5 additions & 4 deletions lib/ruby_lsp/requests/support/selection_range.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ class SelectionRange < Interface::SelectionRange

sig { params(position: Document::PositionShape).returns(T::Boolean) }
def cover?(position)
line_range = (range.start.line..range.end.line)
character_range = (range.start.character..range.end.character)

line_range.cover?(position[:line]) && character_range.cover?(position[:character])
start_covered = range.start.line < position[:line] ||
(range.start.line == position[:line] && range.start.character <= position[:character])
end_covered = range.end.line > position[:line] ||
(range.end.line == position[:line] && range.end.character >= position[:character])
start_covered && end_covered
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"end": {
"line": 0,
"character": 6

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end columns are off by 1 due to a YARP issue which is being addressed separately.

"character": 5
}
},
"parent": {
Expand All @@ -25,7 +25,7 @@
},
"end": {
"line": 0,
"character": 10
"character": 9
}
},
"parent": {
Expand All @@ -36,7 +36,7 @@
},
"end": {
"line": 0,
"character": 10
"character": 9
}
}
}
Expand Down
32 changes: 10 additions & 22 deletions test/expectations/selection_ranges/begin_rescue_ensure.exp.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,40 @@
},
"end": {
"line": 5,
"character": 6
"character": 17
}
},
"parent": {
"range": {
"start": {
"line": 5,
"character": 2
"line": 4,
"character": 0
},
"end": {
"line": 5,
"character": 18
"character": 17
}
},
"parent": {
"range": {
"start": {
"line": 4,
"line": 2,
"character": 0
},
"end": {
"line": 6,
"character": 0
"line": 5,
"character": 17
}
},
"parent": {
"range": {
"start": {
"line": 2,
"line": 0,
"character": 0
},
"end": {
"line": 6,
"character": 0
}
},
"parent": {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it helps for reviewing, I can add a note to explain each 'substantial' change in the expectations.

"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 8,
"character": 3
}
"line": 8,
"character": 2
}
}
}
Expand Down
24 changes: 6 additions & 18 deletions test/expectations/selection_ranges/case_when.exp.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,29 @@
},
"end": {
"line": 2,
"character": 6
"character": 12
}
},
"parent": {
"range": {
"start": {
"line": 2,
"character": 2
"line": 1,
"character": 0
},
"end": {
"line": 2,
"character": 13
"character": 12
}
},
"parent": {
"range": {
"start": {
"line": 1,
"line": 0,
"character": 0
},
"end": {
"line": 5,
"character": 3
}
},
"parent": {
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 5,
"character": 3
}
"character": 2
}
}
}
Expand Down
30 changes: 9 additions & 21 deletions test/expectations/selection_ranges/class_declaration.exp.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,29 @@
},
"end": {
"line": 2,
"character": 8
"character": 16
}
},
"parent": {
"range": {
"start": {
"line": 2,
"character": 4
"line": 1,
"character": 2
},
"end": {
"line": 2,
"character": 17
"line": 3,
"character": 4
}
},
"parent": {
"range": {
"start": {
"line": 1,
"character": 2
"line": 0,
"character": 0
},
"end": {
"line": 3,
"character": 5
}
},
"parent": {
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 4,
"character": 3
}
"line": 4,
"character": 2
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"end": {
"line": 2,
"character": 3
"character": 2
}
}
}
Expand Down
22 changes: 5 additions & 17 deletions test/expectations/selection_ranges/def.exp.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,18 @@
},
"end": {
"line": 1,
"character": 3
"character": 6
}
},
"parent": {
"range": {
"start": {
"line": 1,
"character": 2
"line": 0,
"character": 0
},
"end": {
"line": 1,
"character": 7
}
},
"parent": {
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 3,
"character": 3
}
"line": 3,
"character": 2
}
}
}
Expand Down
Loading