diff options
author | Andrea Pretto <[email protected]> | 2019-04-19 21:30:05 +0100 |
---|---|---|
committer | Andrea Pretto <[email protected]> | 2019-04-21 23:13:00 +0100 |
commit | cf0eff2e332f46eda4fcecb043854c9c0d710e4e (patch) | |
tree | 8744a06eb4c7e05a9242af21774521058aad2475 | |
parent | 766813898f7901736d82bfc103874474177e7aca (diff) |
auto_import: better no anchor management
-rw-r--r-- | crates/ra_assists/src/auto_import.rs | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs index 7527d805d..b002d0e4d 100644 --- a/crates/ra_assists/src/auto_import.rs +++ b/crates/ra_assists/src/auto_import.rs | |||
@@ -168,7 +168,7 @@ fn walk_use_tree_for_best_action<'a>( | |||
168 | current_path_segments: &mut Vec<&'a ast::PathSegment>, // buffer containing path segments | 168 | current_path_segments: &mut Vec<&'a ast::PathSegment>, // buffer containing path segments |
169 | current_parent_use_tree_list: Option<&'a ast::UseTreeList>, // will be Some value if we are in a nested import | 169 | current_parent_use_tree_list: Option<&'a ast::UseTreeList>, // will be Some value if we are in a nested import |
170 | current_use_tree: &'a ast::UseTree, // the use tree we are currently examinating | 170 | current_use_tree: &'a ast::UseTree, // the use tree we are currently examinating |
171 | target: &[SmolStr], // the path we want to import | 171 | target: &[SmolStr], // the path we want to import |
172 | ) -> ImportAction<'a> { | 172 | ) -> ImportAction<'a> { |
173 | // We save the number of segments in the buffer so we can restore the correct segments | 173 | // We save the number of segments in the buffer so we can restore the correct segments |
174 | // before returning. Recursive call will add segments so we need to delete them. | 174 | // before returning. Recursive call will add segments so we need to delete them. |
@@ -341,11 +341,11 @@ fn best_action_for_target<'b, 'a: 'b>( | |||
341 | None => { | 341 | None => { |
342 | // We have no action and no UseItem was found in container so we find | 342 | // We have no action and no UseItem was found in container so we find |
343 | // another item and we use it as anchor. | 343 | // another item and we use it as anchor. |
344 | // If there are no items, we choose the target path itself as anchor. | 344 | // If there are no items above, we choose the target path itself as anchor. |
345 | // todo: we should include even whitespace blocks as anchor candidates | ||
345 | let anchor = container | 346 | let anchor = container |
346 | .children() | 347 | .children() |
347 | .find_map(ast::ModuleItem::cast) | 348 | .find(|n| n.range().start() < anchor.range().start()) |
348 | .map(AstNode::syntax) | ||
349 | .or(Some(anchor)); | 349 | .or(Some(anchor)); |
350 | 350 | ||
351 | return ImportAction::add_new_use(anchor, false); | 351 | return ImportAction::add_new_use(anchor, false); |
@@ -498,9 +498,9 @@ pub fn collect_hir_path_segments(path: &hir::Path) -> Vec<SmolStr> { | |||
498 | match path.kind { | 498 | match path.kind { |
499 | hir::PathKind::Abs => ps.push("".into()), | 499 | hir::PathKind::Abs => ps.push("".into()), |
500 | hir::PathKind::Crate => ps.push("crate".into()), | 500 | hir::PathKind::Crate => ps.push("crate".into()), |
501 | hir::PathKind::Plain => {}, | 501 | hir::PathKind::Plain => {} |
502 | hir::PathKind::Self_ => ps.push("self".into()), | 502 | hir::PathKind::Self_ => ps.push("self".into()), |
503 | hir::PathKind::Super => ps.push("super".into()) | 503 | hir::PathKind::Super => ps.push("super".into()), |
504 | } | 504 | } |
505 | for s in path.segments.iter() { | 505 | for s in path.segments.iter() { |
506 | ps.push(s.name.to_smolstr()); | 506 | ps.push(s.name.to_smolstr()); |
@@ -513,7 +513,7 @@ pub fn collect_hir_path_segments(path: &hir::Path) -> Vec<SmolStr> { | |||
513 | // the cursor position | 513 | // the cursor position |
514 | #[allow(unused)] | 514 | #[allow(unused)] |
515 | pub fn auto_import_text_edit( | 515 | pub fn auto_import_text_edit( |
516 | // Ideally the position of the cursor, used to | 516 | // Ideally the position of the cursor, used to |
517 | position: &SyntaxNode, | 517 | position: &SyntaxNode, |
518 | // The statement to use as anchor (last resort) | 518 | // The statement to use as anchor (last resort) |
519 | anchor: &SyntaxNode, | 519 | anchor: &SyntaxNode, |
@@ -594,6 +594,47 @@ Debug<|> | |||
594 | ", | 594 | ", |
595 | ); | 595 | ); |
596 | } | 596 | } |
597 | #[test] | ||
598 | fn test_auto_import_add_use_no_anchor_with_item_below() { | ||
599 | check_assist( | ||
600 | auto_import, | ||
601 | " | ||
602 | std::fmt::Debug<|> | ||
603 | |||
604 | fn main() { | ||
605 | } | ||
606 | ", | ||
607 | " | ||
608 | use std::fmt::Debug; | ||
609 | |||
610 | Debug<|> | ||
611 | |||
612 | fn main() { | ||
613 | } | ||
614 | ", | ||
615 | ); | ||
616 | } | ||
617 | |||
618 | #[test] | ||
619 | fn test_auto_import_add_use_no_anchor_with_item_above() { | ||
620 | check_assist( | ||
621 | auto_import, | ||
622 | " | ||
623 | fn main() { | ||
624 | } | ||
625 | |||
626 | std::fmt::Debug<|> | ||
627 | ", | ||
628 | " | ||
629 | use std::fmt::Debug; | ||
630 | |||
631 | fn main() { | ||
632 | } | ||
633 | |||
634 | Debug<|> | ||
635 | ", | ||
636 | ); | ||
637 | } | ||
597 | 638 | ||
598 | #[test] | 639 | #[test] |
599 | fn test_auto_import_add_use_no_anchor_2seg() { | 640 | fn test_auto_import_add_use_no_anchor_2seg() { |