summaryrefslogtreecommitdiff
path: root/src/host_io.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 23:26:13 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:18 -0300
commitafe51fc6c3675a6aa8ab2f5caf64796b65597c2c (patch)
tree8257c7e5b12afb7395079ea57cfcc912378a84fd /src/host_io.zig
parent5761f97293960ee7035f7866f09a9826a9e2f74a (diff)
downloadpardes-afe51fc6c3675a6aa8ab2f5caf64796b65597c2c.tar.gz
pardes-afe51fc6c3675a6aa8ab2f5caf64796b65597c2c.zip
A pane's child runs with PAGER=cat and GIT_PAGER=cat where the user's environment sets neither, so a pty/run or a command pane never hangs in a pager
git log or man run through pty/run, or in a command pane, sat in less at its first screen: no one presses q, and the run never answers. The child's environment now names cat as the pager when the inherited one names none; a user's own PAGER or GIT_PAGER is kept. It is every pane child's, a terminal's shell too, since a pty/run's line runs in it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/host_io.zig')
-rw-r--r--src/host_io.zig28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/host_io.zig b/src/host_io.zig
index ebe910aa..1fab3729 100644
--- a/src/host_io.zig
+++ b/src/host_io.zig
@@ -1268,6 +1268,18 @@ pub const ChildEnv = struct {
slots[n] = entry;
n += 1;
}
+ // No pager to wait in: a pty/run or a command pane's output is read
+ // whole, and less would hold it at its first screen for ever. Only
+ // where the inherited environment chose none.
+ for (defaults) |default| {
+ const set = for (libc.environ[0..i]) |entry| {
+ if (std.mem.eql(u8, name(entry.?), name(default))) break true;
+ } else false;
+ if (set) continue;
+ if (n + own.len + 2 > slots.len) return null;
+ slots[n] = default;
+ n += 1;
+ }
for (own) |mine| {
slots[n] = mine;
n += 1;
@@ -1275,6 +1287,9 @@ pub const ChildEnv = struct {
slots[n] = null;
return @ptrCast(slots);
}
+
+ /// Set for a pane's child only when the user's environment has none.
+ const defaults = [_][*:0]const u8{ "PAGER=cat", "GIT_PAGER=cat" };
};
test "the child environment replaces the launcher's terminal identity exactly once" {
@@ -1304,6 +1319,10 @@ test "the child environment replaces the launcher's terminal identity exactly on
var colorterms: usize = 0;
var probes: usize = 0;
var dumb = false;
+ var pagers: usize = 0;
+ var git_pagers: usize = 0;
+ var pager_cat = false;
+ var git_pager_cat = false;
var i: usize = 0;
while (envp[i]) |entry| : (i += 1) {
const line = std.mem.span(entry);
@@ -1311,7 +1330,16 @@ test "the child environment replaces the launcher's terminal identity exactly on
if (std.mem.startsWith(u8, line, "COLORTERM=")) colorterms += 1;
if (std.mem.eql(u8, line, "TERM=dumb")) dumb = true;
if (std.mem.eql(u8, line, "PARDES_CHILD_ENV_PROBE=1")) probes += 1;
+ if (std.mem.startsWith(u8, line, "PAGER=")) pagers += 1;
+ if (std.mem.startsWith(u8, line, "GIT_PAGER=")) git_pagers += 1;
+ if (std.mem.eql(u8, line, "PAGER=cat")) pager_cat = true;
+ if (std.mem.eql(u8, line, "GIT_PAGER=cat")) git_pager_cat = true;
}
+ // A pager only where the user named none: cat, so nothing waits in less.
+ try std.testing.expectEqual(@as(usize, 1), pagers);
+ try std.testing.expectEqual(@as(usize, 1), git_pagers);
+ if (std.c.getenv("PAGER") == null) try std.testing.expect(pager_cat);
+ if (std.c.getenv("GIT_PAGER") == null) try std.testing.expect(git_pager_cat);
try std.testing.expectEqual(@as(usize, 1), terms);
try std.testing.expectEqual(@as(usize, 1), colorterms);
try std.testing.expectEqual(@as(usize, 1), probes);