Emit loaded events for lazily loaded paths in worktree
This commit is contained in:
parent
9ad1ebf387
commit
b22a18345e
2 changed files with 64 additions and 8 deletions
|
@ -2759,6 +2759,10 @@ impl EntryKind {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn is_unloaded(&self) -> bool {
|
||||
matches!(self, EntryKind::UnloadedDir)
|
||||
}
|
||||
|
||||
pub fn is_file(&self) -> bool {
|
||||
matches!(self, EntryKind::File(_))
|
||||
}
|
||||
|
@ -3773,6 +3777,7 @@ impl BackgroundScanner {
|
|||
let mut changes = Vec::new();
|
||||
let mut old_paths = old_snapshot.entries_by_path.cursor::<PathKey>();
|
||||
let mut new_paths = new_snapshot.entries_by_path.cursor::<PathKey>();
|
||||
let mut last_newly_loaded_dir_path = None;
|
||||
old_paths.next(&());
|
||||
new_paths.next(&());
|
||||
for path in event_paths {
|
||||
|
@ -3820,20 +3825,33 @@ impl BackgroundScanner {
|
|||
changes.push((old_entry.path.clone(), old_entry.id, Removed));
|
||||
changes.push((new_entry.path.clone(), new_entry.id, Added));
|
||||
} else if old_entry != new_entry {
|
||||
changes.push((new_entry.path.clone(), new_entry.id, Updated));
|
||||
if old_entry.kind.is_unloaded() {
|
||||
last_newly_loaded_dir_path = Some(&new_entry.path);
|
||||
changes.push((
|
||||
new_entry.path.clone(),
|
||||
new_entry.id,
|
||||
Loaded,
|
||||
));
|
||||
} else {
|
||||
changes.push((
|
||||
new_entry.path.clone(),
|
||||
new_entry.id,
|
||||
Updated,
|
||||
));
|
||||
}
|
||||
}
|
||||
old_paths.next(&());
|
||||
new_paths.next(&());
|
||||
}
|
||||
Ordering::Greater => {
|
||||
let is_newly_loaded = self.phase == InitialScan
|
||||
|| last_newly_loaded_dir_path
|
||||
.as_ref()
|
||||
.map_or(false, |dir| new_entry.path.starts_with(&dir));
|
||||
changes.push((
|
||||
new_entry.path.clone(),
|
||||
new_entry.id,
|
||||
if self.phase == InitialScan {
|
||||
Loaded
|
||||
} else {
|
||||
Added
|
||||
},
|
||||
if is_newly_loaded { Loaded } else { Added },
|
||||
));
|
||||
new_paths.next(&());
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use serde_json::json;
|
|||
use std::{
|
||||
env,
|
||||
fmt::Write,
|
||||
mem,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
@ -313,6 +314,21 @@ async fn test_symlinks_pointing_outside(cx: &mut TestAppContext) {
|
|||
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||
.await;
|
||||
|
||||
let tree_updates = Arc::new(Mutex::new(Vec::new()));
|
||||
tree.update(cx, |_, cx| {
|
||||
let tree_updates = tree_updates.clone();
|
||||
cx.subscribe(&tree, move |_, _, event, _| {
|
||||
if let Event::UpdatedEntries(update) = event {
|
||||
tree_updates.lock().extend(
|
||||
update
|
||||
.iter()
|
||||
.map(|(path, _, change)| (path.clone(), *change)),
|
||||
);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
|
||||
// The symlinked directories are not scanned by default.
|
||||
tree.read_with(cx, |tree, _| {
|
||||
assert_eq!(
|
||||
|
@ -365,6 +381,14 @@ async fn test_symlinks_pointing_outside(cx: &mut TestAppContext) {
|
|||
]
|
||||
);
|
||||
});
|
||||
assert_eq!(
|
||||
mem::take(&mut *tree_updates.lock()),
|
||||
&[
|
||||
(Path::new("deps/dep-dir3").into(), PathChange::Loaded),
|
||||
(Path::new("deps/dep-dir3/deps").into(), PathChange::Loaded),
|
||||
(Path::new("deps/dep-dir3/src").into(), PathChange::Loaded)
|
||||
]
|
||||
);
|
||||
|
||||
// Expand a subdirectory of one of the symlinked directories.
|
||||
tree.read_with(cx, |tree, _| {
|
||||
|
@ -396,6 +420,21 @@ async fn test_symlinks_pointing_outside(cx: &mut TestAppContext) {
|
|||
]
|
||||
);
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
mem::take(&mut *tree_updates.lock()),
|
||||
&[
|
||||
(Path::new("deps/dep-dir3/src").into(), PathChange::Loaded),
|
||||
(
|
||||
Path::new("deps/dep-dir3/src/e.rs").into(),
|
||||
PathChange::Loaded
|
||||
),
|
||||
(
|
||||
Path::new("deps/dep-dir3/src/f.rs").into(),
|
||||
PathChange::Loaded
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -1114,7 +1153,6 @@ fn check_worktree_change_events(tree: &mut Worktree, cx: &mut ModelContext<Workt
|
|||
Ok(ix) | Err(ix) => ix,
|
||||
};
|
||||
match change_type {
|
||||
PathChange::Loaded => entries.insert(ix, entry.unwrap()),
|
||||
PathChange::Added => entries.insert(ix, entry.unwrap()),
|
||||
PathChange::Removed => drop(entries.remove(ix)),
|
||||
PathChange::Updated => {
|
||||
|
@ -1123,7 +1161,7 @@ fn check_worktree_change_events(tree: &mut Worktree, cx: &mut ModelContext<Workt
|
|||
assert_eq!(existing_entry.path, entry.path);
|
||||
*existing_entry = entry;
|
||||
}
|
||||
PathChange::AddedOrUpdated => {
|
||||
PathChange::AddedOrUpdated | PathChange::Loaded => {
|
||||
let entry = entry.unwrap();
|
||||
if entries.get(ix).map(|e| &e.path) == Some(&entry.path) {
|
||||
*entries.get_mut(ix).unwrap() = entry;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue