Use entry_id on File instead of worktree::Diff to detect when buffers' files change
Rather than computing a diff after processing a batch of FSEvents, we instead detect renames as we're inserting entries. We store an entry_id on the File object that is owned by each buffer, and use this to detect when the path of the File has changed. We now also manage all File-related state and event emission for Buffers in the LocalWorktree, since the logic will need to be totally different in the remote case. Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com> Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
co-authored by
Max Brunsfeld
Antonio Scandurra
parent
e80439daaa
commit
34963ac80d
+12
-8
@@ -6,7 +6,7 @@ use crate::{
|
||||
language::LanguageRegistry,
|
||||
rpc,
|
||||
settings::Settings,
|
||||
worktree::{File, Worktree, WorktreeHandle},
|
||||
worktree::{File, Worktree},
|
||||
AppState,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
@@ -394,7 +394,7 @@ impl Workspace {
|
||||
let entries = abs_paths
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|path| self.file_for_path(&path, cx))
|
||||
.map(|path| self.entry_id_for_path(&path, cx))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let bg = cx.background_executor().clone();
|
||||
@@ -402,12 +402,11 @@ impl Workspace {
|
||||
.iter()
|
||||
.cloned()
|
||||
.zip(entries.into_iter())
|
||||
.map(|(abs_path, file)| {
|
||||
.map(|(abs_path, entry_id)| {
|
||||
let is_file = bg.spawn(async move { abs_path.is_file() });
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
if is_file.await {
|
||||
return this
|
||||
.update(&mut cx, |this, cx| this.open_entry(file.entry_id(), cx));
|
||||
return this.update(&mut cx, |this, cx| this.open_entry(entry_id, cx));
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -440,18 +439,22 @@ impl Workspace {
|
||||
(self.add_worktree(abs_path, cx), PathBuf::new())
|
||||
}
|
||||
|
||||
fn file_for_path(&mut self, abs_path: &Path, cx: &mut ViewContext<Self>) -> File {
|
||||
fn entry_id_for_path(
|
||||
&mut self,
|
||||
abs_path: &Path,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> (usize, Arc<Path>) {
|
||||
for tree in self.worktrees.iter() {
|
||||
if let Some(relative_path) = tree
|
||||
.read(cx)
|
||||
.as_local()
|
||||
.and_then(|t| abs_path.strip_prefix(t.abs_path()).ok())
|
||||
{
|
||||
return tree.file(relative_path);
|
||||
return (tree.id(), relative_path.into());
|
||||
}
|
||||
}
|
||||
let worktree = self.add_worktree(&abs_path, cx);
|
||||
worktree.file(Path::new(""))
|
||||
(worktree.id(), Path::new("").into())
|
||||
}
|
||||
|
||||
pub fn add_worktree(
|
||||
@@ -880,6 +883,7 @@ mod tests {
|
||||
use crate::{
|
||||
editor::Editor,
|
||||
test::{build_app_state, temp_tree},
|
||||
worktree::WorktreeHandle,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::{collections::HashSet, fs};
|
||||
|
||||
Reference in New Issue
Block a user