From ff1722d3070fbd828b4ae7d0de0d9ccc5080601d Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 4 Oct 2023 14:29:13 -0600 Subject: [PATCH] Fix tracking newly saved buffers Co-Authored-By: Mikayla Maki --- crates/language/src/buffer.rs | 2 +- crates/project/src/project.rs | 28 +++++++++- crates/project_panel/src/project_panel.rs | 68 ++++++++++++++++++++++- 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 27b01543e1..207c41e7cd 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -660,12 +660,12 @@ impl Buffer { file_changed = true; }; + self.file = Some(new_file); if file_changed { self.file_update_count += 1; cx.emit(Event::FileHandleChanged); cx.notify(); } - self.file = Some(new_file); task } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 96037e9b20..a50e02a631 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1841,6 +1841,7 @@ impl Project { Worktree::Remote(_) => panic!("cannot remote buffers as new files"), }) .await?; + this.update(&mut cx, |this, cx| { this.detect_language_for_buffer(&buffer, cx); this.register_buffer_with_language_servers(&buffer, cx); @@ -2368,7 +2369,30 @@ impl Project { } } } + BufferEvent::FileHandleChanged => { + let Some(file) = File::from_dyn(buffer.read(cx).file()) else { + return None; + }; + match self.local_buffer_ids_by_entry_id.get(&file.entry_id) { + Some(_) => { + return None; + } + None => { + let remote_id = buffer.read(cx).remote_id(); + self.local_buffer_ids_by_entry_id + .insert(file.entry_id, remote_id); + + self.local_buffer_ids_by_path.insert( + ProjectPath { + worktree_id: file.worktree_id(cx), + path: file.path.clone(), + }, + remote_id, + ); + } + } + } _ => {} } @@ -5906,7 +5930,9 @@ impl Project { Some(&buffer_id) => buffer_id, None => match self.local_buffer_ids_by_path.get(&project_path) { Some(&buffer_id) => buffer_id, - None => continue, + None => { + continue; + } }, }; diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 3263649562..d66de1ad2e 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1737,7 +1737,7 @@ mod tests { use settings::SettingsStore; use std::{ collections::HashSet, - path::Path, + path::{Path, PathBuf}, sync::atomic::{self, AtomicUsize}, }; use workspace::{pane, AppState}; @@ -2759,6 +2759,71 @@ mod tests { ); } + #[gpui::test] + async fn test_new_file_move(cx: &mut gpui::TestAppContext) { + init_test(cx); + + let fs = FakeFs::new(cx.background()); + fs.as_fake().insert_tree("/root", json!({})).await; + let project = Project::test(fs, ["/root".as_ref()], cx).await; + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .root(cx); + let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); + + // Make a new buffer with no backing file + workspace.update(cx, |workspace, cx| { + Editor::new_file(workspace, &Default::default(), cx) + }); + + // "Save as"" the buffer, creating a new backing file for it + let task = workspace.update(cx, |workspace, cx| { + workspace.save_active_item(workspace::SaveIntent::Save, cx) + }); + + cx.foreground().run_until_parked(); + cx.simulate_new_path_selection(|_| Some(PathBuf::from("/root/new"))); + task.await.unwrap(); + + // Rename the file + select_path(&panel, "root/new", cx); + assert_eq!( + visible_entries_as_strings(&panel, 0..10, cx), + &["v root", " new <== selected"] + ); + panel.update(cx, |panel, cx| panel.rename(&Rename, cx)); + panel.update(cx, |panel, cx| { + panel + .filename_editor + .update(cx, |editor, cx| editor.set_text("newer", cx)); + }); + panel + .update(cx, |panel, cx| panel.confirm(&Confirm, cx)) + .unwrap() + .await + .unwrap(); + + cx.foreground().run_until_parked(); + assert_eq!( + visible_entries_as_strings(&panel, 0..10, cx), + &["v root", " newer <== selected"] + ); + + workspace + .update(cx, |workspace, cx| { + workspace.save_active_item(workspace::SaveIntent::Save, cx) + }) + .await + .unwrap(); + + cx.foreground().run_until_parked(); + // assert that saving the file doesn't restore "new" + assert_eq!( + visible_entries_as_strings(&panel, 0..10, cx), + &["v root", " newer <== selected"] + ); + } + fn toggle_expand_dir( panel: &ViewHandle, path: impl AsRef, @@ -2862,6 +2927,7 @@ mod tests { editor::init_settings(cx); crate::init((), cx); workspace::init_settings(cx); + client::init_settings(cx); Project::init_settings(cx); }); }