summaryrefslogtreecommitdiff
path: root/src/terminal.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 13:48:53 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commit0fb5881520884691c395ef1ce4b9d1d902434bd6 (patch)
tree4ec25459314b0b2f3249380d4c122611098661dd /src/terminal.zig
parent65a4c17767f175ce16cbbce5520a86926d61692d (diff)
downloadpardes-0fb5881520884691c395ef1ce4b9d1d902434bd6.tar.gz
pardes-0fb5881520884691c395ef1ce4b9d1d902434bd6.zip
A run whose output a redraw moved above its start answers cut, never an empty whole
pty/run reads a command's output between its C and D marks. When the end landed at or before the start, it answered `exit 0` with no output, as if nothing was printed. That happens when the shell redraws its prompt over the output, as it can in a window two rows high (winsize 10 2). Now only equal marks mean nothing was printed. An end at the top-left cell or above the start says `cut`, since how much was printed is not known. bash, fish, long lines and 3000-line outputs at winsize 10 2 all came back whole on this build, so the dogfood's loss could not be reproduced directly. The test drives the marks into the inverted case the loss needs. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/terminal.zig')
-rw-r--r--src/terminal.zig9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/terminal.zig b/src/terminal.zig
index 1a3b6a21..4cac6f1d 100644
--- a/src/terminal.zig
+++ b/src/terminal.zig
@@ -1044,9 +1044,14 @@ pub fn commandOutput(pane: *Pane, gpa: std.mem.Allocator, max_rows: usize) !Comm
const screen = state.vt.screens.get(.primary) orelse break :printed false;
if (end.garbage) break :printed false;
var whole = !marks.lost and !start.garbage;
+ // Nothing printed: the whole of it.
+ if (start.eql(end.*)) break :printed whole;
// D is where the next prompt begins: the output ends a cell before.
- const last = end.leftWrap(1) orelse break :printed whole;
- if (start.eql(end.*) or last.before(start.*)) break :printed whole;
+ // An end at the very top, or before the start, is output a redraw
+ // moved (a prompt drawn over it in a window two rows high): how
+ // much is not known, so it is not called whole.
+ const last = end.leftWrap(1) orelse break :printed false;
+ if (last.before(start.*)) break :printed false;
var from = start.*;
if (last.up(max_rows)) |floor| if (from.before(floor)) {
from = floor;