summaryrefslogtreecommitdiff
path: root/src/exec.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 03:35:43 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitd067c77813f9ce9fcc64b33e6b0284510ac02185 (patch)
treeeb530db7320603af748aa7535c93090a36b78134 /src/exec.zig
parent3e941015ebd2da88a296479f407e9bbf06287234 (diff)
downloadpardes-d067c77813f9ce9fcc64b33e6b0284510ac02185.tar.gz
pardes-d067c77813f9ce9fcc64b33e6b0284510ac02185.zip
A REPL paste's Enter waits on the clock, not on stale core time
sendToRepl timed the Enter's fallback from stepped_ns, which in an idle detached session is as old as the last frame: the wait was over before it began and the \r went out with the paste, which 3.13's REPL then reads as part of it (4 of 5 sends lost their Enter). The wait now starts from the host's clock and is checked against now_ns; the REPL's echo of the paste still sends it sooner, and the wake is scheduled for the deadline. fs.py sends five times after two idle seconds each in a real pty. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/exec.zig')
-rw-r--r--src/exec.zig9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/exec.zig b/src/exec.zig
index 484b85d7..963c8763 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -450,7 +450,7 @@ const repl_enter_wait_ns: u64 = 250 * std.time.ns_per_ms;
pub fn flushReplEnter(p: *Pardes, id: usize, answered: bool) void {
const pane = p.panes[id] orelse return;
if (pane.repl_enter == 0) return;
- if (!answered and p.stepped_ns < pane.repl_enter_due_ns) return;
+ if (!answered and p.now_ns < pane.repl_enter_due_ns) return;
for (0..pane.repl_enter) |_| p.emitWrite(id, "\r");
pane.repl_enter = 0;
}
@@ -499,7 +499,12 @@ pub fn sendToRepl(p: *Pardes, from: usize, to: usize, text: []const u8) void {
// It goes once the REPL has answered the paste (its next output),
// or after a moment if nothing comes.
dst.repl_enter = enters;
- dst.repl_enter_due_ns = p.stepped_ns + repl_enter_wait_ns;
+ // From the clock now, not core time: idle (a detached session
+ // nobody watches), `stepped_ns` and `now_ns` are as old as the last
+ // frame, and a wait counted from there would be over already, the
+ // Enter going out with the paste.
+ const now = if (p.host.vtable.now) |clock| clock(p.host.ctx) else p.now_ns;
+ dst.repl_enter_due_ns = now + repl_enter_wait_ns;
} else for (0..enters) |_| p.emitWrite(to, "\r");
// Line by line, a blank line inside a Python block ends the block.
if (!panes.Terminal.bracketedPaste(dst) and !dst.repl_warned and (if (dst.repl) |r| r.lang == python_lang else false) and