summaryrefslogtreecommitdiff
path: root/src/ninep
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 20:57:49 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commit6a815117d242688c947a1788e4ffda9ff2bce959 (patch)
tree311853ee7195e7b1cbd32cf130ec0f3458f72b2c /src/ninep
parentc2a1b54651be6b2532d48825d913b747a0edbea8 (diff)
downloadpardes-6a815117d242688c947a1788e4ffda9ff2bce959.tar.gz
pardes-6a815117d242688c947a1788e4ffda9ff2bce959.zip
A shell command from the workspace's or a column's tag runs as a command pane in the session's directory, never typed into the terminal with the keyboard
A command clicked in a header tag, or written to /tagexec or a column's exec, was typed into the active terminal when it sat at an empty prompt, so it ran in that pane's directory and left no run or exit record. It now always gets a command pane of its own in the session's directory, as acme's row and column tags have no directory but the session's. tags.md writes the rule down: pane words act on the column's active pane, a column's words on the column, shell commands as their own panes, and over 9P a pane's word is refused. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep')
-rw-r--r--src/ninep/cols.zig21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/ninep/cols.zig b/src/ninep/cols.zig
index 7afcfbd8..6828612c 100644
--- a/src/ninep/cols.zig
+++ b/src/ninep/cols.zig
@@ -426,6 +426,27 @@ test "Help and Find at /tagexec act in the session's directory, not the keyboard
}
}
+test "a shell command at /tagexec or a column's exec is a command pane in the session's directory, never typed into the keyboard's terminal" {
+ if (comptime !pardes.hosted) return;
+ const p = try Pardes.init(testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 30 });
+ defer p.deinit();
+ while (p.nextEffect()) |_| {}
+ const term = p.panes[p.active].?;
+ try testing.expect(pardes.exec.takesCommandLine(p, p.active));
+ const col_exec = tree.Node.ofCol(layout.columnSerial(p, 0), .exec);
+ for ([_]u64{ @intFromEnum(tree.TopFile.tagexec), col_exec }) |node| {
+ p.active = p.paneBySerial(term.serial).?;
+ const before = p.next_serial;
+ const r = th.wr(p, node, "echo from-the-tag\n");
+ try testing.expectEqual(tree.Status.ok, r.reply.status);
+ try testing.expectEqualStrings("", r.pty());
+ try testing.expectEqual(before + 1, p.next_serial);
+ const made = p.panes[p.paneBySerial(p.next_serial).?].?; // the newest
+ try testing.expectEqualStrings("echo from-the-tag", made.command.?);
+ try testing.expectEqualStrings(p.sessionDir(), made.cwdSlice());
+ }
+}
+
test "New and Tty run at /tagexec and a column's exec, with no pane at all too" {
const p = try th.withFile(testing.allocator, "x\n");
defer p.deinit();