Detailed changes
@@ -1900,6 +1900,60 @@ impl Editor {
editor.update_lsp_data(false, Some(*buffer_id), window, cx);
}
}
+
+ project::Event::EntryRenamed(transaction) => {
+ let Some(workspace) = editor.workspace() else {
+ return;
+ };
+ let Some(active_editor) = workspace.read(cx).active_item_as::<Self>(cx)
+ else {
+ return;
+ };
+ if active_editor.entity_id() == cx.entity_id() {
+ let edited_buffers_already_open = {
+ let other_editors: Vec<Entity<Editor>> = workspace
+ .read(cx)
+ .panes()
+ .iter()
+ .flat_map(|pane| pane.read(cx).items_of_type::<Editor>())
+ .filter(|editor| editor.entity_id() != cx.entity_id())
+ .collect();
+
+ transaction.0.keys().all(|buffer| {
+ other_editors.iter().any(|editor| {
+ let multi_buffer = editor.read(cx).buffer();
+ multi_buffer.read(cx).is_singleton()
+ && multi_buffer.read(cx).as_singleton().map_or(
+ false,
+ |singleton| {
+ singleton.entity_id() == buffer.entity_id()
+ },
+ )
+ })
+ })
+ };
+
+ if !edited_buffers_already_open {
+ let workspace = workspace.downgrade();
+ let transaction = transaction.clone();
+ cx.defer_in(window, move |_, window, cx| {
+ cx.spawn_in(window, async move |editor, cx| {
+ Self::open_project_transaction(
+ &editor,
+ workspace,
+ transaction,
+ "Rename".to_string(),
+ cx,
+ )
+ .await
+ .ok()
+ })
+ .detach();
+ });
+ }
+ }
+ }
+
_ => {}
},
));
@@ -6282,7 +6336,7 @@ impl Editor {
}
pub async fn open_project_transaction(
- this: &WeakEntity<Editor>,
+ editor: &WeakEntity<Editor>,
workspace: WeakEntity<Workspace>,
transaction: ProjectTransaction,
title: String,
@@ -6300,7 +6354,7 @@ impl Editor {
if let Some((buffer, transaction)) = entries.first() {
if entries.len() == 1 {
- let excerpt = this.update(cx, |editor, cx| {
+ let excerpt = editor.update(cx, |editor, cx| {
editor
.buffer()
.read(cx)
@@ -88,9 +88,18 @@ pub enum BufferStoreEvent {
},
}
-#[derive(Default, Debug)]
+#[derive(Default, Debug, Clone)]
pub struct ProjectTransaction(pub HashMap<Entity<Buffer>, language::Transaction>);
+impl PartialEq for ProjectTransaction {
+ fn eq(&self, other: &Self) -> bool {
+ self.0.len() == other.0.len()
+ && self.0.iter().all(|(buffer, transaction)| {
+ other.0.get(buffer).is_some_and(|t| t.id == transaction.id)
+ })
+ }
+}
+
impl EventEmitter<BufferStoreEvent> for BufferStore {}
impl RemoteBufferStore {
@@ -8762,7 +8762,7 @@ impl LspStore {
(root_path.join(&old_path), root_path.join(&new_path))
};
- Self::will_rename_entry(
+ let _transaction = Self::will_rename_entry(
this.downgrade(),
worktree_id,
&old_abs_path,
@@ -9224,7 +9224,7 @@ impl LspStore {
new_path: &Path,
is_dir: bool,
cx: AsyncApp,
- ) -> Task<()> {
+ ) -> Task<ProjectTransaction> {
let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
cx.spawn(async move |cx| {
@@ -9257,7 +9257,7 @@ impl LspStore {
.log_err()
.flatten()?;
- LocalLspStore::deserialize_workspace_edit(
+ let transaction = LocalLspStore::deserialize_workspace_edit(
this.upgrade()?,
edit,
false,
@@ -9265,8 +9265,8 @@ impl LspStore {
cx,
)
.await
- .ok();
- Some(())
+ .ok()?;
+ Some(transaction)
}
});
tasks.push(apply_edit);
@@ -9276,11 +9276,17 @@ impl LspStore {
})
.ok()
.flatten();
+ let mut merged_transaction = ProjectTransaction::default();
for task in tasks {
// Await on tasks sequentially so that the order of application of edits is deterministic
// (at least with regards to the order of registration of language servers)
- task.await;
+ if let Some(transaction) = task.await {
+ for (buffer, buffer_transaction) in transaction.0 {
+ merged_transaction.0.insert(buffer, buffer_transaction);
+ }
+ }
}
+ merged_transaction
})
}
@@ -327,6 +327,7 @@ pub enum Event {
RevealInProjectPanel(ProjectEntryId),
SnippetEdit(BufferId, Vec<(lsp::Range, Snippet)>),
ExpandedAllForEntry(WorktreeId, ProjectEntryId),
+ EntryRenamed(ProjectTransaction),
AgentLocationChanged,
}
@@ -2119,7 +2120,7 @@ impl Project {
let is_root_entry = self.entry_is_worktree_root(entry_id, cx);
let lsp_store = self.lsp_store().downgrade();
- cx.spawn(async move |_, cx| {
+ cx.spawn(async move |project, cx| {
let (old_abs_path, new_abs_path) = {
let root_path = worktree.read_with(cx, |this, _| this.abs_path())?;
let new_abs_path = if is_root_entry {
@@ -2129,7 +2130,7 @@ impl Project {
};
(root_path.join(&old_path), new_abs_path)
};
- LspStore::will_rename_entry(
+ let transaction = LspStore::will_rename_entry(
lsp_store.clone(),
worktree_id,
&old_abs_path,
@@ -2145,6 +2146,12 @@ impl Project {
})?
.await?;
+ project
+ .update(cx, |_, cx| {
+ cx.emit(Event::EntryRenamed(transaction));
+ })
+ .ok();
+
lsp_store
.read_with(cx, |this, _| {
this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);