summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 15:49:45 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit2868137e34c973a47cbf667a431e885ca23cd9a2 (patch)
tree2756597f564038f22f61d77f00598a6c996fcd05 /src/pardes.zig
parent5570377c4997a5abe9f433bc15c927bcde237dc1 (diff)
downloadpardes-2868137e34c973a47cbf667a431e885ca23cd9a2.tar.gz
pardes-2868137e34c973a47cbf667a431e885ca23cd9a2.zip
Tty with a shell that is not there says so, and never sets the caller's shell
Tty /nonexistent or Tty fsh started the host's fallback shell without a word, and when spawnTty made no pane, the argument became the calling pane's shell. Tty now looks the shell up first and fails 'Tty: no shell "fsh"' when it is neither a name on the usual paths nor a path to one; spawnTty answers the pane it made, the one given the shell, and says why when it made none. The lookup (host_io Shell.find) gives the turn up around its access() calls, since a typed path may be under a mount this editor serves, and forkShell copies the pane's shell before looking it up and checks the pane is still its own after. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 58354b95..429f33b9 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -1193,7 +1193,7 @@ test "first document fallback splits like Tty from the originating pane" {
const free = p.freeSlot().?;
const doc = try p.openTutorView(free);
exec.placeDoc(p, from, free, doc);
- exec.spawnTty(tty, from);
+ _ = exec.spawnTty(tty, from);
p.sync();
tty.sync();
try std.testing.expectEqual(@as(usize, 2), p.ncol);
@@ -1516,11 +1516,22 @@ test "Tty+fish, one word a tag can hold, opens a terminal on that shell" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
defer p.deinit();
while (p.nextEffect()) |_| {}
- try std.testing.expect(p.executeBuiltinLine(0, "Tty+fish"));
+ // sh, the one shell every host has.
+ try std.testing.expect(p.executeBuiltinLine(0, "Tty+sh"));
try std.testing.expect(p.active != 0);
- try std.testing.expectEqualStrings("fish", p.panes[p.active].?.shell.?);
- p.acknowledgeShell(p.active, "/usr/bin/fish", true);
- try std.testing.expect(std.mem.startsWith(u8, tagline.curTail(p.panes[p.active].?), " Tty+fish "));
+ try std.testing.expectEqualStrings("sh", p.panes[p.active].?.shell.?);
+ p.acknowledgeShell(p.active, "/bin/sh", false);
+ try std.testing.expect(std.mem.startsWith(u8, tagline.curTail(p.panes[p.active].?), " Tty+sh "));
+ p.active = 0;
+ // A shell that is not there is said, not quietly replaced, and the
+ // pane that asked gets no shell of its own.
+ const before = p.active;
+ const caller = p.panes[0].?;
+ try std.testing.expect(p.executeBuiltinLine(0, "Tty /nonexistent"));
+ try std.testing.expect(p.active == before and caller.shell == null);
+ try std.testing.expect(std.mem.indexOf(u8, caller.msg[0..caller.msg_len], "no shell \"/nonexistent\"") != null);
+ try std.testing.expect(p.executeBuiltinLine(0, "Tty fsh-not-a-shell"));
+ try std.testing.expect(caller.shell == null);
// Only a word that says so splits at `+`: `Dump+x.zon` is no Dump.
try std.testing.expect(!p.executeBuiltinLine(0, "Dump+x.zon"));
try std.testing.expect(!p.executeBuiltinLine(0, "Msg+hello"));
@@ -7059,7 +7070,7 @@ test "raw tty Escape only leaves at a shell prompt" {
if (platform == .web) return;
const p = try Pardes.init(std.testing.allocator, .{ .cols = 80, .rows = 24, .file = "mise.toml" });
defer p.deinit();
- exec.spawnTty(p, 0);
+ _ = exec.spawnTty(p, 0);
const shell = p.active;
const pane = p.panes[shell].?;
var buf: [256]u8 = undefined;
@@ -7090,7 +7101,7 @@ test "raw tty Ctrl-B switches to editor mode without sending child input" {
if (platform == .web) return;
const p = try Pardes.init(std.testing.allocator, .{ .file = "mise.toml" });
defer p.deinit();
- exec.spawnTty(p, 0);
+ _ = exec.spawnTty(p, 0);
const shell = p.active;
p.sync();
var buf: [256]u8 = undefined;