Update editor to use new event emitter

Mikayla created

Change summary

crates/editor2/src/editor.rs | 51 +++++++++++++++-------
crates/editor2/src/items.rs  | 84 +++++++++++--------------------------
2 files changed, 60 insertions(+), 75 deletions(-)

Detailed changes

crates/editor2/src/editor.rs 🔗

@@ -39,10 +39,10 @@ use futures::FutureExt;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use git::diff_hunk_to_display;
 use gpui::{
-    action, actions, div, px, relative, AnyElement, AppContext, BackgroundExecutor, ClipboardItem,
-    Context, DispatchContext, Div, Element, Entity, EventEmitter, FocusHandle, FontStyle,
-    FontWeight, HighlightStyle, Hsla, InputHandler, Model, Pixels, PlatformInputHandler, Render,
-    Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakView,
+    action, actions, div, px, relative, AnyElement, AppContext, BackgroundExecutor, BorrowWindow,
+    ClipboardItem, Context, DispatchContext, Div, Element, Entity, EventEmitter, FocusHandle,
+    FontStyle, FontWeight, HighlightStyle, Hsla, InputHandler, Model, Pixels, PlatformInputHandler,
+    Render, Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakView,
     WindowContext,
 };
 use highlight_matching_bracket::refresh_matching_bracket_highlights;
@@ -96,7 +96,9 @@ use theme::{
     ActiveTheme, DiagnosticStyle, PlayerColor, SyntaxTheme, Theme, ThemeColors, ThemeSettings,
 };
 use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
-use workspace::{ItemNavHistory, SplitDirection, ViewId, Workspace};
+use workspace::{
+    item::ItemEvent, searchable::SearchEvent, ItemNavHistory, SplitDirection, ViewId, Workspace,
+};
 
 const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
 const MAX_LINE_LEN: usize = 1024;
