Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 13 additions & 4 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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();
Expand Down
29 changes: 29 additions & 0 deletions src/app_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading