@@ -6,9 +6,12 @@ use std::{fmt, iter, ops};
6
6
use crate :: {
7
7
AstToken , NodeOrToken , SyntaxElement , SyntaxNode , SyntaxToken ,
8
8
ast:: { self , AstNode , make} ,
9
+ syntax_editor:: { SyntaxEditor , SyntaxMappingBuilder } ,
9
10
ted,
10
11
} ;
11
12
13
+ use super :: syntax_factory:: SyntaxFactory ;
14
+
12
15
#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
13
16
pub struct IndentLevel ( pub u8 ) ;
14
17
@@ -95,6 +98,24 @@ impl IndentLevel {
95
98
}
96
99
}
97
100
101
+ pub ( super ) fn clone_increase_indent ( self , node : & SyntaxNode ) -> SyntaxNode {
102
+ let node = node. clone_subtree ( ) ;
103
+ let mut editor = SyntaxEditor :: new ( node. clone ( ) ) ;
104
+ let tokens = node
105
+ . preorder_with_tokens ( )
106
+ . filter_map ( |event| match event {
107
+ rowan:: WalkEvent :: Leave ( NodeOrToken :: Token ( it) ) => Some ( it) ,
108
+ _ => None ,
109
+ } )
110
+ . filter_map ( ast:: Whitespace :: cast)
111
+ . filter ( |ws| ws. text ( ) . contains ( '\n' ) ) ;
112
+ for ws in tokens {
113
+ let new_ws = make:: tokens:: whitespace ( & format ! ( "{}{self}" , ws. syntax( ) ) ) ;
114
+ editor. replace ( ws. syntax ( ) , & new_ws) ;
115
+ }
116
+ editor. finish ( ) . new_root ( ) . clone ( )
117
+ }
118
+
98
119
pub ( super ) fn decrease_indent ( self , node : & SyntaxNode ) {
99
120
let tokens = node. preorder_with_tokens ( ) . filter_map ( |event| match event {
100
121
rowan:: WalkEvent :: Leave ( NodeOrToken :: Token ( it) ) => Some ( it) ,
@@ -111,36 +132,54 @@ impl IndentLevel {
111
132
}
112
133
}
113
134
}
135
+
136
+ pub ( super ) fn clone_decrease_indent ( self , node : & SyntaxNode ) -> SyntaxNode {
137
+ let node = node. clone_subtree ( ) ;
138
+ let mut editor = SyntaxEditor :: new ( node. clone ( ) ) ;
139
+ let tokens = node
140
+ . preorder_with_tokens ( )
141
+ . filter_map ( |event| match event {
142
+ rowan:: WalkEvent :: Leave ( NodeOrToken :: Token ( it) ) => Some ( it) ,
143
+ _ => None ,
144
+ } )
145
+ . filter_map ( ast:: Whitespace :: cast)
146
+ . filter ( |ws| ws. text ( ) . contains ( '\n' ) ) ;
147
+ for ws in tokens {
148
+ let new_ws =
149
+ make:: tokens:: whitespace ( & ws. syntax ( ) . text ( ) . replace ( & format ! ( "\n {self}" ) , "\n " ) ) ;
150
+ editor. replace ( ws. syntax ( ) , & new_ws) ;
151
+ }
152
+ editor. finish ( ) . new_root ( ) . clone ( )
153
+ }
114
154
}
115
155
116
156
fn prev_tokens ( token : SyntaxToken ) -> impl Iterator < Item = SyntaxToken > {
117
157
iter:: successors ( Some ( token) , |token| token. prev_token ( ) )
118
158
}
119
159
120
- /// Soft-deprecated in favor of mutable tree editing API `edit_in_place::Ident`.
121
160
pub trait AstNodeEdit : AstNode + Clone + Sized {
122
161
fn indent_level ( & self ) -> IndentLevel {
123
162
IndentLevel :: from_node ( self . syntax ( ) )
124
163
}
125
164
#[ must_use]
126
165
fn indent ( & self , level : IndentLevel ) -> Self {
127
- fn indent_inner ( node : & SyntaxNode , level : IndentLevel ) -> SyntaxNode {
128
- let res = node. clone_subtree ( ) . clone_for_update ( ) ;
129
- level. increase_indent ( & res) ;
130
- res. clone_subtree ( )
166
+ Self :: cast ( level. clone_increase_indent ( self . syntax ( ) ) ) . unwrap ( )
167
+ }
168
+ #[ must_use]
169
+ fn indent_with_mapping ( & self , level : IndentLevel , make : & SyntaxFactory ) -> Self {
170
+ let new_node = self . indent ( level) ;
171
+ if let Some ( mut mapping) = make. mappings ( ) {
172
+ let mut builder = SyntaxMappingBuilder :: new ( new_node. syntax ( ) . clone ( ) ) ;
173
+ for ( old, new) in self . syntax ( ) . children ( ) . zip ( new_node. syntax ( ) . children ( ) ) {
174
+ builder. map_node ( old, new) ;
175
+ }
176
+ builder. finish ( & mut mapping) ;
131
177
}
132
-
133
- Self :: cast ( indent_inner ( self . syntax ( ) , level) ) . unwrap ( )
178
+ new_node
134
179
}
135
180
#[ must_use]
136
181
fn dedent ( & self , level : IndentLevel ) -> Self {
137
- fn dedent_inner ( node : & SyntaxNode , level : IndentLevel ) -> SyntaxNode {
138
- let res = node. clone_subtree ( ) . clone_for_update ( ) ;
139
- level. decrease_indent ( & res) ;
140
- res. clone_subtree ( )
141
- }
142
-
143
- Self :: cast ( dedent_inner ( self . syntax ( ) , level) ) . unwrap ( )
182
+ Self :: cast ( level. clone_decrease_indent ( self . syntax ( ) ) ) . unwrap ( )
144
183
}
145
184
#[ must_use]
146
185
fn reset_indent ( & self ) -> Self {
0 commit comments