From c631b585a7358d1569a051f2529ecaae222e95cd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 16 Aug 2018 00:23:22 +0300 Subject: matching brace --- crates/libeditor/src/lib.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'crates/libeditor/src/lib.rs') diff --git a/crates/libeditor/src/lib.rs b/crates/libeditor/src/lib.rs index 9e44f5d92..28da457d1 100644 --- a/crates/libeditor/src/lib.rs +++ b/crates/libeditor/src/lib.rs @@ -12,8 +12,8 @@ mod code_actions; use libsyntax2::{ ast::{self, NameOwner}, AstNode, - algo::walk, - SyntaxKind::*, + algo::{walk, find_leaf_at_offset}, + SyntaxKind::{self, *}, }; pub use libsyntax2::{File, TextRange, TextUnit}; pub use self::{ @@ -52,6 +52,28 @@ pub fn parse(text: &str) -> ast::File { ast::File::parse(text) } +pub fn matching_brace(file: &ast::File, offset: TextUnit) -> Option { + const BRACES: &[SyntaxKind] = &[ + L_CURLY, R_CURLY, + L_BRACK, R_BRACK, + L_PAREN, R_PAREN, + L_ANGLE, R_ANGLE, + ]; + let syntax = file.syntax(); + let syntax = syntax.as_ref(); + let (brace_node, brace_idx) = find_leaf_at_offset(syntax, 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() + .find(|node| node.kind() == matching_kind)?; + Some(matching_node.range().start()) +} + pub fn highlight(file: &ast::File) -> Vec { let syntax = file.syntax(); let mut res = Vec::new(); -- cgit v1.2.3