From ac3f8f7fa1871f3845cf2448d065bd245d8e240d Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Thu, 24 Jul 2025 12:48:26 -0300 Subject: [PATCH] Return all diffs Co-authored-by: Ben Brandt Co-authored-by: Richard Feldman --- crates/acp_thread/src/acp_thread.rs | 15 ++-- crates/agent_ui/src/acp/thread_view.rs | 102 +++++++++++++------------ crates/agent_ui/src/agent_diff.rs | 6 +- crates/zed/src/zed.rs | 2 +- 4 files changed, 65 insertions(+), 60 deletions(-) diff --git a/crates/acp_thread/src/acp_thread.rs b/crates/acp_thread/src/acp_thread.rs index 4168f08a53e1b3ad72c31cc8141a726ab9206b72..a0948922b22bffdc64dff6e4ca554821153dc3ea 100644 --- a/crates/acp_thread/src/acp_thread.rs +++ b/crates/acp_thread/src/acp_thread.rs @@ -137,16 +137,15 @@ impl AgentThreadEntry { match self { Self::UserMessage(message) => message.to_markdown(cx), Self::AssistantMessage(message) => message.to_markdown(cx), - Self::ToolCall(too_call) => too_call.to_markdown(cx), + Self::ToolCall(tool_call) => tool_call.to_markdown(cx), } } - // todo! return all diffs? - pub fn first_diff(&self) -> Option<&Diff> { + pub fn diffs(&self) -> impl Iterator { if let AgentThreadEntry::ToolCall(call) = self { - call.first_diff() + itertools::Either::Left(call.diffs()) } else { - None + itertools::Either::Right(std::iter::empty()) } } @@ -197,8 +196,8 @@ impl ToolCall { } } - pub fn first_diff(&self) -> Option<&Diff> { - self.content.iter().find_map(|content| match content { + pub fn diffs(&self) -> impl Iterator { + self.content.iter().filter_map(|content| match content { ToolCallContent::ContentBlock { .. } => None, ToolCallContent::Diff { diff } => Some(diff), }) @@ -623,7 +622,7 @@ impl AcpThread { for entry in self.entries.iter().rev() { match entry { AgentThreadEntry::UserMessage(_) => return false, - AgentThreadEntry::ToolCall(call) if call.first_diff().is_some() => return true, + AgentThreadEntry::ToolCall(call) if call.diffs().next().is_some() => return true, AgentThreadEntry::ToolCall(_) | AgentThreadEntry::AssistantMessage(_) => {} } } diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 98992b2b73c472cda004be2fb731ef28872580b3..95f5ed4d3de7a32623b1f787b40e169a5b843056 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -574,62 +574,70 @@ impl AcpThreadView { window: &mut Window, cx: &mut Context, ) { - let Some(multibuffer) = self.entry_diff_multibuffer(entry_ix, cx) else { + let Some(multibuffers) = self.entry_diff_multibuffers(entry_ix, cx) else { return; }; - if self.diff_editors.contains_key(&multibuffer.entity_id()) { - return; - } + let multibuffers = multibuffers.collect::>(); - let editor = cx.new(|cx| { - let mut editor = Editor::new( - EditorMode::Full { - scale_ui_elements_with_buffer_font_size: false, - show_active_line_background: false, - sized_by_content: true, - }, - multibuffer.clone(), - None, - window, - cx, - ); - editor.set_show_gutter(false, cx); - editor.disable_inline_diagnostics(); - editor.disable_expand_excerpt_buttons(cx); - editor.set_show_vertical_scrollbar(false, cx); - editor.set_minimap_visibility(MinimapVisibility::Disabled, window, cx); - editor.set_soft_wrap_mode(SoftWrap::None, cx); - editor.scroll_manager.set_forbid_vertical_scroll(true); - editor.set_show_indent_guides(false, cx); - editor.set_read_only(true); - editor.set_show_breakpoints(false, cx); - editor.set_show_code_actions(false, cx); - editor.set_show_git_diff_gutter(false, cx); - editor.set_expand_all_diff_hunks(cx); - editor.set_text_style_refinement(TextStyleRefinement { - font_size: Some( - TextSize::Small - .rems(cx) - .to_pixels(ThemeSettings::get_global(cx).agent_font_size(cx)) - .into(), - ), - ..Default::default() + for multibuffer in multibuffers { + if self.diff_editors.contains_key(&multibuffer.entity_id()) { + return; + } + + let editor = cx.new(|cx| { + let mut editor = Editor::new( + EditorMode::Full { + scale_ui_elements_with_buffer_font_size: false, + show_active_line_background: false, + sized_by_content: true, + }, + multibuffer.clone(), + None, + window, + cx, + ); + editor.set_show_gutter(false, cx); + editor.disable_inline_diagnostics(); + editor.disable_expand_excerpt_buttons(cx); + editor.set_show_vertical_scrollbar(false, cx); + editor.set_minimap_visibility(MinimapVisibility::Disabled, window, cx); + editor.set_soft_wrap_mode(SoftWrap::None, cx); + editor.scroll_manager.set_forbid_vertical_scroll(true); + editor.set_show_indent_guides(false, cx); + editor.set_read_only(true); + editor.set_show_breakpoints(false, cx); + editor.set_show_code_actions(false, cx); + editor.set_show_git_diff_gutter(false, cx); + editor.set_expand_all_diff_hunks(cx); + editor.set_text_style_refinement(TextStyleRefinement { + font_size: Some( + TextSize::Small + .rems(cx) + .to_pixels(ThemeSettings::get_global(cx).agent_font_size(cx)) + .into(), + ), + ..Default::default() + }); + editor }); - editor - }); - let entity_id = multibuffer.entity_id(); - cx.observe_release(&multibuffer, move |this, _, _| { - this.diff_editors.remove(&entity_id); - }) - .detach(); + let entity_id = multibuffer.entity_id(); + cx.observe_release(&multibuffer, move |this, _, _| { + this.diff_editors.remove(&entity_id); + }) + .detach(); - self.diff_editors.insert(entity_id, editor); + self.diff_editors.insert(entity_id, editor); + } } - fn entry_diff_multibuffer(&self, entry_ix: usize, cx: &App) -> Option> { + fn entry_diff_multibuffers( + &self, + entry_ix: usize, + cx: &App, + ) -> Option>> { let entry = self.thread()?.read(cx).entries().get(entry_ix)?; - entry.first_diff().map(|diff| diff.multibuffer.clone()) + Some(entry.diffs().map(|diff| diff.multibuffer.clone())) } fn authenticate(&mut self, window: &mut Window, cx: &mut Context) { diff --git a/crates/agent_ui/src/agent_diff.rs b/crates/agent_ui/src/agent_diff.rs index 3f1ea41f491db4e0efebf86d6df8350368a21336..ec0a11f86b6b2ef8b2b12179a93fdffaf4926d79 100644 --- a/crates/agent_ui/src/agent_diff.rs +++ b/crates/agent_ui/src/agent_diff.rs @@ -1506,8 +1506,7 @@ impl AgentDiff { .read(cx) .entries() .last() - .and_then(|entry| entry.first_diff()) - .is_some() + .map_or(false, |entry| entry.diffs().next().is_some()) { self.update_reviewing_editors(workspace, window, cx); } @@ -1517,8 +1516,7 @@ impl AgentDiff { .read(cx) .entries() .get(*ix) - .and_then(|entry| entry.first_diff()) - .is_some() + .map_or(false, |entry| entry.diffs().next().is_some()) { self.update_reviewing_editors(workspace, window, cx); } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index afb40ef37f539f5ff53e22e5e5b53da5f8b370d7..57534c8cd540c171069751281e2bc824ed05c343 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -19,7 +19,7 @@ use collections::VecDeque; use debugger_ui::debugger_panel::DebugPanel; use editor::ProposedChangesEditorToolbar; use editor::{Editor, MultiBuffer}; -use feature_flags::FeatureFlagAppExt; +use feature_flags::{FeatureFlagAppExt, PanicFeatureFlag}; use futures::future::Either; use futures::{StreamExt, channel::mpsc, select_biased}; use git_ui::git_panel::GitPanel;