mirror of
https://github.com/zed-industries/zed.git
synced 2026-05-31 19:05:00 +07:00
sidebar: Improve performance of rebuild_contents (#57717)
Release Notes: - N/A or Added/Fixed/Improved ...
This commit is contained in:
parent
75c17a6ee9
commit
6555ac3d04
9 changed files with 105 additions and 80 deletions
|
|
@ -936,7 +936,11 @@ impl ActionLog {
|
|||
let mut undo_buffers = Vec::new();
|
||||
let mut futures = Vec::new();
|
||||
|
||||
for buffer in self.changed_buffers(cx).into_keys() {
|
||||
for buffer in self
|
||||
.changed_buffers(cx)
|
||||
.map(|(buffer, _)| buffer)
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
let buffer_ranges = vec![Anchor::min_max_range_for_buffer(
|
||||
buffer.read(cx).remote_id(),
|
||||
)];
|
||||
|
|
@ -1023,17 +1027,19 @@ impl ActionLog {
|
|||
}
|
||||
|
||||
/// Returns the set of buffers that contain edits that haven't been reviewed by the user.
|
||||
pub fn changed_buffers(&self, cx: &App) -> BTreeMap<Entity<Buffer>, Entity<BufferDiff>> {
|
||||
pub fn changed_buffers(
|
||||
&self,
|
||||
cx: &App,
|
||||
) -> impl Iterator<Item = (Entity<Buffer>, Entity<BufferDiff>)> {
|
||||
self.tracked_buffers
|
||||
.iter()
|
||||
.filter(|(_, tracked)| tracked.has_edits(cx))
|
||||
.map(|(buffer, tracked)| (buffer.clone(), tracked.diff.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns the total number of lines added and removed across all unreviewed buffers.
|
||||
pub fn diff_stats(&self, cx: &App) -> DiffStats {
|
||||
DiffStats::all_files(&self.changed_buffers(cx), cx)
|
||||
DiffStats::all_files(self.changed_buffers(cx), cx)
|
||||
}
|
||||
|
||||
/// Iterate over buffers changed since last read or edited by the model
|
||||
|
|
@ -1079,7 +1085,7 @@ impl DiffStats {
|
|||
}
|
||||
|
||||
pub fn all_files(
|
||||
changed_buffers: &BTreeMap<Entity<Buffer>, Entity<BufferDiff>>,
|
||||
changed_buffers: impl IntoIterator<Item = (Entity<Buffer>, Entity<BufferDiff>)>,
|
||||
cx: &App,
|
||||
) -> Self {
|
||||
let mut total = DiffStats::default();
|
||||
|
|
@ -3254,21 +3260,21 @@ mod tests {
|
|||
child_log_1
|
||||
.read(cx)
|
||||
.changed_buffers(cx)
|
||||
.into_keys()
|
||||
.map(|(buffer, _)| buffer)
|
||||
.collect()
|
||||
});
|
||||
let child_2_changed: Vec<_> = cx.read(|cx| {
|
||||
child_log_2
|
||||
.read(cx)
|
||||
.changed_buffers(cx)
|
||||
.into_keys()
|
||||
.map(|(buffer, _)| buffer)
|
||||
.collect()
|
||||
});
|
||||
let parent_changed: Vec<_> = cx.read(|cx| {
|
||||
parent_log
|
||||
.read(cx)
|
||||
.changed_buffers(cx)
|
||||
.into_keys()
|
||||
.map(|(buffer, _)| buffer)
|
||||
.collect()
|
||||
});
|
||||
|
||||
|
|
@ -3494,7 +3500,6 @@ mod tests {
|
|||
action_log
|
||||
.read(cx)
|
||||
.changed_buffers(cx)
|
||||
.into_iter()
|
||||
.map(|(buffer, diff)| {
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
(
|
||||
|
|
|
|||
|
|
@ -2608,7 +2608,8 @@ mod tests {
|
|||
|
||||
cx.run_until_parked();
|
||||
|
||||
let changed = action_log.read_with(cx, |log, cx| log.changed_buffers(cx));
|
||||
let changed =
|
||||
action_log.read_with(cx, |log, cx| log.changed_buffers(cx).collect::<Vec<_>>());
|
||||
assert!(
|
||||
!changed.is_empty(),
|
||||
"action_log.changed_buffers() should be non-empty after streaming edit,
|
||||
|
|
|
|||
|
|
@ -1061,7 +1061,8 @@ mod tests {
|
|||
|
||||
cx.run_until_parked();
|
||||
|
||||
let changed = action_log.read_with(cx, |log, cx| log.changed_buffers(cx));
|
||||
let changed =
|
||||
action_log.read_with(cx, |log, cx| log.changed_buffers(cx).collect::<Vec<_>>());
|
||||
assert!(
|
||||
!changed.is_empty(),
|
||||
"action_log.changed_buffers() should be non-empty after streaming write, \
|
||||
|
|
@ -1133,7 +1134,8 @@ mod tests {
|
|||
);
|
||||
|
||||
// Reject all edits — this should delete the newly created file
|
||||
let changed = action_log.read_with(cx, |log, cx| log.changed_buffers(cx));
|
||||
let changed =
|
||||
action_log.read_with(cx, |log, cx| log.changed_buffers(cx).collect::<Vec<_>>());
|
||||
assert!(
|
||||
!changed.is_empty(),
|
||||
"action_log should track the created file as changed"
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ impl AgentDiffPane {
|
|||
.changed_buffers(cx);
|
||||
|
||||
// Sort edited files alphabetically for consistency with Git diff view
|
||||
let mut sorted_buffers: Vec<_> = changed_buffers.iter().collect();
|
||||
let mut sorted_buffers: Vec<_> = changed_buffers.collect();
|
||||
sorted_buffers.sort_by(|(buffer_a, _), (buffer_b, _)| {
|
||||
let path_a = buffer_a.read(cx).file().map(|f| f.path().clone());
|
||||
let path_b = buffer_b.read(cx).file().map(|f| f.path().clone());
|
||||
|
|
@ -1535,7 +1535,7 @@ impl AgentDiff {
|
|||
};
|
||||
|
||||
let action_log = thread.read(cx).action_log();
|
||||
let changed_buffers = action_log.read(cx).changed_buffers(cx);
|
||||
let changed_buffers = action_log.read(cx).changed_buffers(cx).collect::<Vec<_>>();
|
||||
|
||||
let mut unaffected = self.reviewing_editors.clone();
|
||||
|
||||
|
|
@ -1769,12 +1769,13 @@ impl AgentDiff {
|
|||
{
|
||||
let changed_buffers = thread.read(cx).action_log().read(cx).changed_buffers(cx);
|
||||
|
||||
let mut keys = changed_buffers.keys();
|
||||
keys.find(|k| *k == &curr_buffer);
|
||||
let mut keys = changed_buffers.map(|(buffer, _)| buffer);
|
||||
keys.find(|k| *k == curr_buffer);
|
||||
let next_project_path = keys
|
||||
.next()
|
||||
.filter(|k| *k != &curr_buffer)
|
||||
.filter(|k| *k != curr_buffer)
|
||||
.and_then(|after| after.read(cx).project_path(cx));
|
||||
drop(keys);
|
||||
|
||||
if let Some(path) = next_project_path {
|
||||
let task = workspace.open_path(path, None, true, window, cx);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ use std::num::NonZeroUsize;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use std::{collections::BTreeMap, rc::Rc, time::Duration};
|
||||
use std::{rc::Rc, time::Duration};
|
||||
use terminal_view::terminal_panel::TerminalPanel;
|
||||
use text::Anchor;
|
||||
use theme_settings::{AgentBufferFontSize, AgentUiFontSize};
|
||||
|
|
|
|||
|
|
@ -2310,7 +2310,7 @@ impl ThreadView {
|
|||
let thread = &self.thread;
|
||||
let telemetry = ActionLogTelemetry::from(thread.read(cx));
|
||||
let action_log = thread.read(cx).action_log().clone();
|
||||
let has_changes = action_log.read(cx).changed_buffers(cx).len() > 0;
|
||||
let has_changes = action_log.read(cx).changed_buffers(cx).next().is_some();
|
||||
|
||||
action_log
|
||||
.update(cx, |action_log, cx| {
|
||||
|
|
@ -2580,7 +2580,7 @@ impl ThreadView {
|
|||
let thread = self.thread.read(cx);
|
||||
let action_log = thread.action_log();
|
||||
let telemetry = ActionLogTelemetry::from(thread);
|
||||
let changed_buffers = action_log.read(cx).changed_buffers(cx);
|
||||
let changed_buffers = action_log.read(cx).changed_buffers(cx).collect::<Vec<_>>();
|
||||
let plan = thread.plan();
|
||||
let queue_is_empty = !self.has_queued_messages();
|
||||
|
||||
|
|
@ -2686,7 +2686,7 @@ impl ThreadView {
|
|||
&self,
|
||||
action_log: &Entity<ActionLog>,
|
||||
telemetry: ActionLogTelemetry,
|
||||
changed_buffers: &BTreeMap<Entity<Buffer>, Entity<BufferDiff>>,
|
||||
changed_buffers: &[(Entity<Buffer>, Entity<BufferDiff>)],
|
||||
pending_edits: bool,
|
||||
cx: &Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
|
|
@ -3433,7 +3433,7 @@ impl ThreadView {
|
|||
|
||||
fn render_edits_summary(
|
||||
&self,
|
||||
changed_buffers: &BTreeMap<Entity<Buffer>, Entity<BufferDiff>>,
|
||||
changed_buffers: &[(Entity<Buffer>, Entity<BufferDiff>)],
|
||||
expanded: bool,
|
||||
pending_edits: bool,
|
||||
cx: &Context<Self>,
|
||||
|
|
@ -3478,7 +3478,7 @@ impl ThreadView {
|
|||
),
|
||||
)
|
||||
} else {
|
||||
let stats = DiffStats::all_files(changed_buffers, cx);
|
||||
let stats = DiffStats::all_files(changed_buffers.iter().cloned(), cx);
|
||||
let dot_divider = || {
|
||||
Label::new("•")
|
||||
.size(LabelSize::XSmall)
|
||||
|
|
@ -8391,7 +8391,7 @@ impl ThreadView {
|
|||
.map(|thread| thread.read(cx).session_id().clone());
|
||||
let action_log = thread.as_ref().map(|thread| thread.read(cx).action_log());
|
||||
let changed_buffers = action_log
|
||||
.map(|log| log.read(cx).changed_buffers(cx))
|
||||
.map(|log| log.read(cx).changed_buffers(cx).collect::<Vec<_>>())
|
||||
.unwrap_or_default();
|
||||
|
||||
let is_pending_tool_call = thread_view
|
||||
|
|
@ -8404,7 +8404,7 @@ impl ThreadView {
|
|||
|
||||
let is_expanded = self.expanded_tool_calls.contains(&tool_call.id);
|
||||
let files_changed = changed_buffers.len();
|
||||
let diff_stats = DiffStats::all_files(&changed_buffers, cx);
|
||||
let diff_stats = DiffStats::all_files(changed_buffers, cx);
|
||||
|
||||
let is_running = matches!(
|
||||
tool_call.status,
|
||||
|
|
|
|||
|
|
@ -234,12 +234,6 @@ impl TextSystem {
|
|||
Ok(self.advance(font_id, font_size, 'm')?.width)
|
||||
}
|
||||
|
||||
// Consider removing this?
|
||||
/// Returns the shaped layout width of an `em`.
|
||||
pub fn em_layout_width(&self, font_id: FontId, font_size: Pixels) -> Pixels {
|
||||
self.layout_width(font_id, font_size, 'm')
|
||||
}
|
||||
|
||||
/// Returns the width of an `ch`.
|
||||
///
|
||||
/// Uses the width of the `0` character in the given font and size.
|
||||
|
|
@ -699,6 +693,28 @@ impl WindowTextSystem {
|
|||
layout
|
||||
}
|
||||
|
||||
/// Returns the shaped layout width of for the given character, in the given font and size.
|
||||
pub fn layout_width(&self, font_id: FontId, font_size: Pixels, ch: char) -> Pixels {
|
||||
let mut buffer = [0; 4];
|
||||
let buffer: &_ = ch.encode_utf8(&mut buffer);
|
||||
self.line_layout_cache
|
||||
.layout_line(
|
||||
buffer,
|
||||
font_size,
|
||||
&[FontRun {
|
||||
len: buffer.len(),
|
||||
font_id,
|
||||
}],
|
||||
None,
|
||||
)
|
||||
.width
|
||||
}
|
||||
|
||||
/// Returns the shaped layout width of an `em`.
|
||||
pub fn em_layout_width(&self, font_id: FontId, font_size: Pixels) -> Pixels {
|
||||
self.layout_width(font_id, font_size, 'm')
|
||||
}
|
||||
|
||||
/// Probe the line layout cache using a caller-provided content hash, without allocating.
|
||||
///
|
||||
/// Returns `Some(layout)` if the layout is already cached in either the current frame
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ enum ListEntry {
|
|||
is_active: bool,
|
||||
has_threads: bool,
|
||||
},
|
||||
Thread(ThreadEntry),
|
||||
Thread(Arc<ThreadEntry>),
|
||||
Terminal(TerminalEntry),
|
||||
}
|
||||
|
||||
|
|
@ -403,7 +403,7 @@ impl ListEntry {
|
|||
|
||||
impl From<ThreadEntry> for ListEntry {
|
||||
fn from(thread: ThreadEntry) -> Self {
|
||||
ListEntry::Thread(thread)
|
||||
ListEntry::Thread(Arc::new(thread))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -479,24 +479,22 @@ fn linked_worktree_path_lists_for_workspaces(
|
|||
workspaces: &[Entity<Workspace>],
|
||||
cx: &App,
|
||||
) -> Vec<PathList> {
|
||||
let mut linked_worktree_paths = HashSet::new();
|
||||
let mut linked_worktree_paths = Vec::new();
|
||||
for workspace in workspaces {
|
||||
if workspace.read(cx).visible_worktrees(cx).count() != 1 {
|
||||
continue;
|
||||
}
|
||||
for snapshot in root_repository_snapshots(workspace, cx) {
|
||||
for linked_worktree in snapshot.linked_worktrees() {
|
||||
linked_worktree_paths.insert(linked_worktree.path.clone());
|
||||
}
|
||||
linked_worktree_paths.extend(
|
||||
snapshot.linked_worktrees().iter().map(|linked_worktree| {
|
||||
PathList::new(std::slice::from_ref(&linked_worktree.path))
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let mut linked_worktree_paths = linked_worktree_paths.into_iter().collect::<Vec<_>>();
|
||||
linked_worktree_paths.sort();
|
||||
linked_worktree_paths.sort_by(|a, b| a.paths()[0].cmp(&b.paths()[0]));
|
||||
linked_worktree_paths
|
||||
.into_iter()
|
||||
.map(|path| PathList::new(std::slice::from_ref(&path)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn workspace_has_terminal_metadata_except(
|
||||
|
|
@ -1439,12 +1437,11 @@ impl Sidebar {
|
|||
.is_some_and(|active| group_workspaces.contains(active));
|
||||
|
||||
// Collect live thread infos from all workspaces in this group.
|
||||
let live_infos: Vec<_> = group_workspaces
|
||||
let live_infos = group_workspaces
|
||||
.iter()
|
||||
.flat_map(|ws| all_thread_infos_for_workspace(ws, cx))
|
||||
.collect();
|
||||
.flat_map(|ws| all_thread_infos_for_workspace(ws, cx));
|
||||
|
||||
let mut threads: Vec<ThreadEntry> = Vec::new();
|
||||
let mut threads: Vec<Arc<ThreadEntry>> = Vec::new();
|
||||
let mut has_running_threads = false;
|
||||
let mut waiting_thread_count: usize = 0;
|
||||
let group_host = group_key.host();
|
||||
|
|
@ -1461,12 +1458,12 @@ impl Sidebar {
|
|||
let thread_store = ThreadMetadataStore::global(cx);
|
||||
|
||||
let make_thread_entry =
|
||||
|row: ThreadMetadata, workspace: ThreadEntryWorkspace| -> ThreadEntry {
|
||||
|row: ThreadMetadata, workspace: ThreadEntryWorkspace| -> Arc<ThreadEntry> {
|
||||
let (icon, icon_from_external_svg) = resolve_agent_icon(&row.agent_id);
|
||||
let worktrees =
|
||||
worktree_info_from_thread_paths(&row.worktree_paths, &branch_by_path);
|
||||
let is_draft = row.is_draft();
|
||||
ThreadEntry {
|
||||
Arc::new(ThreadEntry {
|
||||
metadata: row,
|
||||
icon,
|
||||
icon_from_external_svg,
|
||||
|
|
@ -1479,7 +1476,7 @@ impl Sidebar {
|
|||
highlight_positions: Vec::new(),
|
||||
worktrees,
|
||||
diff_stats: DiffStats::default(),
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
// Main code path: one query per group via main_worktree_paths.
|
||||
|
|
@ -1574,7 +1571,7 @@ impl Sidebar {
|
|||
if !thread.is_draft {
|
||||
continue;
|
||||
}
|
||||
thread.metadata.title = draft_display_label_for_thread_metadata(
|
||||
Arc::make_mut(thread).metadata.title = draft_display_label_for_thread_metadata(
|
||||
&thread.metadata,
|
||||
&thread.workspace,
|
||||
cx,
|
||||
|
|
@ -1584,26 +1581,26 @@ impl Sidebar {
|
|||
|
||||
// Build a lookup from live_infos and compute running/waiting
|
||||
// counts in a single pass.
|
||||
let mut live_info_by_session: HashMap<&acp::SessionId, &ActiveThreadInfo> =
|
||||
let mut live_info_by_session: HashMap<acp::SessionId, ActiveThreadInfo> =
|
||||
HashMap::new();
|
||||
for info in &live_infos {
|
||||
live_info_by_session.insert(&info.session_id, info);
|
||||
for info in live_infos {
|
||||
if info.status == AgentThreadStatus::Running {
|
||||
has_running_threads = true;
|
||||
}
|
||||
if info.status == AgentThreadStatus::WaitingForConfirmation {
|
||||
waiting_thread_count += 1;
|
||||
}
|
||||
live_info_by_session.insert(info.session_id.clone(), info);
|
||||
}
|
||||
|
||||
// Merge live info into threads and update notification state
|
||||
// in a single pass.
|
||||
for thread in &mut threads {
|
||||
if let Some(session_id) = thread.metadata.session_id.clone() {
|
||||
if let Some(&info) = live_info_by_session.get(&session_id) {
|
||||
if let Some(info) = live_info_by_session.get(&session_id) {
|
||||
let status = info.status;
|
||||
let thread_id = thread.metadata.thread_id;
|
||||
thread.apply_active_info(info);
|
||||
Arc::make_mut(thread).apply_active_info(info);
|
||||
new_live_statuses.insert(session_id, (status, thread_id));
|
||||
}
|
||||
}
|
||||
|
|
@ -1637,7 +1634,7 @@ impl Sidebar {
|
|||
b_time.cmp(&a_time)
|
||||
});
|
||||
} else {
|
||||
for info in &live_infos {
|
||||
for info in live_infos {
|
||||
if info.status == AgentThreadStatus::Running {
|
||||
has_running_threads = true;
|
||||
}
|
||||
|
|
@ -1708,20 +1705,23 @@ impl Sidebar {
|
|||
fuzzy_match_positions(&query, &label).unwrap_or_default();
|
||||
let workspace_matched = !workspace_highlight_positions.is_empty();
|
||||
|
||||
let mut matched_threads: Vec<ThreadEntry> = Vec::new();
|
||||
let mut matched_threads: Vec<Arc<ThreadEntry>> = Vec::new();
|
||||
for mut thread in threads {
|
||||
let title = thread.metadata.display_title();
|
||||
if let Some(positions) = fuzzy_match_positions(&query, title.as_ref()) {
|
||||
thread.highlight_positions = positions;
|
||||
}
|
||||
let mut worktree_matched = false;
|
||||
for worktree in &mut thread.worktrees {
|
||||
let Some(name) = worktree.worktree_name.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
if let Some(positions) = fuzzy_match_positions(&query, name) {
|
||||
worktree.highlight_positions = positions;
|
||||
worktree_matched = true;
|
||||
{
|
||||
let thread = Arc::make_mut(&mut thread);
|
||||
let title = thread.metadata.display_title();
|
||||
if let Some(positions) = fuzzy_match_positions(&query, title.as_ref()) {
|
||||
thread.highlight_positions = positions;
|
||||
}
|
||||
for worktree in &mut thread.worktrees {
|
||||
let Some(name) = worktree.worktree_name.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
if let Some(positions) = fuzzy_match_positions(&query, name) {
|
||||
worktree.highlight_positions = positions;
|
||||
worktree_matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if workspace_matched
|
||||
|
|
@ -4723,7 +4723,7 @@ impl Sidebar {
|
|||
.as_ref()
|
||||
.map(|workspace| PathList::new(&workspace.read(cx).root_paths(cx)))
|
||||
});
|
||||
let thread_entry_workspace = thread_entry.map(|thread| thread.workspace);
|
||||
let thread_entry_workspace = thread_entry.map(|thread| thread.workspace.clone());
|
||||
|
||||
if let (
|
||||
Some(metadata),
|
||||
|
|
@ -5229,7 +5229,7 @@ impl Sidebar {
|
|||
fn push_entries_by_display_time(
|
||||
entries: &mut Vec<ListEntry>,
|
||||
terminals: Vec<TerminalEntry>,
|
||||
threads: Vec<ThreadEntry>,
|
||||
threads: Vec<Arc<ThreadEntry>>,
|
||||
current_session_ids: &mut HashSet<acp::SessionId>,
|
||||
current_thread_ids: &mut HashSet<agent_ui::ThreadId>,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1089,7 +1089,7 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
|
|||
is_active: true,
|
||||
has_threads: true,
|
||||
},
|
||||
ListEntry::Thread(ThreadEntry {
|
||||
ListEntry::Thread(Arc::new(ThreadEntry {
|
||||
metadata: ThreadMetadata {
|
||||
thread_id: ThreadId::new(),
|
||||
session_id: Some(acp::SessionId::new(Arc::from("t-1"))),
|
||||
|
|
@ -1114,9 +1114,9 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
|
|||
highlight_positions: Vec::new(),
|
||||
worktrees: Vec::new(),
|
||||
diff_stats: DiffStats::default(),
|
||||
}),
|
||||
})),
|
||||
// Active thread with Running status
|
||||
ListEntry::Thread(ThreadEntry {
|
||||
ListEntry::Thread(Arc::new(ThreadEntry {
|
||||
metadata: ThreadMetadata {
|
||||
thread_id: ThreadId::new(),
|
||||
session_id: Some(acp::SessionId::new(Arc::from("t-2"))),
|
||||
|
|
@ -1141,9 +1141,9 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
|
|||
highlight_positions: Vec::new(),
|
||||
worktrees: Vec::new(),
|
||||
diff_stats: DiffStats::default(),
|
||||
}),
|
||||
})),
|
||||
// Active thread with Error status
|
||||
ListEntry::Thread(ThreadEntry {
|
||||
ListEntry::Thread(Arc::new(ThreadEntry {
|
||||
metadata: ThreadMetadata {
|
||||
thread_id: ThreadId::new(),
|
||||
session_id: Some(acp::SessionId::new(Arc::from("t-3"))),
|
||||
|
|
@ -1168,10 +1168,10 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
|
|||
highlight_positions: Vec::new(),
|
||||
worktrees: Vec::new(),
|
||||
diff_stats: DiffStats::default(),
|
||||
}),
|
||||
})),
|
||||
// Thread with WaitingForConfirmation status, not active
|
||||
// remote_connection: None,
|
||||
ListEntry::Thread(ThreadEntry {
|
||||
ListEntry::Thread(Arc::new(ThreadEntry {
|
||||
metadata: ThreadMetadata {
|
||||
thread_id: ThreadId::new(),
|
||||
session_id: Some(acp::SessionId::new(Arc::from("t-4"))),
|
||||
|
|
@ -1196,10 +1196,10 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
|
|||
highlight_positions: Vec::new(),
|
||||
worktrees: Vec::new(),
|
||||
diff_stats: DiffStats::default(),
|
||||
}),
|
||||
})),
|
||||
// Background thread that completed (should show notification)
|
||||
// remote_connection: None,
|
||||
ListEntry::Thread(ThreadEntry {
|
||||
ListEntry::Thread(Arc::new(ThreadEntry {
|
||||
metadata: ThreadMetadata {
|
||||
thread_id: notified_thread_id,
|
||||
session_id: Some(acp::SessionId::new(Arc::from("t-5"))),
|
||||
|
|
@ -1224,7 +1224,7 @@ async fn test_visible_entries_as_strings(cx: &mut TestAppContext) {
|
|||
highlight_positions: Vec::new(),
|
||||
worktrees: Vec::new(),
|
||||
diff_stats: DiffStats::default(),
|
||||
}),
|
||||
})),
|
||||
// Collapsed project header
|
||||
ListEntry::ProjectHeader {
|
||||
key: ProjectGroupKey::new(None, collapsed_path.clone()),
|
||||
|
|
|
|||
Loading…
Reference in a new issue