tools: Send stale file notifications only once (#34026)
Previously, we sent notifications repeatedly until the agent read a file, which was often inefficient. With this change, we now send a notification only once (unless the files are modified again, in which case we'll send another notification). Release Notes: - N/A
This commit is contained in:
parent
e0c860c42a
commit
d549993c73
3 changed files with 117 additions and 19 deletions
|
@ -1,5 +1,6 @@
|
|||
use anyhow::{Context as _, Result};
|
||||
use buffer_diff::BufferDiff;
|
||||
use clock;
|
||||
use collections::BTreeMap;
|
||||
use futures::{FutureExt, StreamExt, channel::mpsc};
|
||||
use gpui::{App, AppContext, AsyncApp, Context, Entity, Subscription, Task, WeakEntity};
|
||||
|
@ -17,6 +18,8 @@ pub struct ActionLog {
|
|||
edited_since_project_diagnostics_check: bool,
|
||||
/// The project this action log is associated with
|
||||
project: Entity<Project>,
|
||||
/// Tracks which buffer versions have already been notified as changed externally
|
||||
notified_versions: BTreeMap<Entity<Buffer>, clock::Global>,
|
||||
}
|
||||
|
||||
impl ActionLog {
|
||||
|
@ -26,6 +29,7 @@ impl ActionLog {
|
|||
tracked_buffers: BTreeMap::default(),
|
||||
edited_since_project_diagnostics_check: false,
|
||||
project,
|
||||
notified_versions: BTreeMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +55,7 @@ impl ActionLog {
|
|||
) -> &mut TrackedBuffer {
|
||||
let status = if is_created {
|
||||
if let Some(tracked) = self.tracked_buffers.remove(&buffer) {
|
||||
self.notified_versions.remove(&buffer);
|
||||
match tracked.status {
|
||||
TrackedBufferStatus::Created {
|
||||
existing_file_content,
|
||||
|
@ -106,7 +111,7 @@ impl ActionLog {
|
|||
TrackedBuffer {
|
||||
buffer: buffer.clone(),
|
||||
diff_base,
|
||||
unreviewed_edits: unreviewed_edits,
|
||||
unreviewed_edits,
|
||||
snapshot: text_snapshot.clone(),
|
||||
status,
|
||||
version: buffer.read(cx).version(),
|
||||
|
@ -165,6 +170,7 @@ impl ActionLog {
|
|||
// If the buffer had been edited by a tool, but it got
|
||||
// deleted externally, we want to stop tracking it.
|
||||
self.tracked_buffers.remove(&buffer);
|
||||
self.notified_versions.remove(&buffer);
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
@ -178,6 +184,7 @@ impl ActionLog {
|
|||
// resurrected externally, we want to clear the edits we
|
||||
// were tracking and reset the buffer's state.
|
||||
self.tracked_buffers.remove(&buffer);
|
||||
self.notified_versions.remove(&buffer);
|
||||
self.track_buffer_internal(buffer, false, cx);
|
||||
}
|
||||
cx.notify();
|
||||
|
@ -483,6 +490,7 @@ impl ActionLog {
|
|||
match tracked_buffer.status {
|
||||
TrackedBufferStatus::Created { .. } => {
|
||||
self.tracked_buffers.remove(&buffer);
|
||||
self.notified_versions.remove(&buffer);
|
||||
cx.notify();
|
||||
}
|
||||
TrackedBufferStatus::Modified => {
|
||||
|
@ -508,6 +516,7 @@ impl ActionLog {
|
|||
match tracked_buffer.status {
|
||||
TrackedBufferStatus::Deleted => {
|
||||
self.tracked_buffers.remove(&buffer);
|
||||
self.notified_versions.remove(&buffer);
|
||||
cx.notify();
|
||||
}
|
||||
_ => {
|
||||
|
@ -616,6 +625,7 @@ impl ActionLog {
|
|||
};
|
||||
|
||||
self.tracked_buffers.remove(&buffer);
|
||||
self.notified_versions.remove(&buffer);
|
||||
cx.notify();
|
||||
task
|
||||
}
|
||||
|
@ -629,6 +639,7 @@ impl ActionLog {
|
|||
|
||||
// Clear all tracked edits for this buffer and start over as if we just read it.
|
||||
self.tracked_buffers.remove(&buffer);
|
||||
self.notified_versions.remove(&buffer);
|
||||
self.buffer_read(buffer.clone(), cx);
|
||||
cx.notify();
|
||||
save
|
||||
|
@ -713,6 +724,33 @@ impl ActionLog {
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// Returns stale buffers that haven't been notified yet
|
||||
pub fn unnotified_stale_buffers<'a>(
|
||||
&'a self,
|
||||
cx: &'a App,
|
||||
) -> impl Iterator<Item = &'a Entity<Buffer>> {
|
||||
self.stale_buffers(cx).filter(|buffer| {
|
||||
let buffer_entity = buffer.read(cx);
|
||||
self.notified_versions
|
||||
.get(buffer)
|
||||
.map_or(true, |notified_version| {
|
||||
*notified_version != buffer_entity.version
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Marks the given buffers as notified at their current versions
|
||||
pub fn mark_buffers_as_notified(
|
||||
&mut self,
|
||||
buffers: impl IntoIterator<Item = Entity<Buffer>>,
|
||||
cx: &App,
|
||||
) {
|
||||
for buffer in buffers {
|
||||
let version = buffer.read(cx).version.clone();
|
||||
self.notified_versions.insert(buffer, version);
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over buffers changed since last read or edited by the model
|
||||
pub fn stale_buffers<'a>(&'a self, cx: &'a App) -> impl Iterator<Item = &'a Entity<Buffer>> {
|
||||
self.tracked_buffers
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue