diff options
Diffstat (limited to 'crates/libeditor/src')
-rw-r--r-- | crates/libeditor/src/typing.rs | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/crates/libeditor/src/typing.rs b/crates/libeditor/src/typing.rs index e7eba671f..060095f28 100644 --- a/crates/libeditor/src/typing.rs +++ b/crates/libeditor/src/typing.rs | |||
@@ -1,5 +1,8 @@ | |||
1 | use std::mem; | ||
2 | |||
1 | use libsyntax2::{ | 3 | use libsyntax2::{ |
2 | TextUnit, TextRange, SyntaxNodeRef, File, | 4 | TextUnit, TextRange, SyntaxNodeRef, File, AstNode, |
5 | ast, | ||
3 | algo::{ | 6 | algo::{ |
4 | walk::preorder, | 7 | walk::preorder, |
5 | find_covering_node, | 8 | find_covering_node, |
@@ -60,6 +63,9 @@ fn remove_newline( | |||
60 | offset: TextUnit, | 63 | offset: TextUnit, |
61 | ) { | 64 | ) { |
62 | if node.kind() == WHITESPACE && node_text.bytes().filter(|&b| b == b'\n').count() == 1 { | 65 | if node.kind() == WHITESPACE && node_text.bytes().filter(|&b| b == b'\n').count() == 1 { |
66 | if join_lambda_body(edit, node).is_some() { | ||
67 | return | ||
68 | } | ||
63 | match (node.prev_sibling(), node.next_sibling()) { | 69 | match (node.prev_sibling(), node.next_sibling()) { |
64 | (Some(prev), Some(next)) => { | 70 | (Some(prev), Some(next)) => { |
65 | let range = TextRange::from_to(prev.range().start(), node.range().end()); | 71 | let range = TextRange::from_to(prev.range().start(), node.range().end()); |
@@ -91,6 +97,41 @@ fn remove_newline( | |||
91 | ); | 97 | ); |
92 | } | 98 | } |
93 | 99 | ||
100 | fn join_lambda_body( | ||
101 | edit: &mut EditBuilder, | ||
102 | node: SyntaxNodeRef, | ||
103 | ) -> Option<()> { | ||
104 | let block = ast::Block::cast(node.parent()?)?; | ||
105 | let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; | ||
106 | let _lambda = ast::LambdaExpr::cast(block_expr.syntax().parent()?)?; | ||
107 | let expr = single_expr(block)?; | ||
108 | edit.replace( | ||
109 | block_expr.syntax().range(), | ||
110 | expr.syntax().text(), | ||
111 | ); | ||
112 | Some(()) | ||
113 | } | ||
114 | |||
115 | fn single_expr(block: ast::Block) -> Option<ast::Expr> { | ||
116 | let mut res = None; | ||
117 | for child in block.syntax().children() { | ||
118 | if let Some(expr) = ast::Expr::cast(child) { | ||
119 | if expr.syntax().text().contains('\n') { | ||
120 | return None; | ||
121 | } | ||
122 | if mem::replace(&mut res, Some(expr)).is_some() { | ||
123 | return None; | ||
124 | } | ||
125 | } else { | ||
126 | match child.kind() { | ||
127 | WHITESPACE | L_CURLY | R_CURLY => (), | ||
128 | _ => return None, | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | res | ||
133 | } | ||
134 | |||
94 | fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str { | 135 | fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str { |
95 | match left.kind() { | 136 | match left.kind() { |
96 | L_PAREN | L_BRACK => return "", | 137 | L_PAREN | L_BRACK => return "", |