Add terminal::Toggle (#37585)

Conrad Irwin and Brandan created

Co-Authored-By: Brandan <b5@n0.computer>

Release Notes:

- Added a new action `terminal::Toggle` that is by default bound to
'ctrl-\`'. This copies the default behaviour from VSCode and Jetbrains
where the terminal opens and closes correctly. If you'd like the old
behaviour you can rebind 'ctrl-\`' to `terminal::ToggleFocus`

Co-authored-by: Brandan <b5@n0.computer>

Change summary

assets/keymaps/default-linux.json          |  2 +-
assets/keymaps/default-macos.json          |  2 +-
assets/keymaps/default-windows.json        |  2 +-
assets/keymaps/linux/jetbrains.json        |  2 +-
assets/keymaps/macos/jetbrains.json        |  2 +-
crates/terminal_view/src/terminal_panel.rs |  9 +++++++++
crates/vim/src/command.rs                  |  4 ++--
crates/workspace/src/workspace.rs          | 10 ++++++++++
8 files changed, 26 insertions(+), 7 deletions(-)

Detailed changes

assets/keymaps/default-linux.json 🔗

@@ -583,7 +583,7 @@
       "ctrl-n": "workspace::NewFile",
       "shift-new": "workspace::NewWindow",
       "ctrl-shift-n": "workspace::NewWindow",
-      "ctrl-`": "terminal_panel::ToggleFocus",
+      "ctrl-`": "terminal_panel::Toggle",
       "f10": ["app_menu::OpenApplicationMenu", "Zed"],
       "alt-1": ["workspace::ActivatePane", 0],
       "alt-2": ["workspace::ActivatePane", 1],

assets/keymaps/default-macos.json 🔗

@@ -649,7 +649,7 @@
       "alt-shift-enter": "toast::RunAction",
       "cmd-shift-s": "workspace::SaveAs",
       "cmd-shift-n": "workspace::NewWindow",
-      "ctrl-`": "terminal_panel::ToggleFocus",
+      "ctrl-`": "terminal_panel::Toggle",
       "cmd-1": ["workspace::ActivatePane", 0],
       "cmd-2": ["workspace::ActivatePane", 1],
       "cmd-3": ["workspace::ActivatePane", 2],

assets/keymaps/default-windows.json 🔗

@@ -599,7 +599,7 @@
       "ctrl-n": "workspace::NewFile",
       "shift-new": "workspace::NewWindow",
       "ctrl-shift-n": "workspace::NewWindow",
-      "ctrl-`": "terminal_panel::ToggleFocus",
+      "ctrl-`": "terminal_panel::Toggle",
       "f10": ["app_menu::OpenApplicationMenu", "Zed"],
       "alt-1": ["workspace::ActivatePane", 0],
       "alt-2": ["workspace::ActivatePane", 1],

assets/keymaps/linux/jetbrains.json 🔗

@@ -125,7 +125,7 @@
   {
     "context": "Workspace || Editor",
     "bindings": {
-      "alt-f12": "terminal_panel::ToggleFocus",
+      "alt-f12": "terminal_panel::Toggle",
       "ctrl-shift-k": "git::Push"
     }
   },

assets/keymaps/macos/jetbrains.json 🔗

@@ -127,7 +127,7 @@
   {
     "context": "Workspace || Editor",
     "bindings": {
-      "alt-f12": "terminal_panel::ToggleFocus",
+      "alt-f12": "terminal_panel::Toggle",
       "cmd-shift-k": "git::Push"
     }
   },

crates/terminal_view/src/terminal_panel.rs 🔗

@@ -49,6 +49,8 @@ const TERMINAL_PANEL_KEY: &str = "TerminalPanel";
 actions!(
     terminal_panel,
     [
+        /// Toggles the terminal panel.
+        Toggle,
         /// Toggles focus on the terminal panel.
         ToggleFocus
     ]
@@ -64,6 +66,13 @@ pub fn init(cx: &mut App) {
                     workspace.toggle_panel_focus::<TerminalPanel>(window, cx);
                 }
             });
+            workspace.register_action(|workspace, _: &Toggle, window, cx| {
+                if is_enabled_in_workspace(workspace, cx) {
+                    if !workspace.toggle_panel_focus::<TerminalPanel>(window, cx) {
+                        workspace.close_panel::<TerminalPanel>(window, cx);
+                    }
+                }
+            });
         },
     )
     .detach();

crates/vim/src/command.rs 🔗

@@ -1265,8 +1265,8 @@ fn generate_commands(_: &App) -> Vec<VimCommand> {
         VimCommand::str(("L", "explore"), "project_panel::ToggleFocus"),
         VimCommand::str(("S", "explore"), "project_panel::ToggleFocus"),
         VimCommand::str(("Ve", "xplore"), "project_panel::ToggleFocus"),
-        VimCommand::str(("te", "rm"), "terminal_panel::ToggleFocus"),
-        VimCommand::str(("T", "erm"), "terminal_panel::ToggleFocus"),
+        VimCommand::str(("te", "rm"), "terminal_panel::Toggle"),
+        VimCommand::str(("T", "erm"), "terminal_panel::Toggle"),
         VimCommand::str(("C", "ollab"), "collab_panel::ToggleFocus"),
         VimCommand::str(("Ch", "at"), "chat_panel::ToggleFocus"),
         VimCommand::str(("No", "tifications"), "notification_panel::ToggleFocus"),

crates/workspace/src/workspace.rs 🔗

@@ -3093,6 +3093,16 @@ impl Workspace {
         }
     }
 
+    pub fn close_panel<T: Panel>(&self, window: &mut Window, cx: &mut Context<Self>) {
+        for dock in self.all_docks().iter() {
+            dock.update(cx, |dock, cx| {
+                if dock.panel::<T>().is_some() {
+                    dock.set_open(false, window, cx)
+                }
+            })
+        }
+    }
+
     pub fn panel<T: Panel>(&self, cx: &App) -> Option<Entity<T>> {
         self.all_docks()
             .iter()