Skip to content

Commit

Permalink
Merge pull request #425 from zed-industries/refine-select-larger-node
Browse files Browse the repository at this point in the history
Refine behavior of select_larger_syntax_node
  • Loading branch information
maxbrunsfeld committed Feb 4, 2022
2 parents fe1729f + 7fc9518 commit 82afacd
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 21 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/language/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ serde_json = { version = "1", features = ["preserve_order"] }
similar = "1.3"
smallvec = { version = "1.6", features = ["union"] }
smol = "1.2"
tree-sitter = "0.20.0"
tree-sitter = "0.20"
tree-sitter-rust = { version = "0.20.0", optional = true }

[dev-dependencies]
Expand Down
54 changes: 45 additions & 9 deletions crates/language/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2139,17 +2139,53 @@ impl BufferSnapshot {
}

pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
if let Some(tree) = self.tree.as_ref() {
let root = tree.root_node();
let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut node = root.descendant_for_byte_range(range.start, range.end);
while node.map_or(false, |n| n.byte_range() == range) {
node = node.unwrap().parent();
let tree = self.tree.as_ref()?;
let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut cursor = tree.root_node().walk();

// Descend to smallest leaf that touches or exceeds the start of the range.
while cursor.goto_first_child_for_byte(range.start).is_some() {}

// Ascend to the smallest ancestor that strictly contains the range.
loop {
let node_range = cursor.node().byte_range();
if node_range.start <= range.start
&& node_range.end >= range.end
&& node_range.len() > range.len()
{
break;
}
if !cursor.goto_parent() {
break;
}
node.map(|n| n.byte_range())
} else {
None
}

let left_node = cursor.node();

// For an empty range, try to find another node immediately to the right of the range.
if left_node.end_byte() == range.start {
let mut right_node = None;
while !cursor.goto_next_sibling() {
if !cursor.goto_parent() {
break;
}
}

while cursor.node().start_byte() == range.start {
right_node = Some(cursor.node());
if !cursor.goto_first_child() {
break;
}
}

if let Some(right_node) = right_node {
if right_node.is_named() || !left_node.is_named() {
return Some(right_node.byte_range());
}
}
}

Some(left_node.byte_range())
}

pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Option<Outline<Anchor>> {
Expand Down
10 changes: 5 additions & 5 deletions crates/language/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ async fn test_reparse(mut cx: gpui::TestAppContext) {
concat!(
"(source_file (function_item name: (identifier) ",
"parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
"body: (block (identifier))))"
"body: (block (expression_statement (identifier)))))"
)
);

Expand Down Expand Up @@ -224,11 +224,11 @@ async fn test_reparse(mut cx: gpui::TestAppContext) {
concat!(
"(source_file (function_item name: (identifier) ",
"parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
"body: (block (call_expression ",
"body: (block (expression_statement (call_expression ",
"function: (generic_function ",
"function: (field_expression value: (identifier) field: (field_identifier)) ",
"type_arguments: (type_arguments (type_identifier))) ",
"arguments: (arguments (identifier))))))",
"arguments: (arguments (identifier)))))))",
)
);

Expand Down Expand Up @@ -262,11 +262,11 @@ async fn test_reparse(mut cx: gpui::TestAppContext) {
concat!(
"(source_file (function_item name: (identifier) ",
"parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
"body: (block (call_expression ",
"body: (block (expression_statement (call_expression ",
"function: (generic_function ",
"function: (field_expression value: (identifier) field: (field_identifier)) ",
"type_arguments: (type_arguments (type_identifier))) ",
"arguments: (arguments (identifier))))))",
"arguments: (arguments (identifier)))))))",
)
);

Expand Down
4 changes: 2 additions & 2 deletions crates/zed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ thiserror = "1.0.29"
time = "0.3"
tiny_http = "0.8"
toml = "0.5"
tree-sitter = "0.20.0"
tree-sitter-rust = "0.20.0"
tree-sitter = "0.20.4"
tree-sitter-rust = "0.20.1"
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
url = "2.2"

Expand Down

0 comments on commit 82afacd

Please sign in to comment.