Allow cursors to be shown via a command (#4153)

Joseph T. Lyons created

Change summary

assets/keymaps/default.json  |  3 ++-
crates/editor/src/actions.rs |  1 +
crates/editor/src/editor.rs  | 34 +++++++++++++++++++++-------------
crates/editor/src/element.rs |  3 ++-
4 files changed, 26 insertions(+), 15 deletions(-)

Detailed changes

assets/keymaps/default.json 🔗

@@ -349,7 +349,8 @@
       "alt-cmd-]": "editor::UnfoldLines",
       "ctrl-space": "editor::ShowCompletions",
       "cmd-.": "editor::ToggleCodeActions",
-      "alt-cmd-r": "editor::RevealInFinder"
+      "alt-cmd-r": "editor::RevealInFinder",
+      "ctrl-cmd-c": "editor::ShowCursors"
     }
   },
   {

crates/editor/src/editor.rs 🔗

@@ -367,7 +367,7 @@ pub struct Editor {
     project: Option<Model<Project>>,
     collaboration_hub: Option<Box<dyn CollaborationHub>>,
     blink_manager: Model<BlinkManager>,
-    recently_focused: bool,
+    display_cursors: bool,
     hovered_cursor: Option<HoveredCursor>,
     pub show_local_selections: bool,
     mode: EditorMode,
@@ -1613,7 +1613,7 @@ impl Editor {
             pixel_position_of_newest_cursor: None,
             gutter_width: Default::default(),
             style: None,
-            recently_focused: false,
+            display_cursors: false,
             hovered_cursor: Default::default(),
             editor_actions: Default::default(),
             show_copilot_suggestions: mode == EditorMode::Full,
@@ -3899,6 +3899,24 @@ impl Editor {
         self.update_visible_copilot_suggestion(cx);
     }
 
+    pub fn show_cursors(&mut self, _: &ShowCursors, cx: &mut ViewContext<Self>) {
+        self.display_cursors(cx);
+    }
+
+    fn display_cursors(&mut self, cx: &mut ViewContext<Self>) {
+        self.display_cursors = true;
+        cx.notify();
+        cx.spawn(|this, mut cx| async move {
+            cx.background_executor().timer(Duration::from_secs(2)).await;
+            this.update(&mut cx, |this, cx| {
+                this.display_cursors = false;
+                cx.notify()
+            })
+            .ok()
+        })
+        .detach();
+    }
+
     fn next_copilot_suggestion(&mut self, _: &copilot::NextSuggestion, cx: &mut ViewContext<Self>) {
         if self.has_active_copilot_suggestion(cx) {
             self.cycle_copilot_suggestions(Direction::Next, cx);
@@ -9003,17 +9021,7 @@ impl Editor {
             cx.focus(&rename_editor_focus_handle);
         } else {
             self.blink_manager.update(cx, BlinkManager::enable);
-            self.recently_focused = true;
-            cx.notify();
-            cx.spawn(|this, mut cx| async move {
-                cx.background_executor().timer(Duration::from_secs(2)).await;
-                this.update(&mut cx, |this, cx| {
-                    this.recently_focused = false;
-                    cx.notify()
-                })
-                .ok()
-            })
-            .detach();
+            self.display_cursors(cx);
             self.buffer.update(cx, |buffer, cx| {
                 buffer.finalize_last_transaction(cx);
                 if self.leader_peer_id.is_none() {

crates/editor/src/element.rs 🔗

@@ -327,6 +327,7 @@ impl EditorElement {
         register_action(view, cx, Editor::context_menu_prev);
         register_action(view, cx, Editor::context_menu_next);
         register_action(view, cx, Editor::context_menu_last);
+        register_action(view, cx, Editor::show_cursors);
     }
 
     fn register_key_listeners(&self, cx: &mut WindowContext) {
@@ -2000,7 +2001,7 @@ impl EditorElement {
                     if Some(selection.peer_id) == editor.leader_peer_id {
                         continue;
                     }
-                    let is_shown = editor.recently_focused || editor.hovered_cursor.as_ref().is_some_and(|c| c.replica_id == selection.replica_id && c.selection_id == selection.selection.id);
+                    let is_shown = editor.display_cursors || editor.hovered_cursor.as_ref().is_some_and(|c| c.replica_id == selection.replica_id && c.selection_id == selection.selection.id);
 
                     remote_selections
                         .entry(selection.replica_id)