mirror of
https://github.com/zed-industries/zed.git
synced 2026-10-20 03:24:42 +00:00
project_panel: Allow renaming a root to match a child directory (#64268)
# Objective - Allow renaming a project root folder to the same name as one of its child folders. - Fixes #64255 ## Solution - Skip child-entry collision checks when renaming a project root. - Keep existing collision checks for other entries. ## Testing - Updated and ran `test_rename_root_of_worktree`. - Manually tested on macOS. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed an issue where a project root folder could not be renamed to match a child folder. --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
This commit is contained in:
parent
05c2c9aba0
commit
02238cd4b7
2 changed files with 34 additions and 28 deletions
|
|
@ -2041,10 +2041,8 @@ impl ProjectPanel {
|
|||
return;
|
||||
};
|
||||
|
||||
if let Some(worktree) = self
|
||||
.project
|
||||
.read(cx)
|
||||
.worktree_for_id(edit_state.worktree_id, cx)
|
||||
let project = self.project.read(cx);
|
||||
if let Some(worktree) = project.worktree_for_id(edit_state.worktree_id, cx)
|
||||
&& let Some(entry) = worktree.read(cx).entry_for_id(edit_state.entry_id)
|
||||
{
|
||||
let mut already_exists = false;
|
||||
|
|
@ -2054,12 +2052,18 @@ impl ProjectPanel {
|
|||
already_exists = true;
|
||||
}
|
||||
} else {
|
||||
let new_path = if let Some(parent) = entry.path.clone().parent() {
|
||||
parent.join(&filename)
|
||||
} else {
|
||||
filename.to_owned()
|
||||
let new_path = match entry.path.clone().parent() {
|
||||
Some(parent) => parent.join(&filename),
|
||||
None => filename.to_owned(),
|
||||
};
|
||||
if let Some(existing) = worktree.read(cx).entry_for_path(&new_path)
|
||||
|
||||
// We skip the collision check for worktree roots as the
|
||||
// lookup resolves paths relative to the root itself,
|
||||
// whereas renaming the root should resolve it against its
|
||||
// parent directory. Otherwise, renaming `bar/` to `foo/`
|
||||
// would report a false collision with `bar/foo/`.
|
||||
if !project.entry_is_worktree_root(entry.id, cx)
|
||||
&& let Some(existing) = worktree.read(cx).entry_for_path(&new_path)
|
||||
&& existing.id != entry.id
|
||||
{
|
||||
already_exists = true;
|
||||
|
|
@ -2142,12 +2146,19 @@ impl ProjectPanel {
|
|||
});
|
||||
changes = vec![Change::Created(new_project_path)];
|
||||
} else {
|
||||
let new_path = if let Some(parent) = entry.path.parent() {
|
||||
parent.join(&filename).into()
|
||||
} else {
|
||||
filename.clone()
|
||||
let new_path = match entry.path.parent() {
|
||||
Some(parent) => parent.join(&filename).into(),
|
||||
None => filename.clone(),
|
||||
};
|
||||
if let Some(existing) = worktree.read(cx).entry_for_path(&new_path) {
|
||||
|
||||
// We skip the collision check for worktree roots as the lookup
|
||||
// resolves paths relative to the root itself, whereas renaming the
|
||||
// root should resolve it against its parent directory. Otherwise,
|
||||
// renaming `bar/` to `foo/` would report a false collision with
|
||||
// `bar/foo/`.
|
||||
if !self.project.read(cx).entry_is_worktree_root(entry.id, cx)
|
||||
&& let Some(existing) = worktree.read(cx).entry_for_path(&new_path)
|
||||
{
|
||||
if existing.id == entry.id && refocus {
|
||||
window.focus(&self.focus_handle, cx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4620,7 +4620,7 @@ async fn test_rename_root_of_worktree(cx: &mut gpui::TestAppContext) {
|
|||
&["v root1 <== selected", " v dir1", " file1.txt",],
|
||||
);
|
||||
|
||||
// Rename root1 to new_root1
|
||||
// Rename root1 to match the name of its child directory.
|
||||
panel.update_in(cx, |panel, window, cx| panel.rename(&Rename, window, cx));
|
||||
|
||||
assert_eq!(
|
||||
|
|
@ -4635,30 +4635,25 @@ async fn test_rename_root_of_worktree(cx: &mut gpui::TestAppContext) {
|
|||
let confirm = panel.update_in(cx, |panel, window, cx| {
|
||||
panel
|
||||
.filename_editor
|
||||
.update(cx, |editor, cx| editor.set_text("new_root1", window, cx));
|
||||
panel.confirm_edit(true, window, cx).unwrap()
|
||||
.update(cx, |editor, cx| editor.set_text("dir1", window, cx));
|
||||
|
||||
panel
|
||||
.confirm_edit(true, window, cx)
|
||||
.expect("should be able to rename `root1` to `dir1`")
|
||||
});
|
||||
confirm.await.unwrap();
|
||||
cx.run_until_parked();
|
||||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v new_root1 <== selected",
|
||||
" v dir1",
|
||||
" file1.txt",
|
||||
],
|
||||
&["v dir1 <== selected", " v dir1", " file1.txt",],
|
||||
"Should update worktree name"
|
||||
);
|
||||
|
||||
// Ensure internal paths have been updated
|
||||
select_path(&panel, "new_root1/dir1/file1.txt", cx);
|
||||
select_path(&panel, "dir1/dir1/file1.txt", cx);
|
||||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v new_root1",
|
||||
" v dir1",
|
||||
" file1.txt <== selected",
|
||||
],
|
||||
&["v dir1", " v dir1", " file1.txt <== selected",],
|
||||
"Files in renamed worktree are selectable"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue