mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 02:17:35 +03:00
Fix case-only renaming of files in project panel (#7835)
This is a follow-up to #7768 but now also fixes #5211. Explanation is relatively simple: case-only renames previously failed because while Zed would think that `foobar` and `FOOBAR` are different, the filesystem would give us an file-already-exists error when renaming. So what we're doing here is to check whether we're on a case-insensitive filesystem and if so, we overwrite the old file. Release Notes: - Fixed case-only renaming of files in project panel. ([#5211](https://github.com/zed-industries/zed/issues/5211)). Proof: https://github.com/zed-industries/zed/assets/1185253/57d5063f-09d9-47b1-a2df-3d7edefca97d
This commit is contained in:
parent
ed791c4fc1
commit
2dffc5f6e1
@ -93,6 +93,7 @@ pub struct LocalWorktree {
|
||||
diagnostic_summaries: HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>,
|
||||
client: Arc<Client>,
|
||||
fs: Arc<dyn Fs>,
|
||||
fs_case_sensitive: bool,
|
||||
visible: bool,
|
||||
}
|
||||
|
||||
@ -314,6 +315,13 @@ impl Worktree {
|
||||
.await
|
||||
.context("failed to stat worktree path")?;
|
||||
|
||||
let fs_case_sensitive = fs.is_case_sensitive().await.unwrap_or_else(|e| {
|
||||
log::error!(
|
||||
"Failed to determine whether filesystem is case sensitive (falling back to true) due to error: {e:#}"
|
||||
);
|
||||
true
|
||||
});
|
||||
|
||||
let closure_fs = Arc::clone(&fs);
|
||||
let closure_next_entry_id = Arc::clone(&next_entry_id);
|
||||
let closure_abs_path = abs_path.to_path_buf();
|
||||
@ -435,6 +443,7 @@ impl Worktree {
|
||||
diagnostic_summaries: Default::default(),
|
||||
client,
|
||||
fs,
|
||||
fs_case_sensitive,
|
||||
visible,
|
||||
})
|
||||
})
|
||||
@ -1301,9 +1310,29 @@ impl LocalWorktree {
|
||||
let abs_old_path = self.absolutize(&old_path);
|
||||
let abs_new_path = self.absolutize(&new_path);
|
||||
let fs = self.fs.clone();
|
||||
let case_sensitive = self.fs_case_sensitive;
|
||||
let rename = cx.background_executor().spawn(async move {
|
||||
fs.rename(&abs_old_path?, &abs_new_path?, Default::default())
|
||||
.await
|
||||
let abs_old_path = abs_old_path?;
|
||||
let abs_new_path = abs_new_path?;
|
||||
|
||||
let abs_old_path_lower = abs_old_path.to_str().map(|p| p.to_lowercase());
|
||||
let abs_new_path_lower = abs_new_path.to_str().map(|p| p.to_lowercase());
|
||||
|
||||
// If we're on a case-insensitive FS and we're doing a case-only rename (i.e. `foobar` to `FOOBAR`)
|
||||
// we want to overwrite, because otherwise we run into a file-already-exists error.
|
||||
let overwrite = !case_sensitive
|
||||
&& abs_old_path != abs_new_path
|
||||
&& abs_old_path_lower == abs_new_path_lower;
|
||||
|
||||
fs.rename(
|
||||
&abs_old_path,
|
||||
&abs_new_path,
|
||||
fs::RenameOptions {
|
||||
overwrite,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
});
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
|
Loading…
Reference in New Issue
Block a user