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 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 {
|
||||
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)", 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