diff options
Diffstat (limited to 'crates/ide/src/expand_macro.rs')
-rw-r--r-- | crates/ide/src/expand_macro.rs | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index ffb3a6f7d..be0ee03bf 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | use std::iter; | ||
2 | |||
1 | use hir::Semantics; | 3 | use hir::Semantics; |
2 | use ide_db::RootDatabase; | 4 | use ide_db::RootDatabase; |
3 | use syntax::{ | 5 | use syntax::{ |
@@ -23,6 +25,8 @@ pub struct ExpandedMacro { | |||
23 | // | 25 | // |
24 | // | VS Code | **Rust Analyzer: Expand macro recursively** | 26 | // | VS Code | **Rust Analyzer: Expand macro recursively** |
25 | // |=== | 27 | // |=== |
28 | // | ||
29 | // image::https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif[] | ||
26 | pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> { | 30 | pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> { |
27 | let sema = Semantics::new(db); | 31 | let sema = Semantics::new(db); |
28 | let file = sema.parse(position.file_id); | 32 | let file = sema.parse(position.file_id); |
@@ -89,24 +93,42 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { | |||
89 | let is_last = | 93 | let is_last = |
90 | |f: fn(SyntaxKind) -> bool, default| -> bool { last.map(f).unwrap_or(default) }; | 94 | |f: fn(SyntaxKind) -> bool, default| -> bool { last.map(f).unwrap_or(default) }; |
91 | 95 | ||
92 | res += &match token.kind() { | 96 | match token.kind() { |
93 | k if is_text(k) && is_next(|it| !it.is_punct(), true) => token.text().to_string() + " ", | 97 | k if is_text(k) && is_next(|it| !it.is_punct(), true) => { |
98 | res.push_str(token.text()); | ||
99 | res.push(' '); | ||
100 | } | ||
94 | L_CURLY if is_next(|it| it != R_CURLY, true) => { | 101 | L_CURLY if is_next(|it| it != R_CURLY, true) => { |
95 | indent += 1; | 102 | indent += 1; |
96 | let leading_space = if is_last(is_text, false) { " " } else { "" }; | 103 | if is_last(is_text, false) { |
97 | format!("{}{{\n{}", leading_space, " ".repeat(indent)) | 104 | res.push(' '); |
105 | } | ||
106 | res.push_str("{\n"); | ||
107 | res.extend(iter::repeat(" ").take(2 * indent)); | ||
98 | } | 108 | } |
99 | R_CURLY if is_last(|it| it != L_CURLY, true) => { | 109 | R_CURLY if is_last(|it| it != L_CURLY, true) => { |
100 | indent = indent.saturating_sub(1); | 110 | indent = indent.saturating_sub(1); |
101 | format!("\n{}}}", " ".repeat(indent)) | 111 | res.push('\n'); |
112 | res.extend(iter::repeat(" ").take(2 * indent)); | ||
113 | res.push_str("}"); | ||
102 | } | 114 | } |
103 | R_CURLY => format!("}}\n{}", " ".repeat(indent)), | 115 | R_CURLY => { |
104 | T![;] => format!(";\n{}", " ".repeat(indent)), | 116 | res.push_str("}\n"); |
105 | T![->] => " -> ".to_string(), | 117 | res.extend(iter::repeat(" ").take(2 * indent)); |
106 | T![=] => " = ".to_string(), | 118 | } |
107 | T![=>] => " => ".to_string(), | 119 | LIFETIME_IDENT if is_next(|it| it == IDENT, true) => { |
108 | _ => token.text().to_string(), | 120 | res.push_str(token.text()); |
109 | }; | 121 | res.push(' '); |
122 | } | ||
123 | T![;] => { | ||
124 | res.push_str(";\n"); | ||
125 | res.extend(iter::repeat(" ").take(2 * indent)); | ||
126 | } | ||
127 | T![->] => res.push_str(" -> "), | ||
128 | T![=] => res.push_str(" = "), | ||
129 | T![=>] => res.push_str(" => "), | ||
130 | _ => res.push_str(token.text()), | ||
131 | } | ||
110 | 132 | ||
111 | last = Some(token.kind()); | 133 | last = Some(token.kind()); |
112 | } | 134 | } |