aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ide/src/move_item.rs184
1 files changed, 124 insertions, 60 deletions
diff --git a/crates/ide/src/move_item.rs b/crates/ide/src/move_item.rs
index dbbf2f4c9..906d0f268 100644
--- a/crates/ide/src/move_item.rs
+++ b/crates/ide/src/move_item.rs
@@ -38,44 +38,42 @@ fn find_ancestors(item: SyntaxElement, direction: Direction) -> Option<TextEdit>
38 NodeOrToken::Token(token) => token.parent()?, 38 NodeOrToken::Token(token) => token.parent()?,
39 }; 39 };
40 40
41 let movable = [
42 SyntaxKind::MATCH_ARM,
43 SyntaxKind::PARAM,
44 SyntaxKind::LET_STMT,
45 SyntaxKind::EXPR_STMT,
46 SyntaxKind::MATCH_EXPR,
47 SyntaxKind::MACRO_CALL,
48 SyntaxKind::TYPE_ALIAS,
49 SyntaxKind::TRAIT,
50 SyntaxKind::IMPL,
51 SyntaxKind::MACRO_DEF,
52 SyntaxKind::STRUCT,
53 SyntaxKind::UNION,
54 SyntaxKind::ENUM,
55 SyntaxKind::FN,
56 SyntaxKind::MODULE,
57 SyntaxKind::USE,
58 SyntaxKind::STATIC,
59 SyntaxKind::CONST,
60 SyntaxKind::MACRO_RULES,
61 ];
62
41 let ancestor = once(root.clone()) 63 let ancestor = once(root.clone())
42 .chain(root.ancestors()) 64 .chain(root.ancestors())
43 .filter_map(|ancestor| kind_priority(ancestor.kind()).map(|priority| (priority, ancestor))) 65 .find(|ancestor| movable.contains(&ancestor.kind()))?;
44 .max_by_key(|(priority, _)| *priority)
45 .map(|(_, ancestor)| ancestor)?;
46 66
47 move_in_direction(&ancestor, direction) 67 move_in_direction(&ancestor, direction)
48} 68}
49 69
50fn kind_priority(kind: SyntaxKind) -> Option<i32> {
51 match kind {
52 SyntaxKind::MATCH_ARM => Some(4),
53
54 SyntaxKind::LET_STMT | SyntaxKind::EXPR_STMT | SyntaxKind::MATCH_EXPR => Some(3),
55
56 SyntaxKind::TRAIT
57 | SyntaxKind::IMPL
58 | SyntaxKind::MACRO_CALL
59 | SyntaxKind::MACRO_DEF
60 | SyntaxKind::STRUCT
61 | SyntaxKind::ENUM
62 | SyntaxKind::MODULE
63 | SyntaxKind::USE
64 | SyntaxKind::FN
65 | SyntaxKind::CONST
66 | SyntaxKind::TYPE_ALIAS => Some(2),
67
68 _ => None,
69 }
70}
71
72fn move_in_direction(node: &SyntaxNode, direction: Direction) -> Option<TextEdit> { 70fn move_in_direction(node: &SyntaxNode, direction: Direction) -> Option<TextEdit> {
73 let sibling = match direction { 71 let sibling = match direction {
74 Direction::Up => node.prev_sibling(), 72 Direction::Up => node.prev_sibling(),
75 Direction::Down => node.next_sibling(), 73 Direction::Down => node.next_sibling(),
76 }?; 74 }?;
77 75
78 Some(replace_nodes(&sibling, node)) 76 Some(replace_nodes(node, &sibling))
79} 77}
80 78
81fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit { 79fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit {
@@ -215,39 +213,6 @@ fn main() {
215 } 213 }
216 214
217 #[test] 215 #[test]
218 fn test_prioritizes_match_arm() {
219 check(
220 r#"
221fn main() {
222 match true {
223 true => {
224 let test = 123;$0$0
225 let test2 = 456;
226 },
227 false => {
228 println!("Test");
229 }
230 };
231}
232 "#,
233 expect![[r#"
234fn main() {
235 match true {
236 false => {
237 println!("Test");
238 },
239 true => {
240 let test = 123;
241 let test2 = 456;
242 }
243 };
244}
245 "#]],
246 Direction::Down,
247 );
248 }
249
250 #[test]
251 fn test_moves_expr_up() { 216 fn test_moves_expr_up() {
252 check( 217 check(
253 r#" 218 r#"
@@ -348,7 +313,7 @@ fn main() {
348 $0match test { 313 $0match test {
349 456 => {}, 314 456 => {},
350 _ => {} 315 _ => {}
351 }$0; 316 };$0
352} 317}
353 "#, 318 "#,
354 expect![[r#" 319 expect![[r#"
@@ -366,6 +331,105 @@ fn main() {
366 } 331 }
367 332
368 #[test] 333 #[test]
334 fn moves_param_up() {
335 check(
336 r#"
337fn test(one: i32, two$0$0: u32) {}
338
339fn main() {
340 test(123, 456);
341}
342 "#,
343 expect![[r#"
344fn test(two: u32, one: i32) {}
345
346fn main() {
347 test(123, 456);
348}
349 "#]],
350 Direction::Up,
351 );
352 }
353
354 #[test]
355 fn test_prioritizes_trait_items() {
356 check(
357 r#"
358struct Test;
359
360trait Yay {
361 type One;
362
363 type Two;
364
365 fn inner();
366}
367
368impl Yay for Test {
369 type One = i32;
370
371 type Two = u32;
372
373 fn inner() {$0$0
374 println!("Mmmm");
375 }
376}
377 "#,
378 expect![[r#"
379struct Test;
380
381trait Yay {
382 type One;
383
384 type Two;
385
386 fn inner();
387}
388
389impl Yay for Test {
390 type One = i32;
391
392 fn inner() {
393 println!("Mmmm");
394 }
395
396 type Two = u32;
397}
398 "#]],
399 Direction::Up,
400 );
401 }
402
403 #[test]
404 fn test_weird_nesting() {
405 check(
406 r#"
407fn test() {
408 mod hello {
409 fn inner() {}
410 }
411
412 mod hi {$0$0
413 fn inner() {}
414 }
415}
416 "#,
417 expect![[r#"
418fn test() {
419 mod hi {
420 fn inner() {}
421 }
422
423 mod hello {
424 fn inner() {}
425 }
426}
427 "#]],
428 Direction::Up,
429 );
430 }
431
432 #[test]
369 fn handles_empty_file() { 433 fn handles_empty_file() {
370 check(r#"$0$0"#, expect![[r#""#]], Direction::Up); 434 check(r#"$0$0"#, expect![[r#""#]], Direction::Up);
371 } 435 }