From 757e593b253b4df7e6fc8bf15a4d4f34c9d484c5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 21:32:33 +0300 Subject: rename ra_ide_api -> ra_ide --- crates/ra_ide/src/matching_brace.rs | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 crates/ra_ide/src/matching_brace.rs (limited to 'crates/ra_ide/src/matching_brace.rs') diff --git a/crates/ra_ide/src/matching_brace.rs b/crates/ra_ide/src/matching_brace.rs new file mode 100644 index 000000000..d1204fac0 --- /dev/null +++ b/crates/ra_ide/src/matching_brace.rs @@ -0,0 +1,43 @@ +//! FIXME: write short doc here + +use ra_syntax::{ast::AstNode, SourceFile, SyntaxKind, TextUnit, T}; + +pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option { + const BRACES: &[SyntaxKind] = + &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>]]; + let (brace_node, brace_idx) = file + .syntax() + .token_at_offset(offset) + .filter_map(|node| { + let idx = BRACES.iter().position(|&brace| brace == node.kind())?; + Some((node, idx)) + }) + .next()?; + let parent = brace_node.parent(); + let matching_kind = BRACES[brace_idx ^ 1]; + let matching_node = parent.children_with_tokens().find(|node| node.kind() == matching_kind)?; + Some(matching_node.text_range().start()) +} + +#[cfg(test)] +mod tests { + use test_utils::{add_cursor, assert_eq_text, extract_offset}; + + use super::*; + + #[test] + fn test_matching_brace() { + fn do_check(before: &str, after: &str) { + let (pos, before) = extract_offset(before); + let parse = SourceFile::parse(&before); + let new_pos = match matching_brace(&parse.tree(), pos) { + None => pos, + Some(pos) => pos, + }; + let actual = add_cursor(&before, new_pos); + assert_eq_text!(after, &actual); + } + + do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }"); + } +} -- cgit v1.2.3