Repository: zellij-org/zellij (language: rust)

Issue:
FR: Retain cwd when drop to shell
When a session is restored after machine shutdown, all panes with a running command (e.g. nvim) would become a command pane where the user is prompted to run again, drop to shell or exit. Is it possible to configure so that the "drop to shell" option would retain the cwd of the pending command instead of the default $HOME folder?


Discussion / hints:

Fix patch:
diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs
index 613a9619aa..78f2697ef2 100644
--- a/zellij-server/src/panes/terminal_pane.rs
+++ b/zellij-server/src/panes/terminal_pane.rs
@@ -196,11 +196,13 @@ impl Pane for TerminalPane {
                     Some(AdjustedInput::ReRunCommandInThisPane(run_command))
                 },
                 ESC => {
+                    // Drop to shell in the same working directory as the command was run
+                    let working_dir = run_command.cwd.clone();
                     self.is_held = None;
                     self.grid.reset_terminal_state();
                     self.set_should_render(true);
                     self.remove_banner();
-                    Some(AdjustedInput::DropToShellInThisPane)
+                    Some(AdjustedInput::DropToShellInThisPane { working_dir })
                 },
                 CTRL_C => Some(AdjustedInput::CloseThisPane),
                 _ => None,
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index 77b7319ac9..43cabba064 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -67,7 +67,11 @@ pub enum PtyInstruction {
     ClosePane(PaneId),
     CloseTab(Vec<PaneId>),
     ReRunCommandInPane(PaneId, RunCommand),
-    DropToShellInPane(PaneId, Option<PathBuf>), // Option<PathBuf> - default shell
+    DropToShellInPane {
+        pane_id: PaneId,
+        shell: Option<PathBuf>,
+        working_dir: Option<PathBuf>,
+    },
     SpawnInPlaceTerminal(
         Option<TerminalAction>,
         Option<String>,
@@ -101,7 +105,7 @@ impl From<&PtyInstruction> for PtyContext {
             PtyInstruction::CloseTab(_) => PtyContext::CloseTab,
             PtyInstruction::NewTab(..) => PtyContext::NewTab,
             PtyInstruction::ReRunCommandInPane(..) => PtyContext::ReRunCommandInPane,
-            PtyInstruction::DropToShellInPane(..) => PtyContext::DropToShellInPane,
+            PtyInstruction::DropToShellInPane { .. } => PtyContext::DropToShellInPane,
             PtyInstruction::SpawnInPlaceTerminal(..) => PtyContext::SpawnInPlaceTerminal,
             PtyInstruction::DumpLayout(..) => PtyContext::DumpLayout,
             PtyInstruction::LogLayoutToHd(..) => PtyContext::LogLayoutToHd,
@@ -546,17 +550,21 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
                     },
                 }
             },
-            PtyInstruction::DropToShellInPane(pane_id, default_shell) => {
+            PtyInstruction::DropToShellInPane {
+                pane_id,
+                shell,
+                working_dir,
+            } => {
                 let err_context = || format!("failed to rerun command in pane {:?}", pane_id);
 
                 // TODO: get configured default_shell from screen/tab as an option and default to
                 // this otherwise (also look for a place that turns get_default_shell into a
                 // RunCommand, we might have done this before)
                 let run_command = RunCommand {
-                    command: default_shell.unwrap_or_else(|| get_default_shell()),
+                    command: shell.unwrap_or_else(|| get_default_shell()),
                     hold_on_close: false,
                     hold_on_start: false,
-                    // TODO: cwd
+                    cwd: working_dir,
                     ..Default::default()
                 };
                 match pty
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index d1a940c791..b48a6e43bb 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -485,7 +485,7 @@ pub enum AdjustedInput {
     ReRunCommandInThisPane(RunCommand),
     PermissionRequestResult(Vec<PermissionType>, PermissionStatus),
     CloseThisPane,
-    DropToShellInThisPane,
+    DropToShellInThisPane { working_dir: Option<PathBuf> },
 }
 pub fn get_next_terminal_position(
     tiled_panes: &TiledPanes,
@@ -1723,13 +1723,14 @@ impl Tab {
                         self.close_pane(PaneId::Terminal(active_terminal_id), false, None);
                         should_update_ui = true;
                     },
-                    Some(AdjustedInput::DropToShellInThisPane) => {
+                    Some(AdjustedInput::DropToShellInThisPane { working_dir }) => {
                         self.pids_waiting_resize.insert(active_terminal_id);
                         self.senders
-                            .send_to_pty(PtyInstruction::DropToShellInPane(
-                                PaneId::Terminal(active_terminal_id),
-                                self.default_shell.clone(),
-                            ))
+                            .send_to_pty(PtyInstruction::DropToShellInPane {
+                                pane_id: PaneId::Terminal(active_terminal_id),
+                                shell: self.default_shell.clone(),
+                                working_dir,
+                            })
                             .with_context(err_context)?;
                         should_update_ui = true;
                     },


Test patch: