mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-21 11:27:43 +03:00
Replace Worktree
with an enum
For now this enum only contains a `Local` variant, but the next step is to add a `Remote` variant that will be constructed when joining a remote worktree.
This commit is contained in:
parent
7a66cd1ae1
commit
79cac1340e
@ -2682,9 +2682,10 @@ mod tests {
|
|||||||
"file2": "",
|
"file2": "",
|
||||||
"file3": "",
|
"file3": "",
|
||||||
}));
|
}));
|
||||||
let tree = cx.add_model(|cx| Worktree::new(dir.path(), cx));
|
let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx));
|
||||||
tree.flush_fs_events(&cx).await;
|
tree.flush_fs_events(&cx).await;
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
|
|
||||||
let file1 = cx.update(|cx| tree.file("file1", cx)).await;
|
let file1 = cx.update(|cx| tree.file("file1", cx)).await;
|
||||||
let buffer1 = cx.add_model(|cx| {
|
let buffer1 = cx.add_model(|cx| {
|
||||||
@ -2793,8 +2794,9 @@ mod tests {
|
|||||||
async fn test_file_changes_on_disk(mut cx: gpui::TestAppContext) {
|
async fn test_file_changes_on_disk(mut cx: gpui::TestAppContext) {
|
||||||
let initial_contents = "aaa\nbbbbb\nc\n";
|
let initial_contents = "aaa\nbbbbb\nc\n";
|
||||||
let dir = temp_tree(json!({ "the-file": initial_contents }));
|
let dir = temp_tree(json!({ "the-file": initial_contents }));
|
||||||
let tree = cx.add_model(|cx| Worktree::new(dir.path(), cx));
|
let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx));
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
|
|
||||||
let abs_path = dir.path().join("the-file");
|
let abs_path = dir.path().join("the-file");
|
||||||
let file = cx.update(|cx| tree.file("the-file", cx)).await;
|
let file = cx.update(|cx| tree.file("the-file", cx)).await;
|
||||||
|
@ -362,16 +362,21 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_path(&self, path: &Path, cx: &AppContext) -> bool {
|
pub fn contains_path(&self, path: &Path, cx: &AppContext) -> bool {
|
||||||
self.worktrees
|
for worktree in &self.worktrees {
|
||||||
.iter()
|
let worktree = worktree.read(cx).as_local();
|
||||||
.any(|worktree| worktree.read(cx).contains_abs_path(path))
|
if worktree.map_or(false, |w| w.contains_abs_path(path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn worktree_scans_complete(&self, cx: &AppContext) -> impl Future<Output = ()> + 'static {
|
pub fn worktree_scans_complete(&self, cx: &AppContext) -> impl Future<Output = ()> + 'static {
|
||||||
let futures = self
|
let futures = self
|
||||||
.worktrees
|
.worktrees
|
||||||
.iter()
|
.iter()
|
||||||
.map(|worktree| worktree.read(cx).scan_complete())
|
.filter_map(|worktree| worktree.read(cx).as_local())
|
||||||
|
.map(|worktree| worktree.scan_complete())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
async move {
|
async move {
|
||||||
for future in futures {
|
for future in futures {
|
||||||
@ -422,7 +427,11 @@ impl Workspace {
|
|||||||
|
|
||||||
fn file_for_path(&mut self, abs_path: &Path, cx: &mut ViewContext<Self>) -> Task<FileHandle> {
|
fn file_for_path(&mut self, abs_path: &Path, cx: &mut ViewContext<Self>) -> Task<FileHandle> {
|
||||||
for tree in self.worktrees.iter() {
|
for tree in self.worktrees.iter() {
|
||||||
if let Ok(relative_path) = abs_path.strip_prefix(tree.read(cx).abs_path()) {
|
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, cx.as_mut());
|
return tree.file(relative_path, cx.as_mut());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,7 +444,7 @@ impl Workspace {
|
|||||||
path: &Path,
|
path: &Path,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> ModelHandle<Worktree> {
|
) -> ModelHandle<Worktree> {
|
||||||
let worktree = cx.add_model(|cx| Worktree::new(path, cx));
|
let worktree = cx.add_model(|cx| Worktree::local(path, cx));
|
||||||
cx.observe_model(&worktree, |_, _, cx| cx.notify());
|
cx.observe_model(&worktree, |_, _, cx| cx.notify());
|
||||||
self.worktrees.insert(worktree.clone());
|
self.worktrees.insert(worktree.clone());
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@ -595,11 +604,10 @@ impl Workspace {
|
|||||||
if let Some(item) = self.active_item(cx) {
|
if let Some(item) = self.active_item(cx) {
|
||||||
let handle = cx.handle();
|
let handle = cx.handle();
|
||||||
if item.entry_id(cx.as_ref()).is_none() {
|
if item.entry_id(cx.as_ref()).is_none() {
|
||||||
let start_path = self
|
let worktree = self.worktrees.iter().next();
|
||||||
.worktrees
|
let start_path = worktree
|
||||||
.iter()
|
.and_then(|w| w.read(cx).as_local())
|
||||||
.next()
|
.map_or(Path::new(""), |w| w.abs_path())
|
||||||
.map_or(Path::new(""), |h| h.read(cx).abs_path())
|
|
||||||
.to_path_buf();
|
.to_path_buf();
|
||||||
cx.prompt_for_new_path(&start_path, move |path, cx| {
|
cx.prompt_for_new_path(&start_path, move |path, cx| {
|
||||||
if let Some(path) = path {
|
if let Some(path) = path {
|
||||||
@ -670,7 +678,10 @@ impl Workspace {
|
|||||||
|
|
||||||
let share_task = this.update(&mut cx, |this, cx| {
|
let share_task = this.update(&mut cx, |this, cx| {
|
||||||
let worktree = this.worktrees.iter().next()?;
|
let worktree = this.worktrees.iter().next()?;
|
||||||
Some(worktree.update(cx, |worktree, cx| worktree.share(rpc, connection_id, cx)))
|
worktree.update(cx, |worktree, cx| {
|
||||||
|
let worktree = worktree.as_local_mut()?;
|
||||||
|
Some(worktree.share(rpc, connection_id, cx))
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(share_task) = share_task {
|
if let Some(share_task) = share_task {
|
||||||
@ -721,7 +732,7 @@ impl Workspace {
|
|||||||
|
|
||||||
cx.spawn(|_, _| async move {
|
cx.spawn(|_, _| async move {
|
||||||
if let Err(e) = task.await {
|
if let Err(e) = task.await {
|
||||||
log::error!("joing failed: {}", e);
|
log::error!("joining failed: {}", e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
@ -1096,7 +1107,7 @@ mod tests {
|
|||||||
.read(cx)
|
.read(cx)
|
||||||
.worktrees()
|
.worktrees()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|w| w.read(cx).abs_path())
|
.map(|w| w.read(cx).as_local().unwrap().abs_path())
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
worktree_roots,
|
worktree_roots,
|
||||||
|
@ -46,7 +46,74 @@ enum ScanState {
|
|||||||
Err(Arc<io::Error>),
|
Err(Arc<io::Error>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Worktree {
|
pub enum Worktree {
|
||||||
|
Local(LocalWorktree),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Entity for Worktree {
|
||||||
|
type Event = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Worktree {
|
||||||
|
pub fn local(path: impl Into<Arc<Path>>, cx: &mut ModelContext<Worktree>) -> Self {
|
||||||
|
Worktree::Local(LocalWorktree::new(path, cx))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_local(&self) -> Option<&LocalWorktree> {
|
||||||
|
if let Worktree::Local(worktree) = self {
|
||||||
|
Some(worktree)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_local_mut(&mut self) -> Option<&mut LocalWorktree> {
|
||||||
|
if let Worktree::Local(worktree) = self {
|
||||||
|
Some(worktree)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn snapshot(&self) -> Snapshot {
|
||||||
|
match self {
|
||||||
|
Worktree::Local(worktree) => worktree.snapshot(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_history(
|
||||||
|
&self,
|
||||||
|
path: &Path,
|
||||||
|
cx: &AppContext,
|
||||||
|
) -> impl Future<Output = Result<History>> {
|
||||||
|
match self {
|
||||||
|
Worktree::Local(worktree) => worktree.load_history(path, cx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(
|
||||||
|
&self,
|
||||||
|
path: &Path,
|
||||||
|
content: Rope,
|
||||||
|
cx: &AppContext,
|
||||||
|
) -> impl Future<Output = Result<()>> {
|
||||||
|
match self {
|
||||||
|
Worktree::Local(worktree) => worktree.save(path, content, cx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Worktree {
|
||||||
|
type Target = Snapshot;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
match self {
|
||||||
|
Worktree::Local(worktree) => &worktree.snapshot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LocalWorktree {
|
||||||
snapshot: Snapshot,
|
snapshot: Snapshot,
|
||||||
background_snapshot: Arc<Mutex<Snapshot>>,
|
background_snapshot: Arc<Mutex<Snapshot>>,
|
||||||
handles: Arc<Mutex<HashMap<Arc<Path>, Weak<Mutex<FileHandleState>>>>>,
|
handles: Arc<Mutex<HashMap<Arc<Path>, Weak<Mutex<FileHandleState>>>>>,
|
||||||
@ -69,8 +136,8 @@ struct FileHandleState {
|
|||||||
mtime: SystemTime,
|
mtime: SystemTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Worktree {
|
impl LocalWorktree {
|
||||||
pub fn new(path: impl Into<Arc<Path>>, cx: &mut ModelContext<Self>) -> Self {
|
pub fn new(path: impl Into<Arc<Path>>, cx: &mut ModelContext<Worktree>) -> Self {
|
||||||
let abs_path = path.into();
|
let abs_path = path.into();
|
||||||
let (scan_state_tx, scan_state_rx) = smol::channel::unbounded();
|
let (scan_state_tx, scan_state_rx) = smol::channel::unbounded();
|
||||||
let id = cx.model_id();
|
let id = cx.model_id();
|
||||||
@ -109,7 +176,13 @@ impl Worktree {
|
|||||||
while let Ok(scan_state) = scan_state_rx.recv().await {
|
while let Ok(scan_state) = scan_state_rx.recv().await {
|
||||||
let alive = cx.update(|cx| {
|
let alive = cx.update(|cx| {
|
||||||
if let Some(handle) = this.upgrade(&cx) {
|
if let Some(handle) = this.upgrade(&cx) {
|
||||||
handle.update(cx, |this, cx| this.observe_scan_state(scan_state, cx));
|
handle.update(cx, |this, cx| {
|
||||||
|
if let Worktree::Local(worktree) = this {
|
||||||
|
worktree.observe_scan_state(scan_state, cx)
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
});
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -137,12 +210,12 @@ impl Worktree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn observe_scan_state(&mut self, scan_state: ScanState, cx: &mut ModelContext<Self>) {
|
fn observe_scan_state(&mut self, scan_state: ScanState, cx: &mut ModelContext<Worktree>) {
|
||||||
let _ = self.scan_state.0.blocking_send(scan_state);
|
let _ = self.scan_state.0.blocking_send(scan_state);
|
||||||
self.poll_entries(cx);
|
self.poll_entries(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_entries(&mut self, cx: &mut ModelContext<Self>) {
|
fn poll_entries(&mut self, cx: &mut ModelContext<Worktree>) {
|
||||||
self.snapshot = self.background_snapshot.lock().clone();
|
self.snapshot = self.background_snapshot.lock().clone();
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
|
||||||
@ -150,8 +223,12 @@ impl Worktree {
|
|||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
smol::Timer::after(Duration::from_millis(100)).await;
|
smol::Timer::after(Duration::from_millis(100)).await;
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.poll_scheduled = false;
|
if let Worktree::Local(worktree) = this {
|
||||||
this.poll_entries(cx);
|
worktree.poll_scheduled = false;
|
||||||
|
worktree.poll_entries(cx);
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
@ -202,7 +279,7 @@ impl Worktree {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save<'a>(&self, path: &Path, content: Rope, cx: &AppContext) -> Task<Result<()>> {
|
pub fn save(&self, path: &Path, content: Rope, cx: &AppContext) -> Task<Result<()>> {
|
||||||
let handles = self.handles.clone();
|
let handles = self.handles.clone();
|
||||||
let path = path.to_path_buf();
|
let path = path.to_path_buf();
|
||||||
let abs_path = self.absolutize(&path);
|
let abs_path = self.absolutize(&path);
|
||||||
@ -229,7 +306,7 @@ impl Worktree {
|
|||||||
&mut self,
|
&mut self,
|
||||||
client: rpc::Client,
|
client: rpc::Client,
|
||||||
connection_id: ConnectionId,
|
connection_id: ConnectionId,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Worktree>,
|
||||||
) -> Task<anyhow::Result<(u64, String)>> {
|
) -> Task<anyhow::Result<(u64, String)>> {
|
||||||
self.rpc = Some(client.clone());
|
self.rpc = Some(client.clone());
|
||||||
let snapshot = self.snapshot();
|
let snapshot = self.snapshot();
|
||||||
@ -259,11 +336,7 @@ impl Worktree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for Worktree {
|
impl Deref for LocalWorktree {
|
||||||
type Event = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Worktree {
|
|
||||||
type Target = Snapshot;
|
type Target = Snapshot;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -271,7 +344,7 @@ impl Deref for Worktree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Worktree {
|
impl fmt::Debug for LocalWorktree {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
self.snapshot.fmt(f)
|
self.snapshot.fmt(f)
|
||||||
}
|
}
|
||||||
@ -470,7 +543,7 @@ impl FileHandle {
|
|||||||
.lock()
|
.lock()
|
||||||
.path
|
.path
|
||||||
.file_name()
|
.file_name()
|
||||||
.or_else(|| self.worktree.read(cx).abs_path().file_name())
|
.or_else(|| Some(OsStr::new(self.worktree.read(cx).root_name())))
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +563,7 @@ impl FileHandle {
|
|||||||
self.worktree.read(cx).load_history(&self.path(), cx)
|
self.worktree.read(cx).load_history(&self.path(), cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save<'a>(&self, content: Rope, cx: &AppContext) -> Task<Result<()>> {
|
pub fn save(&self, content: Rope, cx: &AppContext) -> impl Future<Output = Result<()>> {
|
||||||
let worktree = self.worktree.read(cx);
|
let worktree = self.worktree.read(cx);
|
||||||
worktree.save(&self.path(), content, cx)
|
worktree.save(&self.path(), content, cx)
|
||||||
}
|
}
|
||||||
@ -1250,47 +1323,51 @@ impl WorktreeHandle for ModelHandle<Worktree> {
|
|||||||
let path = Arc::from(path.as_ref());
|
let path = Arc::from(path.as_ref());
|
||||||
let handle = self.clone();
|
let handle = self.clone();
|
||||||
let tree = self.read(cx);
|
let tree = self.read(cx);
|
||||||
let abs_path = tree.absolutize(&path);
|
match tree {
|
||||||
cx.spawn(|cx| async move {
|
Worktree::Local(tree) => {
|
||||||
let mtime = cx
|
let abs_path = tree.absolutize(&path);
|
||||||
.background_executor()
|
cx.spawn(|cx| async move {
|
||||||
.spawn(async move {
|
let mtime = cx
|
||||||
if let Ok(metadata) = fs::metadata(&abs_path) {
|
.background_executor()
|
||||||
metadata.modified().unwrap()
|
.spawn(async move {
|
||||||
} else {
|
if let Ok(metadata) = fs::metadata(&abs_path) {
|
||||||
UNIX_EPOCH
|
metadata.modified().unwrap()
|
||||||
|
} else {
|
||||||
|
UNIX_EPOCH
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
let state = handle.read_with(&cx, |tree, _| {
|
||||||
|
let mut handles = tree.as_local().unwrap().handles.lock();
|
||||||
|
if let Some(state) = handles.get(&path).and_then(Weak::upgrade) {
|
||||||
|
state
|
||||||
|
} else {
|
||||||
|
let handle_state = if let Some(entry) = tree.entry_for_path(&path) {
|
||||||
|
FileHandleState {
|
||||||
|
path: entry.path().clone(),
|
||||||
|
is_deleted: false,
|
||||||
|
mtime,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FileHandleState {
|
||||||
|
path: path.clone(),
|
||||||
|
is_deleted: !tree.path_is_pending(path),
|
||||||
|
mtime,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = Arc::new(Mutex::new(handle_state.clone()));
|
||||||
|
handles.insert(handle_state.path, Arc::downgrade(&state));
|
||||||
|
state
|
||||||
|
}
|
||||||
|
});
|
||||||
|
FileHandle {
|
||||||
|
worktree: handle.clone(),
|
||||||
|
state,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
|
||||||
let state = handle.read_with(&cx, |tree, _| {
|
|
||||||
let mut handles = tree.handles.lock();
|
|
||||||
if let Some(state) = handles.get(&path).and_then(Weak::upgrade) {
|
|
||||||
state
|
|
||||||
} else {
|
|
||||||
let handle_state = if let Some(entry) = tree.entry_for_path(&path) {
|
|
||||||
FileHandleState {
|
|
||||||
path: entry.path().clone(),
|
|
||||||
is_deleted: false,
|
|
||||||
mtime,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FileHandleState {
|
|
||||||
path: path.clone(),
|
|
||||||
is_deleted: !tree.path_is_pending(path),
|
|
||||||
mtime,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let state = Arc::new(Mutex::new(handle_state.clone()));
|
|
||||||
handles.insert(handle_state.path, Arc::downgrade(&state));
|
|
||||||
state
|
|
||||||
}
|
|
||||||
});
|
|
||||||
FileHandle {
|
|
||||||
worktree: handle.clone(),
|
|
||||||
state,
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the worktree's FS event stream sometimes delivers "redundant" events for FS changes that
|
// When the worktree's FS event stream sometimes delivers "redundant" events for FS changes that
|
||||||
@ -1318,7 +1395,8 @@ impl WorktreeHandle for ModelHandle<Worktree> {
|
|||||||
tree.condition(&cx, |tree, _| tree.entry_for_path(filename).is_none())
|
tree.condition(&cx, |tree, _| tree.entry_for_path(filename).is_none())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
.boxed_local()
|
.boxed_local()
|
||||||
}
|
}
|
||||||
@ -1467,9 +1545,10 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let tree = cx.add_model(|cx| Worktree::new(root_link_path, cx));
|
let tree = cx.add_model(|cx| Worktree::local(root_link_path, cx));
|
||||||
|
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let tree = tree.read(cx);
|
let tree = tree.read(cx);
|
||||||
assert_eq!(tree.file_count(), 5);
|
assert_eq!(tree.file_count(), 5);
|
||||||
@ -1508,8 +1587,9 @@ mod tests {
|
|||||||
"file1": "the old contents",
|
"file1": "the old contents",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let tree = cx.add_model(|cx| Worktree::new(dir.path(), cx));
|
let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx));
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
cx.read(|cx| assert_eq!(tree.read(cx).file_count(), 1));
|
cx.read(|cx| assert_eq!(tree.read(cx).file_count(), 1));
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(1, "a line of text.\n".repeat(10 * 1024), cx));
|
let buffer = cx.add_model(|cx| Buffer::new(1, "a line of text.\n".repeat(10 * 1024), cx));
|
||||||
@ -1537,8 +1617,9 @@ mod tests {
|
|||||||
"file1": "the old contents",
|
"file1": "the old contents",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let tree = cx.add_model(|cx| Worktree::new(dir.path().join("file1"), cx));
|
let tree = cx.add_model(|cx| Worktree::local(dir.path().join("file1"), cx));
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
cx.read(|cx| assert_eq!(tree.read(cx).file_count(), 1));
|
cx.read(|cx| assert_eq!(tree.read(cx).file_count(), 1));
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(1, "a line of text.\n".repeat(10 * 1024), cx));
|
let buffer = cx.add_model(|cx| Buffer::new(1, "a line of text.\n".repeat(10 * 1024), cx));
|
||||||
@ -1569,7 +1650,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let tree = cx.add_model(|cx| Worktree::new(dir.path(), cx));
|
let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx));
|
||||||
let file2 = cx.update(|cx| tree.file("a/file2", cx)).await;
|
let file2 = cx.update(|cx| tree.file("a/file2", cx)).await;
|
||||||
let file3 = cx.update(|cx| tree.file("a/file3", cx)).await;
|
let file3 = cx.update(|cx| tree.file("a/file3", cx)).await;
|
||||||
let file4 = cx.update(|cx| tree.file("b/c/file4", cx)).await;
|
let file4 = cx.update(|cx| tree.file("b/c/file4", cx)).await;
|
||||||
@ -1577,7 +1658,8 @@ mod tests {
|
|||||||
let non_existent_file = cx.update(|cx| tree.file("a/file_x", cx)).await;
|
let non_existent_file = cx.update(|cx| tree.file("a/file_x", cx)).await;
|
||||||
|
|
||||||
// After scanning, the worktree knows which files exist and which don't.
|
// After scanning, the worktree knows which files exist and which don't.
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
assert!(!file2.is_deleted());
|
assert!(!file2.is_deleted());
|
||||||
assert!(!file3.is_deleted());
|
assert!(!file3.is_deleted());
|
||||||
assert!(!file4.is_deleted());
|
assert!(!file4.is_deleted());
|
||||||
@ -1636,8 +1718,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let tree = cx.add_model(|cx| Worktree::new(dir.path(), cx));
|
let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx));
|
||||||
cx.read(|cx| tree.read(cx).scan_complete()).await;
|
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
tree.flush_fs_events(&cx).await;
|
tree.flush_fs_events(&cx).await;
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let tree = tree.read(cx);
|
let tree = tree.read(cx);
|
||||||
|
Loading…
Reference in New Issue
Block a user