Add File.disk_state enum to clarify filesystem states (#20776)

Motivation for this is to make things more understandable while figuring
out #20775.

This is intended to be a refactoring that does not affect behavior, but
there are a few tricky spots:

* Previously `File.mtime()` (now `File.disk_state().mtime()`) would
return last known modification time for deleted files. Looking at uses,
I believe this will not affect anything. If there are behavior changes
here I believe they would be improvements.

* `BufferEvent::DirtyChanged` is now only emitted if dirtiness actually
changed, rather than if it may have changed. This should only be an
efficiency improvement.

Release Notes:

- N/A

Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
Michael Sloan 2024-11-18 10:30:08 -08:00 committed by GitHub
parent df1d0dec0a
commit d99f5fe83e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 161 additions and 134 deletions

View file

@ -20,7 +20,7 @@ use language::{
deserialize_line_ending, deserialize_version, serialize_line_ending, serialize_version,
split_operations,
},
Buffer, BufferEvent, Capability, File as _, Language, Operation,
Buffer, BufferEvent, Capability, DiskState, File as _, Language, Operation,
};
use rpc::{proto, AnyProtoClient, ErrorExt as _, TypedEnvelope};
use smol::channel::Receiver;
@ -434,7 +434,10 @@ impl LocalBufferStore {
let line_ending = buffer.line_ending();
let version = buffer.version();
let buffer_id = buffer.remote_id();
if buffer.file().is_some_and(|file| !file.is_created()) {
if buffer
.file()
.is_some_and(|file| file.disk_state() == DiskState::New)
{
has_changed_file = true;
}
@ -444,7 +447,7 @@ impl LocalBufferStore {
cx.spawn(move |this, mut cx| async move {
let new_file = save.await?;
let mtime = new_file.mtime;
let mtime = new_file.disk_state().mtime();
this.update(&mut cx, |this, cx| {
if let Some((downstream_client, project_id)) = this.downstream_client(cx) {
if has_changed_file {
@ -658,37 +661,30 @@ impl LocalBufferStore {
return None;
}
let new_file = if let Some(entry) = old_file
let snapshot_entry = old_file
.entry_id
.and_then(|entry_id| snapshot.entry_for_id(entry_id))
{
.or_else(|| snapshot.entry_for_path(old_file.path.as_ref()));
let new_file = if let Some(entry) = snapshot_entry {
File {
disk_state: match entry.mtime {
Some(mtime) => DiskState::Present { mtime },
None => old_file.disk_state,
},
is_local: true,
entry_id: Some(entry.id),
mtime: entry.mtime,
path: entry.path.clone(),
worktree: worktree.clone(),
is_deleted: false,
is_private: entry.is_private,
}
} else if let Some(entry) = snapshot.entry_for_path(old_file.path.as_ref()) {
File {
is_local: true,
entry_id: Some(entry.id),
mtime: entry.mtime,
path: entry.path.clone(),
worktree: worktree.clone(),
is_deleted: false,
is_private: entry.is_private,
}
} else {
File {
disk_state: DiskState::Deleted,
is_local: true,
entry_id: old_file.entry_id,
path: old_file.path.clone(),
mtime: old_file.mtime,
worktree: worktree.clone(),
is_deleted: true,
is_private: old_file.is_private,
}
};
@ -867,10 +863,9 @@ impl BufferStoreImpl for Model<LocalBufferStore> {
Some(Arc::new(File {
worktree,
path,
mtime: None,
disk_state: DiskState::New,
entry_id: None,
is_local: true,
is_deleted: false,
is_private: false,
})),
Capability::ReadWrite,