fix: match brackets preceded by an empty node
`find_pair` looked up the node under the cursor with an empty byte range. When a zero-width node starts at that position, tree-sitter returns it, and since it is hidden the lookup resolves to its visible parent instead. Typst emits such a token right before the `(` or `[` of a call, so on those brackets `mm` either did nothing or jumped to the closing bracket of an outer pair. `find_matching_bracket` had the same problem. Look up the byte under the cursor instead, like the plaintext fallback at the end of `find_pair` already does.
This commit is contained in:
1 parent
90d0dfc263
commit
0f01568dd8
1 file changed
+26
-1
@@ -83,7 +83,7 @@ fn find_pair(
|
|||||||
let pos = doc.char_to_byte(pos_) as u32;
|
let pos = doc.char_to_byte(pos_) as u32;
|
||||||
|
|
||||||
let root = syntax.tree_for_byte_range(pos, pos).root_node();
|
let root = syntax.tree_for_byte_range(pos, pos).root_node();
|
||||||
let mut node = root.descendant_for_byte_range(pos, pos)?;
|
let mut node = root.descendant_for_byte_range(pos, pos + 1)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if node.is_named() && node.child_count() >= 2 {
|
if node.is_named() && node.child_count() >= 2 {
|
||||||
@@ -350,4 +350,29 @@ mod tests {
|
|||||||
assert("(prev line\n ) (middle) ( \n next line)", 14, 21);
|
assert("(prev line\n ) (middle) ( \n next line)", 14, 21);
|
||||||
assert("(prev line\n ) (middle) ( \n next line)", 23, 36);
|
assert("(prev line\n ) (middle) ( \n next line)", 23, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_find_matching_bracket_after_empty_node() {
|
||||||
|
// Typst emits a zero-width token right before the `(` or `[` of a call
|
||||||
|
let loader = crate::config::default_lang_loader();
|
||||||
|
let language = loader.language_for_name("typst").unwrap();
|
||||||
|
let doc = crate::Rope::from_str(
|
||||||
|
"#rect(width: 100%, stroke: stroke(dash: \"dash-dotted\", thickness: 2pt), radius: 5mm)[\n\n]\n",
|
||||||
|
);
|
||||||
|
let syntax = Syntax::new(doc.slice(..), language, &loader).unwrap();
|
||||||
|
|
||||||
|
let assert = |pos, expected| {
|
||||||
|
let actual = find_matching_bracket(&syntax, doc.slice(..), pos);
|
||||||
|
assert_eq!(Some(expected), actual);
|
||||||
|
let actual = find_matching_bracket_fuzzy(&syntax, doc.slice(..), pos);
|
||||||
|
assert_eq!(Some(expected), actual);
|
||||||
|
|
||||||
|
let actual = find_matching_bracket_fuzzy(&syntax, doc.slice(..), expected);
|
||||||
|
assert_eq!(Some(pos), actual, "expected symmetrical behaviour");
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(5, 83);
|
||||||
|
assert(33, 69);
|
||||||
|
assert(84, 87);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user