})
.collect::<Vec<SyntaxElement>>();
let tail_expr = tail_expr.map(|expr| expr.dedent(old_indent).indent(body_indent));
- make::hacky_block_expr_with_comments(elements, tail_expr)
+
+ make::hacky_block_expr(elements, tail_expr)
}
};
elements.push(syntax::NodeOrToken::Node(stmt_tail.syntax().clone()));
}
- make::hacky_block_expr_with_comments(elements, Some(tail_expr))
+ make::hacky_block_expr(elements, Some(tail_expr))
}
fn format_type(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> String {
);
}
- // FIXME: we do want to preserve whitespace
#[test]
- fn extract_function_does_not_preserve_whitespace() {
+ fn extract_function_does_preserve_whitespace() {
check_assist(
extract_function,
r#"
fn $0fun_name() {
let a = 0;
+
let x = 0;
}
"#,
}
/// Ideally this function wouldn't exist since it involves manual indenting.
-/// It differs from `make::block_expr` by also supporting comments.
+/// It differs from `make::block_expr` by also supporting comments and whitespace.
///
/// FIXME: replace usages of this with the mutable syntax tree API
-pub fn hacky_block_expr_with_comments(
+pub fn hacky_block_expr(
elements: impl IntoIterator<Item = crate::SyntaxElement>,
tail_expr: Option<ast::Expr>,
) -> ast::BlockExpr {
for node_or_token in elements.into_iter() {
match node_or_token {
rowan::NodeOrToken::Node(n) => format_to!(buf, " {n}\n"),
- rowan::NodeOrToken::Token(t) if t.kind() == SyntaxKind::COMMENT => {
- format_to!(buf, " {t}\n")
+ rowan::NodeOrToken::Token(t) => {
+ let kind = t.kind();
+ if kind == SyntaxKind::COMMENT {
+ format_to!(buf, " {t}\n")
+ } else if kind == SyntaxKind::WHITESPACE {
+ let content = t.text().trim_matches(|c| c != '\n');
+ if content.len() >= 1 {
+ format_to!(buf, "{}", &content[1..])
+ }
+ }
}
- _ => (),
}
}
if let Some(tail_expr) = tail_expr {