@@ -1903,7 +1905,8 @@ impl Editor {
             if let Some(project) = project.as_ref() {
                 if buffer.read(cx).is_singleton() {
                     project_subscriptions.push(cx.observe(project, |_, _, cx| {
-                        cx.emit(Event::TitleChanged);
+                        cx.emit(ItemEvent::UpdateTab);
+                        cx.emit(ItemEvent::UpdateBreadcrumbs);
                     }));
                 }
                 project_subscriptions.push(cx.subscribe(project, |editor, _, event, cx| {
@@ -2361,6 +2364,15 @@ impl Editor {
 
         self.blink_manager.update(cx, BlinkManager::pause_blinking);
         cx.emit(Event::SelectionsChanged { local });
+
+        if self.selections.disjoint_anchors().len() == 1 {
+            cx.emit(SearchEvent::ActiveMatchChanged)
+        }
+
+        if local {
+            cx.emit(ItemEvent::UpdateBreadcrumbs);
+        }
+
         cx.notify();
     }
 
@@ -8760,6 +8772,9 @@ impl Editor {
                     self.update_visible_copilot_suggestion(cx);
                 }
                 cx.emit(Event::BufferEdited);
+                cx.emit(ItemEvent::Edit);
+                cx.emit(ItemEvent::UpdateBreadcrumbs);
+                cx.emit(SearchEvent::MatchesInvalidated);
 
                 if *sigleton_buffer_edited {
                     if let Some(project) = &self.project {
@@ -8806,13 +8821,20 @@ impl Editor {
                 self.refresh_inlay_hints(InlayHintRefreshReason::ExcerptsRemoved(ids.clone()), cx);
                 cx.emit(Event::ExcerptsRemoved { ids: ids.clone() })
             }
-            multi_buffer::Event::Reparsed => cx.emit(Event::Reparsed),
-            multi_buffer::Event::DirtyChanged => cx.emit(Event::DirtyChanged),
-            multi_buffer::Event::Saved => cx.emit(Event::Saved),
-            multi_buffer::Event::FileHandleChanged => cx.emit(Event::TitleChanged),
-            multi_buffer::Event::Reloaded => cx.emit(Event::TitleChanged),
+            multi_buffer::Event::Reparsed => {
+                cx.emit(ItemEvent::UpdateBreadcrumbs);
+            }
+            multi_buffer::Event::DirtyChanged => {
+                cx.emit(ItemEvent::UpdateTab);
+            }
+            multi_buffer::Event::Saved
+            | multi_buffer::Event::FileHandleChanged
+            | multi_buffer::Event::Reloaded => {
+                cx.emit(ItemEvent::UpdateTab);
+                cx.emit(ItemEvent::UpdateBreadcrumbs);
+            }
             multi_buffer::Event::DiffBaseChanged => cx.emit(Event::DiffBaseChanged),
-            multi_buffer::Event::Closed => cx.emit(Event::Closed),
+            multi_buffer::Event::Closed => cx.emit(ItemEvent::CloseItem),
             multi_buffer::Event::DiagnosticsUpdated => {
                 self.refresh_active_diagnostics(cx);
             }
@@ -9378,12 +9400,8 @@ pub enum Event {
     },
     BufferEdited,
     Edited,
-    Reparsed,
     Focused,
     Blurred,
-    DirtyChanged,
-    Saved,
-    TitleChanged,
     DiffBaseChanged,
     SelectionsChanged {
         local: bool,
@@ -9392,7 +9410,6 @@ pub enum Event {
         local: bool,
         autoscroll: bool,
     },
-    Closed,
 }
 
 pub struct EditorFocused(pub View<Editor>);

crates/editor2/src/items.rs 🔗

@@ -7,9 +7,9 @@ use anyhow::{anyhow, Context, Result};
 use collections::HashSet;
 use futures::future::try_join_all;
 use gpui::{
-    div, point, AnyElement, AppContext, AsyncAppContext, Entity, EntityId, FocusHandle, Model,
-    ParentElement, Pixels, SharedString, Styled, Subscription, Task, View, ViewContext,
-    VisualContext, WeakView,
+    div, point, AnyElement, AppContext, AsyncAppContext, Entity, EntityId, EventEmitter,
+    FocusHandle, Model, ParentElement, Pixels, SharedString, Styled, Subscription, Task, View,
+    ViewContext, VisualContext, WeakView,
 };
 use language::{
     proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point,
@@ -29,7 +29,7 @@ use std::{
 use text::Selection;
 use theme::{ActiveTheme, Theme};
 use util::{paths::PathExt, ResultExt, TryFutureExt};
-use workspace::item::{BreadcrumbText, FollowableItemHandle};
+use workspace::item::{BreadcrumbText, FollowEvent, FollowableEvents, FollowableItemHandle};
 use workspace::{
     item::{FollowableItem, Item, ItemEvent, ItemHandle, ProjectItem},
     searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle},
@@ -38,7 +38,26 @@ use workspace::{
 
 pub const MAX_TAB_TITLE_LEN: usize = 24;
 
+impl FollowableEvents for Event {
+    fn to_follow_event(&self) -> Option<workspace::item::FollowEvent> {
+        match self {
+            Event::Edited => Some(FollowEvent::Unfollow),
+            Event::SelectionsChanged { local } | Event::ScrollPositionChanged { local, .. } => {
+                if *local {
+                    Some(FollowEvent::Unfollow)
+                } else {
+                    None
+                }
+            }
+            _ => None,
+        }
+    }
+}
+
+impl EventEmitter<ItemEvent> for Editor {}
+
 impl FollowableItem for Editor {
+    type FollowableEvent = Event;
     fn remote_id(&self) -> Option<ViewId> {
         self.remote_id
     }
@@ -217,7 +236,7 @@ impl FollowableItem for Editor {
 
     fn add_event_to_update_proto(
         &self,
-        event: &Self::Event,
+        event: &Self::FollowableEvent,
         update: &mut Option<proto::update_view::Variant>,
         cx: &AppContext,
     ) -> bool {
@@ -292,15 +311,6 @@ impl FollowableItem for Editor {
         })
     }
 
-    fn should_unfollow_on_event(event: &Self::Event, _: &AppContext) -> bool {
-        match event {
-            Event::Edited => true,
-            Event::SelectionsChanged { local } => *local,
-            Event::ScrollPositionChanged { local, .. } => *local,
-            _ => false,
-        }
-    }
-
     fn is_project_item(&self, _cx: &AppContext) -> bool {
         true
     }
@@ -739,32 +749,6 @@ impl Item for Editor {
         })
     }
 
-    fn to_item_events(event: &Self::Event) -> SmallVec<[ItemEvent; 2]> {
-        let mut result = SmallVec::new();
-        match event {
-            Event::Closed => result.push(ItemEvent::CloseItem),
-            Event::Saved | Event::TitleChanged => {
-                result.push(ItemEvent::UpdateTab);
-                result.push(ItemEvent::UpdateBreadcrumbs);
-            }
-            Event::Reparsed => {
-                result.push(ItemEvent::UpdateBreadcrumbs);
-            }
-            Event::SelectionsChanged { local } if *local => {
-                result.push(ItemEvent::UpdateBreadcrumbs);
-            }
-            Event::DirtyChanged => {
-                result.push(ItemEvent::UpdateTab);
-            }
-            Event::BufferEdited => {
-                result.push(ItemEvent::Edit);
-                result.push(ItemEvent::UpdateBreadcrumbs);
-            }
-            _ => {}
-        }
-        result
-    }
-
     fn as_searchable(&self, handle: &View<Self>) -> Option<Box<dyn SearchableItemHandle>> {
         Some(Box::new(handle.clone()))
     }
@@ -913,28 +897,12 @@ impl ProjectItem for Editor {
     }
 }
 
+impl EventEmitter<SearchEvent> for Editor {}
+
 pub(crate) enum BufferSearchHighlights {}
 impl SearchableItem for Editor {
     type Match = Range<Anchor>;
 
-    fn to_search_event(
-        &mut self,
-        event: &Self::Event,
-        _: &mut ViewContext<Self>,
-    ) -> Option<SearchEvent> {
-        match event {
-            Event::BufferEdited => Some(SearchEvent::MatchesInvalidated),
-            Event::SelectionsChanged { .. } => {
-                if self.selections.disjoint_anchors().len() == 1 {
-                    Some(SearchEvent::ActiveMatchChanged)
-                } else {
-                    None
-                }
-            }
-            _ => None,
-        }
-    }
-
     fn clear_matches(&mut self, cx: &mut ViewContext<Self>) {
         todo!()
         // self.clear_background_highlights::<BufferSearchHighlights>(cx);