From 96fc01a30b88d95619b26fd96c58627dd54cb339 Mon Sep 17 00:00:00 2001 From: asv Date: Sat, 6 Mar 2021 13:02:26 +0200 Subject: Make group imports configurable --- crates/ide_db/src/helpers/insert_use.rs | 17 +++++++++--- crates/ide_db/src/helpers/insert_use/tests.rs | 38 ++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) (limited to 'crates/ide_db') diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index fd4035198..f52aee344 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs @@ -19,6 +19,7 @@ use test_utils::mark; pub struct InsertUseConfig { pub merge: Option, pub prefix_kind: hir::PrefixKind, + pub group: bool, } #[derive(Debug, Clone)] @@ -99,13 +100,13 @@ fn is_inner_comment(token: SyntaxToken) -> bool { pub fn insert_use<'a>( scope: &ImportScope, path: ast::Path, - merge: Option, + cfg: InsertUseConfig, ) -> SyntaxRewriter<'a> { let _p = profile::span("insert_use"); let mut rewriter = SyntaxRewriter::default(); let use_item = make::use_(None, make::use_tree(path.clone(), None, None, false)); // merge into existing imports if possible - if let Some(mb) = merge { + if let Some(mb) = cfg.merge { for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) { if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { rewriter.replace(existing_use.syntax(), merged.syntax()); @@ -116,7 +117,7 @@ pub fn insert_use<'a>( // either we weren't allowed to merge or there is no import that fits the merge conditions // so look for the place we have to insert to - let (insert_position, add_blank) = find_insert_position(scope, path); + let (insert_position, add_blank) = find_insert_position(scope, path, cfg.group); let indent = if let ident_level @ 1..=usize::MAX = scope.indent_level().0 as usize { Some(make::tokens::whitespace(&" ".repeat(4 * ident_level)).into()) @@ -538,6 +539,7 @@ impl AddBlankLine { fn find_insert_position( scope: &ImportScope, insert_path: ast::Path, + group_imports: bool, ) -> (InsertPosition, AddBlankLine) { let group = ImportGroup::new(&insert_path); let path_node_iter = scope @@ -550,6 +552,14 @@ fn find_insert_position( let has_tl = tree.use_tree_list().is_some(); Some((path, has_tl, node)) }); + + if !group_imports { + if let Some((_, _, node)) = path_node_iter.last() { + return (InsertPosition::After(node.into()), AddBlankLine::Before); + } + return (InsertPosition::First, AddBlankLine::AfterTwice); + } + // Iterator that discards anything thats not in the required grouping // This implementation allows the user to rearrange their import groups as this only takes the first group that fits let group_iter = path_node_iter @@ -565,6 +575,7 @@ fn find_insert_position( use_tree_path_cmp(&insert_path, false, path, has_tl) != Ordering::Greater }, ); + match post_insert { // insert our import before that element Some((.., node)) => (InsertPosition::Before(node.into()), AddBlankLine::After), diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index 4bbe66f1f..67d0d6fb6 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs @@ -1,7 +1,31 @@ use super::*; +use hir::PrefixKind; use test_utils::assert_eq_text; +#[test] +fn insert_not_group() { + check( + "use external_crate2::bar::A", + r" +use std::bar::B; +use external_crate::bar::A; +use crate::bar::A; +use self::bar::A; +use super::bar::A;", + r" +use std::bar::B; +use external_crate::bar::A; +use crate::bar::A; +use self::bar::A; +use super::bar::A; +use external_crate2::bar::A;", + None, + false, + false, + ); +} + #[test] fn insert_existing() { check_full("std::fs", "use std::fs;", "use std::fs;") @@ -240,6 +264,7 @@ fn insert_empty_module() { }", None, true, + true, ) } @@ -584,6 +609,7 @@ fn check( ra_fixture_after: &str, mb: Option, module: bool, + group: bool, ) { let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone(); if module { @@ -597,21 +623,25 @@ fn check( .find_map(ast::Path::cast) .unwrap(); - let rewriter = insert_use(&file, path, mb); + let rewriter = insert_use( + &file, + path, + InsertUseConfig { merge: mb, prefix_kind: PrefixKind::Plain, group }, + ); let result = rewriter.rewrite(file.as_syntax_node()).to_string(); assert_eq_text!(ra_fixture_after, &result); } fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { - check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Full), false) + check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Full), false, true) } fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { - check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Last), false) + check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Last), false, true) } fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { - check(path, ra_fixture_before, ra_fixture_after, None, false) + check(path, ra_fixture_before, ra_fixture_after, None, false, true) } fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior) { -- cgit v1.2.3