summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exec.zig9
-rw-r--r--src/pardes.zig12
-rw-r--r--test/fs.py8
3 files changed, 23 insertions, 6 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
diff --git a/src/pardes.zig b/src/pardes.zig
index dab27160..9297c829 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -1655,10 +1655,13 @@ test "a REPL bound for a language takes the exec made on a body in it; tags, Exe
try std.testing.expectEqualStrings("\r", Sent.said(1));
// Nothing answering, it goes when its wait is up.
_ = exec.executeFrom(p, 0, "print(2)", true);
- p.stepped_ns += 300 * std.time.ns_per_ms;
+ p.update(.tick); // on the clock: not yet, however old core time is
+ Sent.drain(p);
+ try std.testing.expect(std.mem.endsWith(u8, Sent.said(1), "\x1b[200~print(2)\x1b[201~"));
+ p.now_ns = p.panes[1].?.repl_enter_due_ns; // the clock reaches its wait
p.update(.tick);
Sent.drain(p);
- try std.testing.expect(std.mem.endsWith(u8, Sent.said(1), "\x1b[200~print(2)\x1b[201~\r"));
+ try std.testing.expectEqualStrings("\r", Sent.said(1));
p.update(.{ .output = .{ .pane = 1, .bytes = "\x1b[?2004l" } });
Sent.len[1] = 0;
// A block left open by its indented last line gets the blank line that
@@ -6571,9 +6574,10 @@ pub const Pardes = struct {
const wait = Messages.messageWake(p, pane) orelse continue;
frames = if (frames) |soonest| @min(soonest, wait) else wait;
};
- // A paste's Enter waiting on its REPL goes at the end of its wait.
+ // A paste's Enter waiting on its REPL goes at the end of its wait,
+ // a time on the clock: the frames from `stepped_ns` that reach it.
for (p.panes) |slot| if (slot) |pane| if (pane.repl_enter > 0) {
- const wait = @max(1, (pane.repl_enter_due_ns -| p.stepped_ns) / animation.frame_ns);
+ const wait = @max(1, (pane.repl_enter_due_ns -| p.stepped_ns + animation.frame_ns - 1) / animation.frame_ns);
frames = if (frames) |soonest| @min(soonest, wait) else wait;
};
return if (frames) |n| p.stepped_ns + n * animation.frame_ns else null;
diff --git a/test/fs.py b/test/fs.py
index 9336a53a..bac7020c 100644
--- a/test/fs.py
+++ b/test/fs.py
@@ -515,6 +515,14 @@ def python_repl_runs_one_line(binary):
record = b'MX0 0 0 10 print(6*7)\n'
client.rpc(118, struct.pack('<IQI', fid, 0, len(record)) + record)
assert wait_for('\n42'), body()
+ # After the session has sat idle, the Enter still waits for
+ # the paste: core time is as old as the last frame then.
+ for n in range(5):
+ time.sleep(2)
+ line = f'print({1000 + n})'.encode()
+ record = b'MX0 0 0 %d %s\n' % (len(line), line)
+ client.rpc(118, struct.pack('<IQI', fid, 0, len(record)) + record)
+ assert wait_for(f'\n{1000 + n}'), (n, body())
finally:
client.close(fid)