aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/matching_brace.rs
diff options
context:
space:
mode:
authorWilco Kusee <[email protected]>2019-03-23 16:34:49 +0000
committerWilco Kusee <[email protected]>2019-03-23 16:34:49 +0000
commita3711e08dc4e393957dff136218c47d8b77da14f (patch)
tree862ad28652de70aac75cf6e619850ae013500694 /crates/ra_ide_api/src/matching_brace.rs
parenta656b891fba4b89775adbc93114a20c99afe5f36 (diff)
Move highlighting and matching_brace
Diffstat (limited to 'crates/ra_ide_api/src/matching_brace.rs')
-rw-r--r--crates/ra_ide_api/src/matching_brace.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide_api/src/matching_brace.rs
new file mode 100644
index 000000000..d1405f14f
--- /dev/null
+++ b/crates/ra_ide_api/src/matching_brace.rs
@@ -0,0 +1,45 @@
1use ra_syntax::{
2 SourceFile, TextUnit,
3 algo::find_leaf_at_offset,
4 SyntaxKind::{self, *},
5 ast::AstNode,
6};
7
8pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
9 const BRACES: &[SyntaxKind] =
10 &[L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE];
11 let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset)
12 .filter_map(|node| {
13 let idx = BRACES.iter().position(|&brace| brace == node.kind())?;
14 Some((node, idx))
15 })
16 .next()?;
17 let parent = brace_node.parent()?;
18 let matching_kind = BRACES[brace_idx ^ 1];
19 let matching_node = parent.children().find(|node| node.kind() == matching_kind)?;
20 Some(matching_node.range().start())
21}
22
23#[cfg(test)]
24mod tests {
25 use test_utils::{add_cursor, assert_eq_text, extract_offset};
26
27 use super::*;
28
29 #[test]
30 fn test_matching_brace() {
31 fn do_check(before: &str, after: &str) {
32 let (pos, before) = extract_offset(before);
33 let file = SourceFile::parse(&before);
34 let new_pos = match matching_brace(&file, pos) {
35 None => pos,
36 Some(pos) => pos,
37 };
38 let actual = add_cursor(&before, new_pos);
39 assert_eq_text!(after, &actual);
40 }
41
42 do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }");
43 }
44
45}