aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_fmt/src/lib.rs
blob: b92477f9e7a2d5a375e200f38c26503043a5338a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//! This crate provides some utilities for indenting rust code.

use std::iter::successors;

use syntax::{
    ast::{self, AstToken},
    SmolStr, SyntaxNode, SyntaxToken,
};

/// If the node is on the beginning of the line, calculate indent.
pub fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> {
    for token in prev_tokens(node.first_token()?) {
        if let Some(ws) = ast::Whitespace::cast(token.clone()) {
            let ws_text = ws.text();
            if let Some(pos) = ws_text.rfind('\n') {
                return Some(ws_text[pos + 1..].into());
            }
        }
        if token.text().contains('\n') {
            break;
        }
    }
    None
}

fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
    successors(token.prev_token(), |token| token.prev_token())
}