aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_fmt/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-09 09:56:54 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-09 09:56:54 +0000
commit34398a8756b56c323d3b4b2ef32fbca32d88a105 (patch)
tree92ebf0ec790945116e152fce7a9e3cc749c6b8e0 /crates/ra_fmt/src
parent3e8351fb0607f8711749b00d80f68bf25de01a76 (diff)
parent02dd0cfd8c7bf50cfb26c3c5178be5af4f3fdd25 (diff)
Merge #766
766: Formatting code into ra_fmt r=matklad a=eulerdisk As discussed https://github.com/rust-analyzer/rust-analyzer/pull/762#discussion_r254905885 I did only move the code without other improvements. Co-authored-by: Andrea Pretto <[email protected]>
Diffstat (limited to 'crates/ra_fmt/src')
-rw-r--r--crates/ra_fmt/src/lib.rs76
1 files changed, 76 insertions, 0 deletions
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 @@
1//! This crate provides some utilities for indenting rust code.
2//!
3use itertools::Itertools;
4use ra_syntax::{
5 AstNode,
6 SyntaxNode, SyntaxKind::*,
7 ast::{self, AstToken},
8 algo::generate,
9};
10
11pub fn reindent(text: &str, indent: &str) -> String {
12 let indent = format!("\n{}", indent);
13 text.lines().intersperse(&indent).collect()
14}
15
16/// If the node is on the beginning of the line, calculate indent.
17pub fn leading_indent(node: &SyntaxNode) -> Option<&str> {
18 for leaf in prev_leaves(node) {
19 if let Some(ws) = ast::Whitespace::cast(leaf) {
20 let ws_text = ws.text();
21 if let Some(pos) = ws_text.rfind('\n') {
22 return Some(&ws_text[pos + 1..]);
23 }
24 }
25 if leaf.leaf_text().unwrap().contains('\n') {
26 break;
27 }
28 }
29 None
30}
31
32fn prev_leaves(node: &SyntaxNode) -> impl Iterator<Item = &SyntaxNode> {
33 generate(prev_leaf(node), |&node| prev_leaf(node))
34}
35
36fn prev_leaf(node: &SyntaxNode) -> Option<&SyntaxNode> {
37 generate(node.ancestors().find_map(SyntaxNode::prev_sibling), |it| it.last_child()).last()
38}
39
40pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> {
41 let expr = block.expr()?;
42 if expr.syntax().text().contains('\n') {
43 return None;
44 }
45 let non_trivial_children = block.syntax().children().filter(|it| match it.kind() {
46 WHITESPACE | L_CURLY | R_CURLY => false,
47 _ => it != &expr.syntax(),
48 });
49 if non_trivial_children.count() > 0 {
50 return None;
51 }
52 Some(expr)
53}
54
55pub fn compute_ws(left: &SyntaxNode, right: &SyntaxNode) -> &'static str {
56 match left.kind() {
57 L_PAREN | L_BRACK => return "",
58 L_CURLY => {
59 if let USE_TREE = right.kind() {
60 return "";
61 }
62 }
63 _ => (),
64 }
65 match right.kind() {
66 R_PAREN | R_BRACK => return "",
67 R_CURLY => {
68 if let USE_TREE = left.kind() {
69 return "";
70 }
71 }
72 DOT => return "",
73 _ => (),
74 }
75 " "
76}