Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/matching_brace.rs')
-rw-r--r--crates/ide/src/matching_brace.rs48
1 files changed, 34 insertions, 14 deletions
diff --git a/crates/ide/src/matching_brace.rs b/crates/ide/src/matching_brace.rs
index b2b91d6e3c..5079b0c4f9 100644
--- a/crates/ide/src/matching_brace.rs
+++ b/crates/ide/src/matching_brace.rs
@@ -17,25 +17,37 @@ use syntax::{
pub(crate) fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> {
const BRACES: &[SyntaxKind] =
&[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]];
- let (brace_token, brace_idx) = file
- .syntax()
- .token_at_offset(offset)
+ let current = file.syntax().token_at_offset(offset);
+ if let Some((brace_token, brace_idx)) = current
+ .clone()
.filter_map(|node| {
let idx = BRACES.iter().position(|&brace| brace == node.kind())?;
Some((node, idx))
})
- .last()?;
- let parent = brace_token.parent()?;
- if brace_token.kind() == T![|] && !ast::ParamList::can_cast(parent.kind()) {
- cov_mark::hit!(pipes_not_braces);
- return None;
+ .last()
+ {
+ let parent = brace_token.parent()?;
+ if brace_token.kind() == T![|] && !ast::ParamList::can_cast(parent.kind()) {
+ cov_mark::hit!(pipes_not_braces);
+ return None;
+ }
+ let matching_kind = BRACES[brace_idx ^ 1];
+ let matching_node = parent
+ .children_with_tokens()
+ .filter_map(|it| it.into_token())
+ .find(|node| node.kind() == matching_kind && node != &brace_token)?;
+ Some(matching_node.text_range().start())
+ } else {
+ // when the offset is not at a brace, find first parent
+ current.last()?.parent_ancestors().find_map(|x| {
+ x.children_with_tokens()
+ .filter_map(|it| it.into_token())
+ // with ending brace
+ .filter(|node| BRACES.contains(&node.kind()))
+ .last()
+ .map(|x| x.text_range().start())
+ })
}
- let matching_kind = BRACES[brace_idx ^ 1];
- let matching_node = parent
- .children_with_tokens()
- .filter_map(|it| it.into_token())
- .find(|node| node.kind() == matching_kind && node != &brace_token)?;
- Some(matching_node.text_range().start())
}
#[cfg(test)]
@@ -64,6 +76,14 @@ mod tests {
"fn func(x) { return (2 * (x + 3)$0) + 5;}",
"fn func(x) { return $0(2 * (x + 3)) + 5;}",
);
+ do_check(
+ "fn func(x) { return (2 * (x $0+ 3)) + 5;}",
+ "fn func(x) { return (2 * (x + 3$0)) + 5;}",
+ );
+ do_check(
+ "fn func(x) { re$0turn (2 * (x + 3)) + 5;}",
+ "fn func(x) { return (2 * (x + 3)) + 5;$0}",
+ );
{
cov_mark::check!(pipes_not_braces);