@@ -15,6 +15,7 @@ pub struct JoinLinesConfig {
1515 pub join_else_if : bool ,
1616 pub remove_trailing_comma : bool ,
1717 pub unwrap_trivial_blocks : bool ,
18+ pub join_assignments : bool ,
1819}
1920
2021// Feature: Join Lines
@@ -162,6 +163,12 @@ fn remove_newline(
162163 }
163164 }
164165
166+ if config. join_assignments {
167+ if join_assignments ( edit, & prev, & next) . is_some ( ) {
168+ return ;
169+ }
170+ }
171+
165172 if config. unwrap_trivial_blocks {
166173 // Special case that turns something like:
167174 //
@@ -232,6 +239,41 @@ fn join_single_use_tree(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Opti
232239 Some ( ( ) )
233240}
234241
242+ fn join_assignments (
243+ edit : & mut TextEditBuilder ,
244+ prev : & SyntaxElement ,
245+ next : & SyntaxElement ,
246+ ) -> Option < ( ) > {
247+ let let_stmt = ast:: LetStmt :: cast ( prev. as_node ( ) ?. clone ( ) ) ?;
248+ if let_stmt. eq_token ( ) . is_some ( ) {
249+ cov_mark:: hit!( join_assignments_already_initialized) ;
250+ return None ;
251+ }
252+ let let_ident_pat = match let_stmt. pat ( ) ? {
253+ ast:: Pat :: IdentPat ( it) => it,
254+ _ => return None ,
255+ } ;
256+
257+ let expr_stmt = ast:: ExprStmt :: cast ( next. as_node ( ) ?. clone ( ) ) ?;
258+ let bin_expr = match expr_stmt. expr ( ) ? {
259+ ast:: Expr :: BinExpr ( it) => it,
260+ _ => return None ,
261+ } ;
262+ if !matches ! ( bin_expr. op_kind( ) ?, ast:: BinaryOp :: Assignment { op: None } ) {
263+ return None ;
264+ }
265+ let lhs = bin_expr. lhs ( ) ?;
266+ let name_ref = lhs. name_ref ( ) ?;
267+
268+ if name_ref. to_string ( ) != let_ident_pat. syntax ( ) . to_string ( ) {
269+ cov_mark:: hit!( join_assignments_mismatch) ;
270+ return None ;
271+ }
272+
273+ edit. delete ( let_stmt. semicolon_token ( ) ?. text_range ( ) . cover ( lhs. syntax ( ) . text_range ( ) ) ) ;
274+ Some ( ( ) )
275+ }
276+
235277fn as_if_expr ( element : & SyntaxElement ) -> Option < ast:: IfExpr > {
236278 let mut node = element. as_node ( ) ?. clone ( ) ;
237279 if let Some ( stmt) = ast:: ExprStmt :: cast ( node. clone ( ) ) {
@@ -275,6 +317,7 @@ mod tests {
275317 join_else_if : true ,
276318 remove_trailing_comma : true ,
277319 unwrap_trivial_blocks : true ,
320+ join_assignments : true ,
278321 } ;
279322
280323 let ( before_cursor_pos, before) = extract_offset ( ra_fixture_before) ;
@@ -300,6 +343,7 @@ mod tests {
300343 join_else_if : true ,
301344 remove_trailing_comma : true ,
302345 unwrap_trivial_blocks : true ,
346+ join_assignments : true ,
303347 } ;
304348
305349 let ( sel, before) = extract_range ( ra_fixture_before) ;
@@ -990,6 +1034,55 @@ fn main() {
9901034
9911035 }
9921036}
1037+ "# ,
1038+ ) ;
1039+ }
1040+
1041+ #[ test]
1042+ fn join_assignments ( ) {
1043+ check_join_lines (
1044+ r#"
1045+ fn foo() {
1046+ $0let foo;
1047+ foo = "bar";
1048+ }
1049+ "# ,
1050+ r#"
1051+ fn foo() {
1052+ $0let foo = "bar";
1053+ }
1054+ "# ,
1055+ ) ;
1056+
1057+ cov_mark:: check!( join_assignments_mismatch) ;
1058+ check_join_lines (
1059+ r#"
1060+ fn foo() {
1061+ let foo;
1062+ let qux;$0
1063+ foo = "bar";
1064+ }
1065+ "# ,
1066+ r#"
1067+ fn foo() {
1068+ let foo;
1069+ let qux;$0 foo = "bar";
1070+ }
1071+ "# ,
1072+ ) ;
1073+
1074+ cov_mark:: check!( join_assignments_already_initialized) ;
1075+ check_join_lines (
1076+ r#"
1077+ fn foo() {
1078+ let foo = "bar";$0
1079+ foo = "bar";
1080+ }
1081+ "# ,
1082+ r#"
1083+ fn foo() {
1084+ let foo = "bar";$0 foo = "bar";
1085+ }
9931086"# ,
9941087 ) ;
9951088 }
0 commit comments