Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit fc00602

Browse files
committed
merge imports assist avoids adding unnecessary braces when merging nested use tree selections
1 parent b241593 commit fc00602

File tree

1 file changed

+53
-5
lines changed

1 file changed

+53
-5
lines changed

crates/ide-assists/src/handlers/merge_imports.rs

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use either::Either;
22
use ide_db::imports::{
33
insert_use::{ImportGranularity, InsertUseConfig},
4-
merge_imports::{try_merge_imports, try_merge_trees, MergeBehavior},
4+
merge_imports::{try_merge_imports, try_merge_trees, try_normalize_use_tree, MergeBehavior},
55
};
6+
use itertools::Itertools;
67
use syntax::{
78
algo::neighbor,
89
ast::{self, edit_in_place::Removable},
@@ -83,7 +84,35 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
8384
for edit in edits_mut {
8485
match edit {
8586
Remove(it) => it.as_ref().either(Removable::remove, Removable::remove),
86-
Replace(old, new) => ted::replace(old, new),
87+
Replace(old, new) => {
88+
ted::replace(old, &new);
89+
90+
// If there's a selection and we're replacing a use tree in a tree list,
91+
// normalize the parent use tree if it only contains the merged subtree.
92+
if !ctx.has_empty_selection() {
93+
let normalized_use_tree = ast::UseTree::cast(new)
94+
.as_ref()
95+
.and_then(ast::UseTree::parent_use_tree_list)
96+
.and_then(|use_tree_list| {
97+
if use_tree_list.use_trees().collect_tuple::<(_,)>().is_some() {
98+
Some(use_tree_list.parent_use_tree())
99+
} else {
100+
None
101+
}
102+
})
103+
.and_then(|target_tree| {
104+
try_normalize_use_tree(
105+
&target_tree,
106+
ctx.config.insert_use.granularity.into(),
107+
)
108+
.map(|top_use_tree_flat| (target_tree, top_use_tree_flat))
109+
});
110+
if let Some((old_tree, new_tree)) = normalized_use_tree {
111+
cov_mark::hit!(replace_parent_with_normalized_use_tree);
112+
ted::replace(old_tree.syntax(), new_tree.syntax());
113+
}
114+
}
115+
}
87116
}
88117
}
89118
},
@@ -148,7 +177,10 @@ impl Edit {
148177

149178
#[cfg(test)]
150179
mod tests {
151-
use crate::tests::{check_assist, check_assist_import_one, check_assist_not_applicable};
180+
use crate::tests::{
181+
check_assist, check_assist_import_one, check_assist_not_applicable,
182+
check_assist_not_applicable_for_import_one,
183+
};
152184

153185
use super::*;
154186

@@ -258,6 +290,15 @@ use std::fmt::{self, Display};
258290
);
259291
}
260292

293+
#[test]
294+
fn not_applicable_to_single_import() {
295+
check_assist_not_applicable(merge_imports, "use std::{fmt, $0fmt::Display};");
296+
check_assist_not_applicable_for_import_one(
297+
merge_imports,
298+
"use {std::{fmt, $0fmt::Display}};",
299+
);
300+
}
301+
261302
#[test]
262303
fn skip_pub1() {
263304
check_assist_not_applicable(
@@ -658,12 +699,19 @@ use std::{
658699
};",
659700
);
660701

661-
// FIXME: Remove redundant braces. See also unnecessary-braces diagnostic.
662702
cov_mark::check!(merge_with_selected_use_tree_neighbors);
703+
check_assist(
704+
merge_imports,
705+
r"use std::{fmt::Result, $0fmt::Display, fmt::Debug$0};",
706+
r"use std::{fmt::Result, fmt::{Debug, Display}};",
707+
);
708+
709+
cov_mark::check!(merge_with_selected_use_tree_neighbors);
710+
cov_mark::check!(replace_parent_with_normalized_use_tree);
663711
check_assist(
664712
merge_imports,
665713
r"use std::$0{fmt::Display, fmt::Debug}$0;",
666-
r"use std::{fmt::{Debug, Display}};",
714+
r"use std::fmt::{Debug, Display};",
667715
);
668716
}
669717
}

0 commit comments

Comments
 (0)