diff options
author | Aleksey Kladov <[email protected]> | 2018-08-12 16:50:16 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-12 16:50:16 +0100 |
commit | 66be735aa98c32fb062d1c756fa9303ff2d13002 (patch) | |
tree | d679bef9b4005f969cfa5a369c6804195de6c779 /crates/libeditor/src/code_actions.rs | |
parent | 56aa6e20e0279c69e0130905573b1607056cfaf9 (diff) |
flip comma
Diffstat (limited to 'crates/libeditor/src/code_actions.rs')
-rw-r--r-- | crates/libeditor/src/code_actions.rs | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs new file mode 100644 index 000000000..7c9874588 --- /dev/null +++ b/crates/libeditor/src/code_actions.rs | |||
@@ -0,0 +1,33 @@ | |||
1 | use {TextUnit, File, EditBuilder, Edit}; | ||
2 | use libsyntax2::{ | ||
3 | ast::AstNode, | ||
4 | SyntaxKind::COMMA, | ||
5 | SyntaxNodeRef, | ||
6 | algo::{ | ||
7 | Direction, siblings, | ||
8 | find_leaf_at_offset, | ||
9 | }, | ||
10 | }; | ||
11 | |||
12 | pub fn flip_comma<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> Edit + 'a> { | ||
13 | let syntax = file.syntax(); | ||
14 | let syntax = syntax.as_ref(); | ||
15 | |||
16 | let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?; | ||
17 | let left = non_trivia_sibling(comma, Direction::Backward)?; | ||
18 | let right = non_trivia_sibling(comma, Direction::Forward)?; | ||
19 | Some(move || { | ||
20 | let mut edit = EditBuilder::new(); | ||
21 | edit.replace(left.range(), right.text()); | ||
22 | edit.replace(right.range(), left.text()); | ||
23 | edit.finish() | ||
24 | }) | ||
25 | } | ||
26 | |||
27 | fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { | ||
28 | siblings(node, direction) | ||
29 | .skip(1) | ||
30 | .find(|node| !node.kind().is_trivia()) | ||
31 | } | ||
32 | |||
33 | |||