Skip to content

Commit b9275f1

Browse files
committed
feat: implement Removable trait for ast::Use and ast::UseTree
Signed-off-by: Tarek <[email protected]>
1 parent 52dd11e commit b9275f1

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

crates/syntax/src/syntax_editor/edits.rs

+65-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! Structural editing for ast using `SyntaxEditor`
22
33
use crate::{
4+
algo::neighbor,
45
ast::{
5-
self, edit::IndentLevel, make, syntax_factory::SyntaxFactory, AstNode, Fn, GenericParam,
6-
HasGenericParams, HasName,
6+
self, edit::IndentLevel, make, syntax_factory::SyntaxFactory, AstNode, AstToken, Fn,
7+
GenericParam, HasGenericParams, HasName,
78
},
89
syntax_editor::{Position, SyntaxEditor},
910
Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T,
@@ -143,6 +144,68 @@ fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) ->
143144
Some(())
144145
}
145146

147+
pub trait Removable: AstNode {
148+
fn remove(&self, editor: &mut SyntaxEditor);
149+
}
150+
151+
impl Removable for ast::Use {
152+
fn remove(&self, editor: &mut SyntaxEditor) {
153+
let make = SyntaxFactory::new();
154+
155+
let next_ws = self
156+
.syntax()
157+
.next_sibling_or_token()
158+
.and_then(|it| it.into_token())
159+
.and_then(ast::Whitespace::cast);
160+
if let Some(next_ws) = next_ws {
161+
let ws_text = next_ws.syntax().text();
162+
if let Some(rest) = ws_text.strip_prefix('\n') {
163+
if rest.is_empty() {
164+
editor.delete(next_ws.syntax());
165+
} else {
166+
editor.replace(next_ws.syntax(), make.whitespace(rest));
167+
}
168+
}
169+
}
170+
let prev_ws = self
171+
.syntax()
172+
.prev_sibling_or_token()
173+
.and_then(|it| it.into_token())
174+
.and_then(ast::Whitespace::cast);
175+
if let Some(prev_ws) = prev_ws {
176+
let ws_text = prev_ws.syntax().text();
177+
let prev_newline = ws_text.rfind('\n').map(|x| x + 1).unwrap_or(0);
178+
let rest = &ws_text[0..prev_newline];
179+
if rest.is_empty() {
180+
editor.delete(prev_ws.syntax());
181+
} else {
182+
editor.replace(prev_ws.syntax(), make.whitespace(rest));
183+
}
184+
}
185+
186+
editor.delete(self.syntax());
187+
}
188+
}
189+
190+
impl Removable for ast::UseTree {
191+
fn remove(&self, editor: &mut SyntaxEditor) {
192+
for dir in [Direction::Next, Direction::Prev] {
193+
if let Some(next_use_tree) = neighbor(self, dir) {
194+
let separators = self
195+
.syntax()
196+
.siblings_with_tokens(dir)
197+
.skip(1)
198+
.take_while(|it| it.as_node() != Some(next_use_tree.syntax()));
199+
for sep in separators {
200+
editor.delete(sep);
201+
}
202+
break;
203+
}
204+
}
205+
editor.delete(self.syntax());
206+
}
207+
}
208+
146209
#[cfg(test)]
147210
mod tests {
148211
use parser::Edition;

0 commit comments

Comments
 (0)