diff options
Diffstat (limited to 'crates/ra_editor/src/assists/flip_comma.rs')
-rw-r--r-- | crates/ra_editor/src/assists/flip_comma.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/crates/ra_editor/src/assists/flip_comma.rs b/crates/ra_editor/src/assists/flip_comma.rs new file mode 100644 index 000000000..d8727db0d --- /dev/null +++ b/crates/ra_editor/src/assists/flip_comma.rs | |||
@@ -0,0 +1,45 @@ | |||
1 | use ra_text_edit::TextEditBuilder; | ||
2 | use ra_syntax::{ | ||
3 | algo::find_leaf_at_offset, | ||
4 | Direction, SourceFileNode, | ||
5 | SyntaxKind::COMMA, | ||
6 | TextUnit, | ||
7 | }; | ||
8 | |||
9 | use crate::assists::{LocalEdit, non_trivia_sibling}; | ||
10 | |||
11 | pub fn flip_comma<'a>( | ||
12 | file: &'a SourceFileNode, | ||
13 | offset: TextUnit, | ||
14 | ) -> Option<impl FnOnce() -> LocalEdit + 'a> { | ||
15 | let syntax = file.syntax(); | ||
16 | |||
17 | let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?; | ||
18 | let prev = non_trivia_sibling(comma, Direction::Prev)?; | ||
19 | let next = non_trivia_sibling(comma, Direction::Next)?; | ||
20 | Some(move || { | ||
21 | let mut edit = TextEditBuilder::new(); | ||
22 | edit.replace(prev.range(), next.text().to_string()); | ||
23 | edit.replace(next.range(), prev.text().to_string()); | ||
24 | LocalEdit { | ||
25 | label: "flip comma".to_string(), | ||
26 | edit: edit.finish(), | ||
27 | cursor_position: None, | ||
28 | } | ||
29 | }) | ||
30 | } | ||
31 | |||
32 | #[cfg(test)] | ||
33 | mod tests { | ||
34 | use super::*; | ||
35 | use crate::test_utils::check_action; | ||
36 | |||
37 | #[test] | ||
38 | fn test_swap_comma() { | ||
39 | check_action( | ||
40 | "fn foo(x: i32,<|> y: Result<(), ()>) {}", | ||
41 | "fn foo(y: Result<(), ()>,<|> x: i32) {}", | ||
42 | |file, off| flip_comma(file, off).map(|f| f()), | ||
43 | ) | ||
44 | } | ||
45 | } | ||