From fbeffc4f37d17da189ec3812bef13ff46f51fd4c Mon Sep 17 00:00:00 2001 From: Dino Date: Mon, 9 Mar 2026 17:45:36 +0000 Subject: [PATCH] Fix expand/collapse all button for splittable editor (#50859) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Expand All Files"/"Collapse All Files" button in `BufferSearchBar` was broken for `SplittableEditor`, which is used in the project diff view. It was happening because `ProjectDiff::as_searchable` returns an handle to the `SplittableEditor`, which the search bar implementation then tries to downcast to an `Editor`, which the `SplittableEditor` did not support, so both the expand/collapse all buttons, as well as the collapse state were broken. Unfortunately this was accidentally introduced in https://github.com/zed-industries/zed/pull/48773 , so this Pull Request updates the `Item` implementation for `SplittableEditor` in order for it to be able to act as an `Editor`. Release Notes: - Fix the "Expand All Files"/"Collapse All Files" button in the project diff view --------- Co-authored-by: Tom Houlé --- crates/editor/src/split.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/crates/editor/src/split.rs b/crates/editor/src/split.rs index b3511915be42ae9816bfb8fece19d28a2a6ca6e3..4e5f8ebf2793f6807e0a9108e12c276a7ab45427 100644 --- a/crates/editor/src/split.rs +++ b/crates/editor/src/split.rs @@ -1857,6 +1857,21 @@ impl Item for SplittableEditor { fn pixel_position_of_cursor(&self, cx: &App) -> Option> { self.focused_editor().read(cx).pixel_position_of_cursor(cx) } + + fn act_as_type<'a>( + &'a self, + type_id: std::any::TypeId, + self_handle: &'a Entity, + _: &'a App, + ) -> Option { + if type_id == std::any::TypeId::of::() { + Some(self_handle.clone().into()) + } else if type_id == std::any::TypeId::of::() { + Some(self.rhs_editor.clone().into()) + } else { + None + } + } } impl SearchableItem for SplittableEditor { @@ -2064,7 +2079,7 @@ impl Render for SplittableEditor { #[cfg(test)] mod tests { - use std::sync::Arc; + use std::{any::TypeId, sync::Arc}; use buffer_diff::BufferDiff; use collections::{HashMap, HashSet}; @@ -2080,14 +2095,14 @@ mod tests { use settings::{DiffViewStyle, SettingsStore}; use ui::{VisualContext as _, div, px}; use util::rel_path::rel_path; - use workspace::MultiWorkspace; + use workspace::{Item, MultiWorkspace}; - use crate::SplittableEditor; use crate::display_map::{ BlockPlacement, BlockProperties, BlockStyle, Crease, FoldPlaceholder, }; use crate::inlays::Inlay; use crate::test::{editor_content_with_blocks_and_width, set_block_content_for_tests}; + use crate::{Editor, SplittableEditor}; use multi_buffer::MultiBufferOffset; async fn init_test( @@ -6025,4 +6040,17 @@ mod tests { cx.run_until_parked(); } + + #[gpui::test] + async fn test_act_as_type(cx: &mut gpui::TestAppContext) { + let (splittable_editor, cx) = init_test(cx, SoftWrap::None, DiffViewStyle::Split).await; + let editor = splittable_editor.read_with(cx, |editor, cx| { + editor.act_as_type(TypeId::of::(), &splittable_editor, cx) + }); + + assert!( + editor.is_some(), + "SplittableEditor should be able to act as Editor" + ); + } }