Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix behaviour of matching when tree-sitter grammar is available #7238

Closed
wants to merge 2 commits into from
Closed
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
32 changes: 22 additions & 10 deletions helix-core/src/match_brackets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,17 @@ fn find_pair(syntax: &Syntax, doc: &Rope, pos: usize, traverse_parents: bool) ->
let pos = doc.char_to_byte(pos);

let mut node = tree.root_node().named_descendant_for_byte_range(pos, pos)?;
let mut node_positions = get_node_positions(doc, &node);

loop {
let (start_byte, end_byte) = surrounding_bytes(doc, &node)?;
let (start_char, end_char) = (doc.byte_to_char(start_byte), doc.byte_to_char(end_byte));
if is_valid_bracket(doc.char(pos)) {
if let Some((_, _, start_char, end_char)) = node_positions {
if !is_valid_pair(doc, start_char, end_char) {
return find_matching_bracket_plaintext(doc, pos);
}
}
}

while let Some((_, end_byte, start_char, end_char)) = node_positions {
if is_valid_pair(doc, start_char, end_char) {
if end_byte == pos {
return Some(start_char);
Expand All @@ -67,10 +73,19 @@ fn find_pair(syntax: &Syntax, doc: &Rope, pos: usize, traverse_parents: bool) ->

if traverse_parents {
node = node.parent()?;
node_positions = get_node_positions(doc, &node);
} else {
return None;
break;
}
}

None
}

fn get_node_positions(doc: &Rope, node: &Node) -> Option<(usize, usize, usize, usize)> {
let (start_byte, end_byte) = surrounding_bytes(doc, node)?;
let (start_char, end_char) = (doc.byte_to_char(start_byte), doc.byte_to_char(end_byte));
Some((start_byte, end_byte, start_char, end_char))
}

/// Returns the position of the matching bracket under cursor.
Expand All @@ -85,10 +100,7 @@ fn find_pair(syntax: &Syntax, doc: &Rope, pos: usize, traverse_parents: bool) ->
///
/// If no matching bracket is found, `None` is returned.
#[must_use]
pub fn find_matching_bracket_current_line_plaintext(
doc: &Rope,
cursor_pos: usize,
) -> Option<usize> {
pub fn find_matching_bracket_plaintext(doc: &Rope, cursor_pos: usize) -> Option<usize> {
Copy link
Contributor Author

@alevinval alevinval Jun 5, 2023

Choose a reason for hiding this comment

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

😓 even after having so much looks into it, and fixing the docs, I missed that the function name was left saying it worked on "current_line". So I'm addressing it here, removing mention of only working on the current line.

// Don't do anything when the cursor is not on top of a bracket.
let bracket = doc.char(cursor_pos);
if !is_valid_bracket(bracket) {
Expand Down Expand Up @@ -169,10 +181,10 @@ mod tests {
fn test_find_matching_bracket_current_line_plaintext() {
let assert = |input: &str, pos, expected| {
let input = &Rope::from(input);
let actual = find_matching_bracket_current_line_plaintext(input, pos);
let actual = find_matching_bracket_plaintext(input, pos);
assert_eq!(expected, actual.unwrap());

let actual = find_matching_bracket_current_line_plaintext(input, expected);
let actual = find_matching_bracket_plaintext(input, expected);
assert_eq!(pos, actual.unwrap(), "expected symmetrical behaviour");
};

Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4535,7 +4535,7 @@ fn match_brackets(cx: &mut Context) {
let selection = doc.selection(view.id).clone().transform(|range| {
let pos = range.cursor(text_slice);
if let Some(matched_pos) = doc.syntax().map_or_else(
|| match_brackets::find_matching_bracket_current_line_plaintext(text, pos),
|| match_brackets::find_matching_bracket_plaintext(text, pos),
|syntax| match_brackets::find_matching_bracket_fuzzy(syntax, text, pos),
) {
range.put_cursor(text_slice, matched_pos, is_select)
Expand Down