parent
483a84a7f1
commit
22148a3639
2 changed files with 48 additions and 2 deletions
|
@ -1621,8 +1621,13 @@ impl BufferSnapshot {
|
||||||
let range = range.start.to_offset(self)..range.end.to_offset(self);
|
let range = range.start.to_offset(self)..range.end.to_offset(self);
|
||||||
let mut cursor = tree.root_node().walk();
|
let mut cursor = tree.root_node().walk();
|
||||||
|
|
||||||
// Descend to smallest leaf that touches or exceeds the start of the range.
|
// Descend to the first leaf that touches the start of the range,
|
||||||
while cursor.goto_first_child_for_byte(range.start).is_some() {}
|
// and if the range is non-empty, extends beyond the start.
|
||||||
|
while cursor.goto_first_child_for_byte(range.start).is_some() {
|
||||||
|
if !range.is_empty() && cursor.node().end_byte() == range.start {
|
||||||
|
cursor.goto_next_sibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ascend to the smallest ancestor that strictly contains the range.
|
// Ascend to the smallest ancestor that strictly contains the range.
|
||||||
loop {
|
loop {
|
||||||
|
@ -1656,6 +1661,9 @@ impl BufferSnapshot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is a candidate node on both sides of the (empty) range, then
|
||||||
|
// decide between the two by favoring a named node over an anonymous token.
|
||||||
|
// If both nodes are the same in that regard, favor the right one.
|
||||||
if let Some(right_node) = right_node {
|
if let Some(right_node) = right_node {
|
||||||
if right_node.is_named() || !left_node.is_named() {
|
if right_node.is_named() || !left_node.is_named() {
|
||||||
return Some(right_node.byte_range());
|
return Some(right_node.byte_range());
|
||||||
|
|
|
@ -458,6 +458,44 @@ fn test_enclosing_bracket_ranges(cx: &mut MutableAppContext) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_range_for_syntax_ancestor(cx: &mut MutableAppContext) {
|
||||||
|
cx.add_model(|cx| {
|
||||||
|
let text = "fn a() { b(|c| {}) }";
|
||||||
|
let buffer = Buffer::new(0, text, cx).with_language(Arc::new(rust_lang()), cx);
|
||||||
|
let snapshot = buffer.snapshot();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
snapshot.range_for_syntax_ancestor(empty_range_at(text, "|")),
|
||||||
|
Some(range_of(text, "|"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
snapshot.range_for_syntax_ancestor(range_of(text, "|")),
|
||||||
|
Some(range_of(text, "|c|"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
snapshot.range_for_syntax_ancestor(range_of(text, "|c|")),
|
||||||
|
Some(range_of(text, "|c| {}"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
snapshot.range_for_syntax_ancestor(range_of(text, "|c| {}")),
|
||||||
|
Some(range_of(text, "(|c| {})"))
|
||||||
|
);
|
||||||
|
|
||||||
|
buffer
|
||||||
|
});
|
||||||
|
|
||||||
|
fn empty_range_at(text: &str, part: &str) -> Range<usize> {
|
||||||
|
let start = text.find(part).unwrap();
|
||||||
|
start..start
|
||||||
|
}
|
||||||
|
|
||||||
|
fn range_of(text: &str, part: &str) -> Range<usize> {
|
||||||
|
let start = text.find(part).unwrap();
|
||||||
|
start..start + part.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_edit_with_autoindent(cx: &mut MutableAppContext) {
|
fn test_edit_with_autoindent(cx: &mut MutableAppContext) {
|
||||||
cx.add_model(|cx| {
|
cx.add_model(|cx| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue