svg_preview: Remove unnecessary dependency on editor (#43147)

Lukas Wirth created

Editor is a choke point in our compilation graph while also being a very
common crate that is being edited. So reducing things that depend on it
will generally improve compilation times for us.

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

Cargo.lock                                     |  2 
crates/agent_ui/src/agent_diff.rs              | 10 ++--
crates/agent_ui/src/text_thread_editor.rs      | 18 +++---
crates/breadcrumbs/src/breadcrumbs.rs          |  2 
crates/collab_ui/src/channel_view.rs           | 10 ++--
crates/debugger_ui/src/stack_trace_view.rs     |  8 +-
crates/diagnostics/src/buffer_diagnostics.rs   |  6 +-
crates/diagnostics/src/diagnostics.rs          |  8 +-
crates/editor/src/editor_tests.rs              |  2 
crates/editor/src/items.rs                     | 15 ++++++
crates/git_ui/src/commit_view.rs               | 12 ++--
crates/git_ui/src/file_diff_view.rs            | 10 ++--
crates/git_ui/src/project_diff.rs              |  8 +-
crates/git_ui/src/text_diff_view.rs            | 10 ++--
crates/language_tools/src/lsp_log_view.rs      | 10 ++--
crates/search/src/project_search.rs            |  9 +--
crates/svg_preview/Cargo.toml                  |  2 
crates/svg_preview/src/svg_preview_view.rs     | 50 ++++++++-----------
crates/workspace/src/item.rs                   | 26 +++++-----
crates/workspace/src/pane.rs                   |  6 +-
crates/workspace/src/searchable.rs             |  4 
crates/workspace/src/workspace.rs              |  8 +-
crates/zed/src/zed/quick_action_bar/preview.rs |  2 
crates/zeta2_tools/src/zeta2_context_view.rs   |  8 +-
24 files changed, 127 insertions(+), 119 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -16561,10 +16561,10 @@ checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb"
 name = "svg_preview"
 version = "0.1.0"
 dependencies = [
- "editor",
  "file_icons",
  "gpui",
  "language",
+ "multi_buffer",
  "ui",
  "workspace",
 ]

crates/agent_ui/src/agent_diff.rs 🔗

@@ -13,8 +13,8 @@ use editor::{
     scroll::Autoscroll,
 };
 use gpui::{
-    Action, AnyElement, AnyView, App, AppContext, Empty, Entity, EventEmitter, FocusHandle,
-    Focusable, Global, SharedString, Subscription, Task, WeakEntity, Window, prelude::*,
+    Action, AnyElement, App, AppContext, Empty, Entity, EventEmitter, FocusHandle, Focusable,
+    Global, SharedString, Subscription, Task, WeakEntity, Window, prelude::*,
 };
 
 use language::{Buffer, Capability, DiskState, OffsetRangeExt, Point};
@@ -580,11 +580,11 @@ impl Item for AgentDiffPane {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/agent_ui/src/text_thread_editor.rs 🔗

@@ -22,11 +22,11 @@ use editor::{FoldPlaceholder, display_map::CreaseId};
 use fs::Fs;
 use futures::FutureExt;
 use gpui::{
-    Action, Animation, AnimationExt, AnyElement, AnyView, App, ClipboardEntry, ClipboardItem,
-    Empty, Entity, EventEmitter, FocusHandle, Focusable, FontWeight, Global, InteractiveElement,
-    IntoElement, ParentElement, Pixels, Render, RenderImage, SharedString, Size,
-    StatefulInteractiveElement, Styled, Subscription, Task, WeakEntity, actions, div, img, point,
-    prelude::*, pulsating_between, size,
+    Action, Animation, AnimationExt, AnyElement, App, ClipboardEntry, ClipboardItem, Empty, Entity,
+    EventEmitter, FocusHandle, Focusable, FontWeight, Global, InteractiveElement, IntoElement,
+    ParentElement, Pixels, Render, RenderImage, SharedString, Size, StatefulInteractiveElement,
+    Styled, Subscription, Task, WeakEntity, actions, div, img, point, prelude::*,
+    pulsating_between, size,
 };
 use language::{
     BufferSnapshot, LspAdapterDelegate, ToOffset,
@@ -66,7 +66,7 @@ use workspace::{
 };
 use workspace::{
     Save, Toast, Workspace,
-    item::{self, FollowableItem, Item, ItemHandle},
+    item::{self, FollowableItem, Item},
     notifications::NotificationId,
     pane,
     searchable::{SearchEvent, SearchableItem},
@@ -2588,11 +2588,11 @@ impl Item for TextThreadEditor {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/breadcrumbs/src/breadcrumbs.rs 🔗

@@ -123,7 +123,7 @@ impl Render for Breadcrumbs {
                                 .upgrade()
                                 .zip(zed_actions::outline::TOGGLE_OUTLINE.get())
                             {
-                                callback(editor.to_any(), window, cx);
+                                callback(editor.to_any_view(), window, cx);
                             }
                         }
                     })

crates/collab_ui/src/channel_view.rs 🔗

@@ -11,7 +11,7 @@ use editor::{
     display_map::ToDisplayPoint, scroll::Autoscroll,
 };
 use gpui::{
-    AnyView, App, ClipboardItem, Context, Entity, EventEmitter, Focusable, Pixels, Point, Render,
+    App, ClipboardItem, Context, Entity, EventEmitter, Focusable, Pixels, Point, Render,
     Subscription, Task, VisualContext as _, WeakEntity, Window, actions,
 };
 use project::Project;
@@ -25,7 +25,7 @@ use util::ResultExt;
 use workspace::{CollaboratorId, item::TabContentParams};
 use workspace::{
     ItemNavHistory, Pane, SaveIntent, Toast, ViewId, Workspace, WorkspaceId,
-    item::{FollowableItem, Item, ItemEvent, ItemHandle},
+    item::{FollowableItem, Item, ItemEvent},
     searchable::SearchableItemHandle,
 };
 use workspace::{item::Dedup, notifications::NotificationId};
@@ -441,11 +441,11 @@ impl Item for ChannelView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/debugger_ui/src/stack_trace_view.rs 🔗

@@ -7,7 +7,7 @@ use editor::{
     RowHighlightOptions, SelectionEffects, ToPoint, scroll::Autoscroll,
 };
 use gpui::{
-    AnyView, App, AppContext, Entity, EventEmitter, Focusable, IntoElement, Render, SharedString,
+    App, AppContext, Entity, EventEmitter, Focusable, IntoElement, Render, SharedString,
     Subscription, Task, WeakEntity, Window,
 };
 use language::{BufferSnapshot, Capability, Point, Selection, SelectionGoal, TreeSitterOptions};
@@ -418,11 +418,11 @@ impl Item for StackTraceView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/diagnostics/src/buffer_diagnostics.rs 🔗

@@ -680,11 +680,11 @@ impl Item for BufferDiagnosticsEditor {
         type_id: std::any::TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<gpui::AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/diagnostics/src/diagnostics.rs 🔗

@@ -17,7 +17,7 @@ use editor::{
     multibuffer_context_lines,
 };
 use gpui::{
-    AnyElement, AnyView, App, AsyncApp, Context, Entity, EventEmitter, FocusHandle, FocusOutEvent,
+    AnyElement, App, AsyncApp, Context, Entity, EventEmitter, FocusHandle, FocusOutEvent,
     Focusable, Global, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
     Styled, Subscription, Task, WeakEntity, Window, actions, div,
 };
@@ -880,11 +880,11 @@ impl Item for ProjectDiagnosticsEditor {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/editor/src/editor_tests.rs 🔗

@@ -26983,7 +26983,7 @@ async fn test_non_utf_8_opens(cx: &mut TestAppContext) {
         .unwrap();
 
     assert_eq!(
-        handle.to_any().entity_type(),
+        handle.to_any_view().entity_type(),
         TypeId::of::<InvalidItemView>()
     );
 }

crates/editor/src/items.rs 🔗

@@ -588,6 +588,21 @@ fn deserialize_anchor(buffer: &MultiBufferSnapshot, anchor: proto::EditorAnchor)
 impl Item for Editor {
     type Event = EditorEvent;
 
+    fn act_as_type<'a>(
+        &'a self,
+        type_id: TypeId,
+        self_handle: &'a Entity<Self>,
+        cx: &'a App,
+    ) -> Option<gpui::AnyEntity> {
+        if TypeId::of::<Self>() == type_id {
+            Some(self_handle.clone().into())
+        } else if TypeId::of::<MultiBuffer>() == type_id {
+            Some(self_handle.read(cx).buffer.clone().into())
+        } else {
+            None
+        }
+    }
+
     fn navigate(
         &mut self,
         data: Box<dyn std::any::Any>,

crates/git_ui/src/commit_view.rs 🔗

@@ -6,9 +6,9 @@ use editor::{
 };
 use git::repository::{CommitDetails, CommitDiff, RepoPath};
 use gpui::{
-    Action, AnyElement, AnyView, App, AppContext as _, AsyncApp, AsyncWindowContext, Context,
-    Entity, EventEmitter, FocusHandle, Focusable, IntoElement, PromptLevel, Render, Task,
-    WeakEntity, Window, actions,
+    Action, AnyElement, App, AppContext as _, AsyncApp, AsyncWindowContext, Context, Entity,
+    EventEmitter, FocusHandle, Focusable, IntoElement, PromptLevel, Render, Task, WeakEntity,
+    Window, actions,
 };
 use language::{
     Anchor, Buffer, Capability, DiskState, File, LanguageRegistry, LineEnding, OffsetRangeExt as _,
@@ -499,11 +499,11 @@ impl Item for CommitView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/git_ui/src/file_diff_view.rs 🔗

@@ -5,8 +5,8 @@ use buffer_diff::{BufferDiff, BufferDiffSnapshot};
 use editor::{Editor, EditorEvent, MultiBuffer};
 use futures::{FutureExt, select_biased};
 use gpui::{
-    AnyElement, AnyView, App, AppContext as _, AsyncApp, Context, Entity, EventEmitter,
-    FocusHandle, Focusable, IntoElement, Render, Task, Window,
+    AnyElement, App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, FocusHandle,
+    Focusable, IntoElement, Render, Task, Window,
 };
 use language::Buffer;
 use project::Project;
@@ -268,11 +268,11 @@ impl Item for FileDiffView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/git_ui/src/project_diff.rs 🔗

@@ -19,7 +19,7 @@ use git::{
     status::FileStatus,
 };
 use gpui::{
-    Action, AnyElement, AnyView, App, AppContext as _, AsyncWindowContext, Entity, EventEmitter,
+    Action, AnyElement, App, AppContext as _, AsyncWindowContext, Entity, EventEmitter,
     FocusHandle, Focusable, Render, Subscription, Task, WeakEntity, actions,
 };
 use language::{Anchor, Buffer, Capability, OffsetRangeExt};
@@ -775,11 +775,11 @@ impl Item for ProjectDiff {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/git_ui/src/text_diff_view.rs 🔗

@@ -5,8 +5,8 @@ use buffer_diff::{BufferDiff, BufferDiffSnapshot};
 use editor::{Editor, EditorEvent, MultiBuffer, ToPoint, actions::DiffClipboardWithSelectionData};
 use futures::{FutureExt, select_biased};
 use gpui::{
-    AnyElement, AnyView, App, AppContext as _, AsyncApp, Context, Entity, EventEmitter,
-    FocusHandle, Focusable, IntoElement, Render, Task, Window,
+    AnyElement, App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, FocusHandle,
+    Focusable, IntoElement, Render, Task, Window,
 };
 use language::{self, Buffer, Point};
 use project::Project;
@@ -329,11 +329,11 @@ impl Item for TextDiffView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.diff_editor.to_any())
+            Some(self.diff_editor.clone().into())
         } else {
             None
         }

crates/language_tools/src/lsp_log_view.rs 🔗

@@ -2,8 +2,8 @@ use collections::VecDeque;
 use copilot::Copilot;
 use editor::{Editor, EditorEvent, MultiBufferOffset, actions::MoveToEnd, scroll::Autoscroll};
 use gpui::{
-    AnyView, App, Context, Corner, Entity, EventEmitter, FocusHandle, Focusable, IntoElement,
-    ParentElement, Render, Styled, Subscription, Task, WeakEntity, Window, actions, div,
+    App, Context, Corner, Entity, EventEmitter, FocusHandle, Focusable, IntoElement, ParentElement,
+    Render, Styled, Subscription, Task, WeakEntity, Window, actions, div,
 };
 use itertools::Itertools;
 use language::{LanguageServerId, language_settings::SoftWrap};
@@ -748,11 +748,11 @@ impl Item for LspLogView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.editor.to_any())
+            Some(self.editor.clone().into())
         } else {
             None
         }

crates/search/src/project_search.rs 🔗

@@ -17,10 +17,9 @@ use editor::{
 };
 use futures::{StreamExt, stream::FuturesOrdered};
 use gpui::{
-    Action, AnyElement, AnyView, App, Axis, Context, Entity, EntityId, EventEmitter, FocusHandle,
-    Focusable, Global, Hsla, InteractiveElement, IntoElement, KeyContext, ParentElement, Point,
-    Render, SharedString, Styled, Subscription, Task, UpdateGlobal, WeakEntity, Window, actions,
-    div,
+    Action, AnyElement, App, Axis, Context, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
+    Global, Hsla, InteractiveElement, IntoElement, KeyContext, ParentElement, Point, Render,
+    SharedString, Styled, Subscription, Task, UpdateGlobal, WeakEntity, Window, actions, div,
 };
 use language::{Buffer, Language};
 use menu::Confirm;
@@ -497,7 +496,7 @@ impl Item for ProjectSearchView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
             Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {

crates/svg_preview/Cargo.toml 🔗

@@ -12,7 +12,7 @@ workspace = true
 path = "src/svg_preview.rs"
 
 [dependencies]
-editor.workspace = true
+multi_buffer.workspace = true
 file_icons.workspace = true
 gpui.workspace = true
 language.workspace = true

crates/svg_preview/src/svg_preview_view.rs 🔗

@@ -1,13 +1,13 @@
 use std::mem;
 use std::sync::Arc;
 
-use editor::Editor;
 use file_icons::FileIcons;
 use gpui::{
     App, Context, Entity, EventEmitter, FocusHandle, Focusable, IntoElement, ParentElement, Render,
     RenderImage, Styled, Subscription, Task, WeakEntity, Window, div, img,
 };
 use language::{Buffer, BufferEvent};
+use multi_buffer::MultiBuffer;
 use ui::prelude::*;
 use workspace::item::Item;
 use workspace::{Pane, Workspace};
@@ -34,7 +34,7 @@ pub enum SvgPreviewMode {
 impl SvgPreviewView {
     pub fn new(
         mode: SvgPreviewMode,
-        active_editor: Entity<Editor>,
+        active_buffer: Entity<MultiBuffer>,
         workspace_handle: WeakEntity<Workspace>,
         window: &mut Window,
         cx: &mut Context<Workspace>,
@@ -48,11 +48,7 @@ impl SvgPreviewView {
                 None
             };
 
-            let buffer = active_editor
-                .read(cx)
-                .buffer()
-                .clone()
-                .read_with(cx, |buffer, _cx| buffer.as_singleton());
+            let buffer = active_buffer.read_with(cx, |buffer, _cx| buffer.as_singleton());
 
             let subscription = buffer
                 .as_ref()
@@ -84,10 +80,10 @@ impl SvgPreviewView {
                 if let workspace::Event::ActiveItemChanged = event {
                     let workspace = workspace.read(cx);
                     if let Some(active_item) = workspace.active_item(cx)
-                        && let Some(editor) = active_item.downcast::<Editor>()
-                        && Self::is_svg_file(&editor, cx)
+                        && let Some(buffer) = active_item.downcast::<MultiBuffer>()
+                        && Self::is_svg_file(&buffer, cx)
                     {
-                        let Some(buffer) = editor.read(cx).buffer().read(cx).as_singleton() else {
+                        let Some(buffer) = buffer.read(cx).as_singleton() else {
                             return;
                         };
                         if this.buffer.as_ref() != Some(&buffer) {
@@ -142,10 +138,10 @@ impl SvgPreviewView {
 
     fn find_existing_preview_item_idx(
         pane: &Pane,
-        editor: &Entity<Editor>,
+        buffer: &Entity<MultiBuffer>,
         cx: &App,
     ) -> Option<usize> {
-        let buffer_id = editor.read(cx).buffer().entity_id();
+        let buffer_id = buffer.entity_id();
         pane.items_of_type::<SvgPreviewView>()
             .find(|view| {
                 view.read(cx)
@@ -156,25 +152,25 @@ impl SvgPreviewView {
             .and_then(|view| pane.index_for_item(&view))
     }
 
-    pub fn resolve_active_item_as_svg_editor(
+    pub fn resolve_active_item_as_svg_buffer(
         workspace: &Workspace,
         cx: &mut Context<Workspace>,
-    ) -> Option<Entity<Editor>> {
+    ) -> Option<Entity<MultiBuffer>> {
         workspace
             .active_item(cx)?
-            .act_as::<Editor>(cx)
-            .filter(|editor| Self::is_svg_file(&editor, cx))
+            .act_as::<MultiBuffer>(cx)
+            .filter(|buffer| Self::is_svg_file(&buffer, cx))
     }
 
     fn create_svg_view(
         mode: SvgPreviewMode,
         workspace: &mut Workspace,
-        editor: Entity<Editor>,
+        buffer: Entity<MultiBuffer>,
         window: &mut Window,
         cx: &mut Context<Workspace>,
     ) -> Entity<SvgPreviewView> {
         let workspace_handle = workspace.weak_handle();
-        SvgPreviewView::new(mode, editor, workspace_handle, window, cx)
+        SvgPreviewView::new(mode, buffer, workspace_handle, window, cx)
     }
 
     fn create_buffer_subscription(
@@ -194,10 +190,8 @@ impl SvgPreviewView {
         )
     }
 
-    pub fn is_svg_file(editor: &Entity<Editor>, cx: &App) -> bool {
-        editor
-            .read(cx)
-            .buffer()
+    pub fn is_svg_file(buffer: &Entity<MultiBuffer>, cx: &App) -> bool {
+        buffer
             .read(cx)
             .as_singleton()
             .and_then(|buffer| buffer.read(cx).file())
@@ -210,19 +204,19 @@ impl SvgPreviewView {
 
     pub fn register(workspace: &mut Workspace, _window: &mut Window, _cx: &mut Context<Workspace>) {
         workspace.register_action(move |workspace, _: &OpenPreview, window, cx| {
-            if let Some(editor) = Self::resolve_active_item_as_svg_editor(workspace, cx)
-                && Self::is_svg_file(&editor, cx)
+            if let Some(buffer) = Self::resolve_active_item_as_svg_buffer(workspace, cx)
+                && Self::is_svg_file(&buffer, cx)
             {
                 let view = Self::create_svg_view(
                     SvgPreviewMode::Default,
                     workspace,
-                    editor.clone(),
+                    buffer.clone(),
                     window,
                     cx,
                 );
                 workspace.active_pane().update(cx, |pane, cx| {
                     if let Some(existing_view_idx) =
-                        Self::find_existing_preview_item_idx(pane, &editor, cx)
+                        Self::find_existing_preview_item_idx(pane, &buffer, cx)
                     {
                         pane.activate_item(existing_view_idx, true, true, window, cx);
                     } else {
@@ -234,7 +228,7 @@ impl SvgPreviewView {
         });
 
         workspace.register_action(move |workspace, _: &OpenPreviewToTheSide, window, cx| {
-            if let Some(editor) = Self::resolve_active_item_as_svg_editor(workspace, cx)
+            if let Some(editor) = Self::resolve_active_item_as_svg_buffer(workspace, cx)
                 && Self::is_svg_file(&editor, cx)
             {
                 let editor_clone = editor.clone();
@@ -269,7 +263,7 @@ impl SvgPreviewView {
         });
 
         workspace.register_action(move |workspace, _: &OpenFollowingPreview, window, cx| {
-            if let Some(editor) = Self::resolve_active_item_as_svg_editor(workspace, cx)
+            if let Some(editor) = Self::resolve_active_item_as_svg_buffer(workspace, cx)
                 && Self::is_svg_file(&editor, cx)
             {
                 let view =

crates/workspace/src/item.rs 🔗

@@ -11,9 +11,9 @@ use anyhow::Result;
 use client::{Client, proto};
 use futures::{StreamExt, channel::mpsc};
 use gpui::{
-    Action, AnyElement, AnyView, App, AppContext, Context, Entity, EntityId, EventEmitter,
-    FocusHandle, Focusable, Font, HighlightStyle, Pixels, Point, Render, SharedString, Task,
-    WeakEntity, Window,
+    Action, AnyElement, AnyEntity, AnyView, App, AppContext, Context, Entity, EntityId,
+    EventEmitter, FocusHandle, Focusable, Font, HighlightStyle, Pixels, Point, Render,
+    SharedString, Task, WeakEntity, Window,
 };
 use project::{Project, ProjectEntryId, ProjectPath};
 pub use settings::{
@@ -279,7 +279,7 @@ pub trait Item: Focusable + EventEmitter<Self::Event> + Render + Sized {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<AnyView> {
+    ) -> Option<AnyEntity> {
         if TypeId::of::<Self>() == type_id {
             Some(self_handle.clone().into())
         } else {
@@ -454,7 +454,7 @@ pub trait ItemHandle: 'static + Send {
     fn workspace_deactivated(&self, window: &mut Window, cx: &mut App);
     fn navigate(&self, data: Box<dyn Any>, window: &mut Window, cx: &mut App) -> bool;
     fn item_id(&self) -> EntityId;
-    fn to_any(&self) -> AnyView;
+    fn to_any_view(&self) -> AnyView;
     fn is_dirty(&self, cx: &App) -> bool;
     fn has_deleted_file(&self, cx: &App) -> bool;
     fn has_conflict(&self, cx: &App) -> bool;
@@ -480,7 +480,7 @@ pub trait ItemHandle: 'static + Send {
         window: &mut Window,
         cx: &mut App,
     ) -> Task<Result<()>>;
-    fn act_as_type(&self, type_id: TypeId, cx: &App) -> Option<AnyView>;
+    fn act_as_type(&self, type_id: TypeId, cx: &App) -> Option<AnyEntity>;
     fn to_followable_item_handle(&self, cx: &App) -> Option<Box<dyn FollowableItemHandle>>;
     fn to_serializable_item_handle(&self, cx: &App) -> Option<Box<dyn SerializableItemHandle>>;
     fn on_release(
@@ -513,7 +513,7 @@ pub trait WeakItemHandle: Send + Sync {
 
 impl dyn ItemHandle {
     pub fn downcast<V: 'static>(&self) -> Option<Entity<V>> {
-        self.to_any().downcast().ok()
+        self.to_any_view().downcast().ok()
     }
 
     pub fn act_as<V: 'static>(&self, cx: &App) -> Option<Entity<V>> {
@@ -911,7 +911,7 @@ impl<T: Item> ItemHandle for Entity<T> {
         self.entity_id()
     }
 
-    fn to_any(&self) -> AnyView {
+    fn to_any_view(&self) -> AnyView {
         self.clone().into()
     }
 
@@ -964,7 +964,7 @@ impl<T: Item> ItemHandle for Entity<T> {
         self.update(cx, |item, cx| item.reload(project, window, cx))
     }
 
-    fn act_as_type<'a>(&'a self, type_id: TypeId, cx: &'a App) -> Option<AnyView> {
+    fn act_as_type<'a>(&'a self, type_id: TypeId, cx: &'a App) -> Option<AnyEntity> {
         self.read(cx).act_as_type(type_id, self, cx)
     }
 
@@ -1009,7 +1009,7 @@ impl<T: Item> ItemHandle for Entity<T> {
     }
 
     fn to_serializable_item_handle(&self, cx: &App) -> Option<Box<dyn SerializableItemHandle>> {
-        SerializableItemRegistry::view_to_serializable_item_handle(self.to_any(), cx)
+        SerializableItemRegistry::view_to_serializable_item_handle(self.to_any_view(), cx)
     }
 
     fn preserve_preview(&self, cx: &App) -> bool {
@@ -1030,13 +1030,13 @@ impl<T: Item> ItemHandle for Entity<T> {
 
 impl From<Box<dyn ItemHandle>> for AnyView {
     fn from(val: Box<dyn ItemHandle>) -> Self {
-        val.to_any()
+        val.to_any_view()
     }
 }
 
 impl From<&Box<dyn ItemHandle>> for AnyView {
     fn from(val: &Box<dyn ItemHandle>) -> Self {
-        val.to_any()
+        val.to_any_view()
     }
 }
 
@@ -1247,7 +1247,7 @@ impl<T: FollowableItem> FollowableItemHandle for Entity<T> {
         window: &mut Window,
         cx: &mut App,
     ) -> Option<Dedup> {
-        let existing = existing.to_any().downcast::<T>().ok()?;
+        let existing = existing.to_any_view().downcast::<T>().ok()?;
         self.read(cx).dedup(existing.read(cx), window, cx)
     }
 

crates/workspace/src/pane.rs 🔗

@@ -1203,7 +1203,7 @@ impl Pane {
     pub fn items_of_type<T: Render>(&self) -> impl '_ + Iterator<Item = Entity<T>> {
         self.items
             .iter()
-            .filter_map(|item| item.to_any().downcast().ok())
+            .filter_map(|item| item.to_any_view().downcast().ok())
     }
 
     pub fn active_item(&self) -> Option<Box<dyn ItemHandle>> {
@@ -3869,7 +3869,7 @@ impl Render for Pane {
                                 .size_full()
                                 .overflow_hidden()
                                 .child(self.toolbar.clone())
-                                .child(item.to_any())
+                                .child(item.to_any_view())
                         } else {
                             let placeholder = div
                                 .id("pane_placeholder")
@@ -6957,7 +6957,7 @@ mod tests {
                 .enumerate()
                 .map(|(ix, item)| {
                     let mut state = item
-                        .to_any()
+                        .to_any_view()
                         .downcast::<TestItem>()
                         .unwrap()
                         .read(cx)

crates/workspace/src/searchable.rs 🔗

@@ -399,13 +399,13 @@ impl<T: SearchableItem> SearchableItemHandle for Entity<T> {
 
 impl From<Box<dyn SearchableItemHandle>> for AnyView {
     fn from(this: Box<dyn SearchableItemHandle>) -> Self {
-        this.to_any()
+        this.to_any_view()
     }
 }
 
 impl From<&Box<dyn SearchableItemHandle>> for AnyView {
     fn from(this: &Box<dyn SearchableItemHandle>) -> Self {
-        this.to_any()
+        this.to_any_view()
     }
 }
 

crates/workspace/src/workspace.rs 🔗

@@ -2869,7 +2869,7 @@ impl Workspace {
 
     pub fn active_item_as<I: 'static>(&self, cx: &App) -> Option<Entity<I>> {
         let item = self.active_item(cx)?;
-        item.to_any().downcast::<I>().ok()
+        item.to_any_view().downcast::<I>().ok()
     }
 
     fn active_project_path(&self, cx: &App) -> Option<ProjectPath> {
@@ -11214,7 +11214,7 @@ mod tests {
 
             // Now we can check if the handle we got back errored or not
             assert_eq!(
-                handle.to_any().entity_type(),
+                handle.to_any_view().entity_type(),
                 TypeId::of::<TestPngItemView>()
             );
 
@@ -11227,7 +11227,7 @@ mod tests {
                 .unwrap();
 
             assert_eq!(
-                handle.to_any().entity_type(),
+                handle.to_any_view().entity_type(),
                 TypeId::of::<TestIpynbItemView>()
             );
 
@@ -11276,7 +11276,7 @@ mod tests {
 
             // This _must_ be the second item registered
             assert_eq!(
-                handle.to_any().entity_type(),
+                handle.to_any_view().entity_type(),
                 TypeId::of::<TestAlternatePngItemView>()
             );
 

crates/zed/src/zed/quick_action_bar/preview.rs 🔗

@@ -32,7 +32,7 @@ impl QuickActionBar {
                     .is_some()
                 {
                     preview_type = Some(PreviewType::Markdown);
-                } else if SvgPreviewView::resolve_active_item_as_svg_editor(workspace, cx).is_some()
+                } else if SvgPreviewView::resolve_active_item_as_svg_buffer(workspace, cx).is_some()
                 {
                     preview_type = Some(PreviewType::Svg);
                 }

crates/zeta2_tools/src/zeta2_context_view.rs 🔗

@@ -24,7 +24,7 @@ use ui::{
     IconSize, InteractiveElement, IntoElement, ListHeader, ListItem, StyledTypography, div, h_flex,
     v_flex,
 };
-use workspace::{Item, ItemHandle as _};
+use workspace::Item;
 use zeta2::{
     Zeta, ZetaContextRetrievalDebugInfo, ZetaContextRetrievalStartedDebugInfo, ZetaDebugInfo,
     ZetaSearchQueryDebugInfo,
@@ -402,11 +402,11 @@ impl Item for Zeta2ContextView {
         type_id: TypeId,
         self_handle: &'a Entity<Self>,
         _: &'a App,
-    ) -> Option<gpui::AnyView> {
+    ) -> Option<gpui::AnyEntity> {
         if type_id == TypeId::of::<Self>() {
-            Some(self_handle.to_any())
+            Some(self_handle.clone().into())
         } else if type_id == TypeId::of::<Editor>() {
-            Some(self.runs.get(self.current_ix)?.editor.to_any())
+            Some(self.runs.get(self.current_ix)?.editor.clone().into())
         } else {
             None
         }