diff options
-rw-r--r-- | crates/ra_ide/src/matching_brace.rs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/crates/ra_ide/src/matching_brace.rs b/crates/ra_ide/src/matching_brace.rs index 407a9636d..685ba10ad 100644 --- a/crates/ra_ide/src/matching_brace.rs +++ b/crates/ra_ide/src/matching_brace.rs | |||
@@ -1,8 +1,12 @@ | |||
1 | use ra_syntax::{ast::AstNode, SourceFile, SyntaxKind, TextSize, T}; | 1 | use ra_syntax::{ |
2 | ast::{self, AstNode}, | ||
3 | SourceFile, SyntaxKind, TextSize, T, | ||
4 | }; | ||
5 | use test_utils::mark; | ||
2 | 6 | ||
3 | // Feature: Matching Brace | 7 | // Feature: Matching Brace |
4 | // | 8 | // |
5 | // If the cursor is on any brace (`<>(){}[]`) which is a part of a brace-pair, | 9 | // If the cursor is on any brace (`<>(){}[]||`) which is a part of a brace-pair, |
6 | // moves cursor to the matching brace. It uses the actual parser to determine | 10 | // moves cursor to the matching brace. It uses the actual parser to determine |
7 | // braces, so it won't confuse generics with comparisons. | 11 | // braces, so it won't confuse generics with comparisons. |
8 | // | 12 | // |
@@ -13,8 +17,8 @@ use ra_syntax::{ast::AstNode, SourceFile, SyntaxKind, TextSize, T}; | |||
13 | // |=== | 17 | // |=== |
14 | pub fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> { | 18 | pub fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> { |
15 | const BRACES: &[SyntaxKind] = | 19 | const BRACES: &[SyntaxKind] = |
16 | &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>]]; | 20 | &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]]; |
17 | let (brace_node, brace_idx) = file | 21 | let (brace_token, brace_idx) = file |
18 | .syntax() | 22 | .syntax() |
19 | .token_at_offset(offset) | 23 | .token_at_offset(offset) |
20 | .filter_map(|node| { | 24 | .filter_map(|node| { |
@@ -22,7 +26,11 @@ pub fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> { | |||
22 | Some((node, idx)) | 26 | Some((node, idx)) |
23 | }) | 27 | }) |
24 | .next()?; | 28 | .next()?; |
25 | let parent = brace_node.parent(); | 29 | let parent = brace_token.parent(); |
30 | if brace_token.kind() == T![|] && !ast::ParamList::can_cast(parent.kind()) { | ||
31 | mark::hit!(pipes_not_braces); | ||
32 | return None; | ||
33 | } | ||
26 | let matching_kind = BRACES[brace_idx ^ 1]; | 34 | let matching_kind = BRACES[brace_idx ^ 1]; |
27 | let matching_node = parent.children_with_tokens().find(|node| node.kind() == matching_kind)?; | 35 | let matching_node = parent.children_with_tokens().find(|node| node.kind() == matching_kind)?; |
28 | Some(matching_node.text_range().start()) | 36 | Some(matching_node.text_range().start()) |
@@ -48,5 +56,14 @@ mod tests { | |||
48 | } | 56 | } |
49 | 57 | ||
50 | do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }"); | 58 | do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }"); |
59 | do_check("fn main() { |x: i32|<|> x * 2;}", "fn main() { <|>|x: i32| x * 2;}"); | ||
60 | |||
61 | { | ||
62 | mark::check!(pipes_not_braces); | ||
63 | do_check( | ||
64 | "fn main() { match 92 { 1 | 2 |<|> 3 => 92 } }", | ||
65 | "fn main() { match 92 { 1 | 2 |<|> 3 => 92 } }", | ||
66 | ); | ||
67 | } | ||
51 | } | 68 | } |
52 | } | 69 | } |