diff --git a/docs/commands.md b/docs/commands.md index 2a529cf..b4481d3 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -139,7 +139,7 @@ Press `m` to toggle the "in use" tag, marked `◆`. In state mode, tagged tasks Press `M` to select the next tagged task in dashboard order, wrapping after the last. With no tagged tasks, the selection is unchanged; with one, that task is selected. -In custom mode only, a new command is assigned the selected task's group, through both `n` and the `@` picker. The destination is shown in the spawn prompt as `❯ dir ▸ group ▸ command`, each segment present only when it applies: the dir segment for a non-default directory, the group segment when a group will be inherited. New tasks are unassigned in state and dir modes. +In custom mode only, a new command is assigned the selected task's group, through both `n` and the `@` picker. The destination is shown in the spawn prompt as `❯ dir ▸ group ▸ command`, each segment present only when it applies: the dir segment for a non-default directory, the group segment when a group will be inherited. New tasks are unassigned in state and dir modes. In dir mode, `n` instead opens in the selected task's directory; the `@` picker is unaffected. #### The flagship diff --git a/src/app.rs b/src/app.rs index efe260d..a9692c7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -226,9 +226,9 @@ pub struct App { pub mode: Mode, pub group_mode: GroupMode, pub input: EditBuffer, - /// Directory a typed command or a picked agent launches in. Set to - /// `invocation_dir` for the `n` flow, or to the picked directory for the - /// `@` flow. + /// Directory a typed command or a picked agent launches in. Set to the + /// selected task's directory for the `n` flow in Dir mode, `invocation_dir` + /// for the `n` flow otherwise, or the picked directory for the `@` flow. pub spawn_cwd: PathBuf, /// Group assigned to the next spawn. Custom mode snapshots the selected /// task's group; State and Dir modes leave the spawn unassigned. @@ -1110,6 +1110,15 @@ impl App { self.refresh_dir_candidates(); } + /// Resolve the `n` spawn directory: the selected task's cwd in Dir mode, else + /// `invocation_dir`. + fn inherited_dir(&self) -> PathBuf { + match (self.group_mode, self.selected_task()) { + (GroupMode::Dir, Some(i)) => self.views[i].cwd.clone(), + _ => self.invocation_dir.clone(), + } + } + // --- `g` group picker ------------------------------------------------------- /// Resolve spawn inheritance from the selected task in Custom mode. @@ -1328,7 +1337,7 @@ impl App { KeyCode::Char('/') => self.open_find_palette(), // Uppercase R renames; lowercase r reruns. KeyCode::Char('R') => self.open_rename_prompt(), - KeyCode::Char('n') => self.open_spawn_prompt(self.invocation_dir.clone()), + KeyCode::Char('n') => self.open_spawn_prompt(self.inherited_dir()), KeyCode::Char('@') => { self.dir_input.clear(); self.refresh_dir_candidates(); diff --git a/src/app_tests.rs b/src/app_tests.rs index 6ebf8e0..bfd2714 100644 --- a/src/app_tests.rs +++ b/src/app_tests.rs @@ -2948,6 +2948,35 @@ fn state_and_dir_mode_spawns_stay_unassigned() { assert_eq!(v.group, None); } +/// In Dir mode, `n` opens in the selected task's directory; State and Custom modes keep +/// the invocation directory. +#[test] +fn dir_mode_spawn_inherits_the_selected_directory() { + let mut app = App::new_local(30, 100); + let scratch = temp("app_dir_inherit"); + let (dir, inv) = (scratch.to_path_buf(), app.invocation_dir.clone()); + app.spawn_in("sleep 5", dir.clone()); // id 1 + + for (mode, want) in [ + (GroupMode::Dir, &dir), + (GroupMode::State, &inv), + (GroupMode::Custom, &inv), + ] { + app.group_mode = mode; + app.on_key_dashboard(key(KeyCode::Char('n'))); + assert_eq!(&app.spawn_cwd, want, "{mode:?}"); + app.on_key_spawn(key(KeyCode::Esc)); + } + + app.group_mode = GroupMode::Dir; + app.on_key_dashboard(key(KeyCode::Char('n'))); + app.type_spawn("sleep 5"); + app.on_key_spawn(key(KeyCode::Enter)); + app.pump(); + let v = app.views.iter().find(|v| v.id == 2).unwrap(); + assert_eq!(v.cwd, dir, "the spawn must launch in the inherited directory"); +} + // --- `n` spawn prompt: Agent page -------------------------------------- impl App {