From 02dd0cfd8c7bf50cfb26c3c5178be5af4f3fdd25 Mon Sep 17 00:00:00 2001 From: Andrea Pretto Date: Fri, 8 Feb 2019 18:58:27 +0100 Subject: Refactor formatting code out of ra_ida_api_light into ra_fmt. --- crates/ra_fmt/src/lib.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 crates/ra_fmt/src/lib.rs (limited to 'crates/ra_fmt/src') diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs new file mode 100644 index 000000000..62e6fb9c1 --- /dev/null +++ b/crates/ra_fmt/src/lib.rs @@ -0,0 +1,76 @@ +//! This crate provides some utilities for indenting rust code. +//! +use itertools::Itertools; +use ra_syntax::{ + AstNode, + SyntaxNode, SyntaxKind::*, + ast::{self, AstToken}, + algo::generate, +}; + +pub fn reindent(text: &str, indent: &str) -> String { + let indent = format!("\n{}", indent); + text.lines().intersperse(&indent).collect() +} + +/// If the node is on the beginning of the line, calculate indent. +pub fn leading_indent(node: &SyntaxNode) -> Option<&str> { + for leaf in prev_leaves(node) { + if let Some(ws) = ast::Whitespace::cast(leaf) { + let ws_text = ws.text(); + if let Some(pos) = ws_text.rfind('\n') { + return Some(&ws_text[pos + 1..]); + } + } + if leaf.leaf_text().unwrap().contains('\n') { + break; + } + } + None +} + +fn prev_leaves(node: &SyntaxNode) -> impl Iterator { + generate(prev_leaf(node), |&node| prev_leaf(node)) +} + +fn prev_leaf(node: &SyntaxNode) -> Option<&SyntaxNode> { + generate(node.ancestors().find_map(SyntaxNode::prev_sibling), |it| it.last_child()).last() +} + +pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> { + let expr = block.expr()?; + if expr.syntax().text().contains('\n') { + return None; + } + let non_trivial_children = block.syntax().children().filter(|it| match it.kind() { + WHITESPACE | L_CURLY | R_CURLY => false, + _ => it != &expr.syntax(), + }); + if non_trivial_children.count() > 0 { + return None; + } + Some(expr) +} + +pub fn compute_ws(left: &SyntaxNode, right: &SyntaxNode) -> &'static str { + match left.kind() { + L_PAREN | L_BRACK => return "", + L_CURLY => { + if let USE_TREE = right.kind() { + return ""; + } + } + _ => (), + } + match right.kind() { + R_PAREN | R_BRACK => return "", + R_CURLY => { + if let USE_TREE = left.kind() { + return ""; + } + } + DOT => return "", + _ => (), + } + " " +} -- cgit v1.2.3