diff options
-rw-r--r-- | crates/ide/src/move_item.rs | 184 |
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 | ||
50 | fn 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 | |||
72 | fn move_in_direction(node: &SyntaxNode, direction: Direction) -> Option<TextEdit> { | 70 | fn 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 | ||
81 | fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit { | 79 | fn 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#" | ||
221 | fn 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#" | ||
234 | fn 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#" | ||
337 | fn test(one: i32, two$0$0: u32) {} | ||
338 | |||
339 | fn main() { | ||
340 | test(123, 456); | ||
341 | } | ||
342 | "#, | ||
343 | expect![[r#" | ||
344 | fn test(two: u32, one: i32) {} | ||
345 | |||
346 | fn 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#" | ||
358 | struct Test; | ||
359 | |||
360 | trait Yay { | ||
361 | type One; | ||
362 | |||
363 | type Two; | ||
364 | |||
365 | fn inner(); | ||
366 | } | ||
367 | |||
368 | impl 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#" | ||
379 | struct Test; | ||
380 | |||
381 | trait Yay { | ||
382 | type One; | ||
383 | |||
384 | type Two; | ||
385 | |||
386 | fn inner(); | ||
387 | } | ||
388 | |||
389 | impl 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#" | ||
407 | fn test() { | ||
408 | mod hello { | ||
409 | fn inner() {} | ||
410 | } | ||
411 | |||
412 | mod hi {$0$0 | ||
413 | fn inner() {} | ||
414 | } | ||
415 | } | ||
416 | "#, | ||
417 | expect![[r#" | ||
418 | fn 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 | } |