aboutsummaryrefslogtreecommitdiff
path: root/crates/libeditor/src/typing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libeditor/src/typing.rs')
-rw-r--r--crates/libeditor/src/typing.rs43
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 @@
1use std::mem;
2
1use libsyntax2::{ 3use 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
100fn 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
115fn 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
94fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str { 135fn 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 "",