project: Fix inability to open file after save as (#41012)
Update `project::buffer_store::BufferStore.save_buffer_as` in order to correctly update the `path_to_buffer_id` hash map, ensuring that the currently open file's path is dissociated from the buffer's id, to prevent the new buffer from being open when trying to open the original file. Closes #29783 Release Notes: - Fixed issue where using `workspace: save as` would prevent users from opening the original file from which the new file was created --------- Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
This commit is contained in:
@@ -909,7 +909,14 @@ impl BufferStore {
|
||||
};
|
||||
cx.spawn(async move |this, cx| {
|
||||
task.await?;
|
||||
this.update(cx, |_, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
old_file.clone().and_then(|file| {
|
||||
this.path_to_buffer_id.remove(&ProjectPath {
|
||||
worktree_id: file.worktree_id(cx),
|
||||
path: file.path().clone(),
|
||||
})
|
||||
});
|
||||
|
||||
cx.emit(BufferStoreEvent::BufferChangedFilePath { buffer, old_file });
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4251,6 +4251,73 @@ async fn test_save_as(cx: &mut gpui::TestAppContext) {
|
||||
assert_eq!(opened_buffer, buffer);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_save_as_existing_file(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
|
||||
|
||||
fs.insert_tree(
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"data_a.txt": "data about a"
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/dir/data_a.txt"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit([(11..12, "b")], None, cx);
|
||||
});
|
||||
|
||||
// Save buffer's contents as a new file and confirm that the buffer's now
|
||||
// associated with `data_b.txt` instead of `data_a.txt`, confirming that the
|
||||
// file associated with the buffer has now been updated to `data_b.txt`
|
||||
project
|
||||
.update(cx, |project, cx| {
|
||||
let worktree_id = project.worktrees(cx).next().unwrap().read(cx).id();
|
||||
let new_path = ProjectPath {
|
||||
worktree_id,
|
||||
path: rel_path("data_b.txt").into(),
|
||||
};
|
||||
|
||||
project.save_buffer_as(buffer.clone(), new_path, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
assert_eq!(
|
||||
buffer.file().unwrap().full_path(cx),
|
||||
Path::new("dir/data_b.txt")
|
||||
)
|
||||
});
|
||||
|
||||
// Open the original `data_a.txt` file, confirming that its contents are
|
||||
// unchanged and the resulting buffer's associated file is `data_a.txt`.
|
||||
let original_buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/dir/data_a.txt"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
original_buffer.update(cx, |buffer, cx| {
|
||||
assert_eq!(buffer.text(), "data about a");
|
||||
assert_eq!(
|
||||
buffer.file().unwrap().full_path(cx),
|
||||
Path::new("dir/data_a.txt")
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test(retries = 5)]
|
||||
async fn test_rescan_and_remote_updates(cx: &mut gpui::TestAppContext) {
|
||||
use worktree::WorktreeModelHandle as _;
|
||||
|
||||
Reference in New Issue
Block a user