@@ -6,9 +6,12 @@ use std::{fmt, iter, ops};
66use crate :: {
77 AstToken , NodeOrToken , SyntaxElement , SyntaxNode , SyntaxToken ,
88 ast:: { self , AstNode , make} ,
9+ syntax_editor:: { SyntaxEditor , SyntaxMappingBuilder } ,
910 ted,
1011} ;
1112
13+ use super :: syntax_factory:: SyntaxFactory ;
14+
1215#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
1316pub struct IndentLevel ( pub u8 ) ;
1417
@@ -95,6 +98,24 @@ impl IndentLevel {
9598 }
9699 }
97100
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+
98119 pub ( super ) fn decrease_indent ( self , node : & SyntaxNode ) {
99120 let tokens = node. preorder_with_tokens ( ) . filter_map ( |event| match event {
100121 rowan:: WalkEvent :: Leave ( NodeOrToken :: Token ( it) ) => Some ( it) ,
@@ -111,36 +132,54 @@ impl IndentLevel {
111132 }
112133 }
113134 }
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+ }
114154}
115155
116156fn prev_tokens ( token : SyntaxToken ) -> impl Iterator < Item = SyntaxToken > {
117157 iter:: successors ( Some ( token) , |token| token. prev_token ( ) )
118158}
119159
120- /// Soft-deprecated in favor of mutable tree editing API `edit_in_place::Ident`.
121160pub trait AstNodeEdit : AstNode + Clone + Sized {
122161 fn indent_level ( & self ) -> IndentLevel {
123162 IndentLevel :: from_node ( self . syntax ( ) )
124163 }
125164 #[ must_use]
126165 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) ;
131177 }
132-
133- Self :: cast ( indent_inner ( self . syntax ( ) , level) ) . unwrap ( )
178+ new_node
134179 }
135180 #[ must_use]
136181 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 ( )
144183 }
145184 #[ must_use]
146185 fn reset_indent ( & self ) -> Self {
0 commit comments