summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exec.zig15
-rw-r--r--src/pardes.zig19
2 files changed, 22 insertions, 12 deletions
diff --git a/src/exec.zig b/src/exec.zig
index 2b3ca40c..104e3b4d 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -522,7 +522,7 @@ const Routed = union(enum) { none, sent: usize, asked };
/// The REPL bound here has no program running to take the text: said,
/// and nothing sent or run.
-fn replGone(p: *Pardes, from: usize, repl: *const Pane) Routed {
+pub fn replGone(p: *Pardes, from: usize, repl: *const Pane) Routed {
var idbuf: [48]u8 = undefined;
var said: [128]u8 = undefined;
p.setMessage(from, std.fmt.bufPrint(&said, "Repl: {s} has no program running; nothing sent", .{replId(&idbuf, repl)}) catch "Repl: no program running");
@@ -539,23 +539,22 @@ fn routeToRepl(p: *Pardes, from: usize, text: []const u8) Routed {
return .{ .sent = from };
}
const lang = langOf(src) orelse return .none;
+ // Every REPL bound for the language, a program running in it or not:
+ // which one is the text's is never guessed from which happens to be
+ // running now.
var bound: [26]usize = undefined;
var n: usize = 0;
- var gone: ?usize = null;
for (p.panes, 0..) |slot, i| if (slot) |pane| if (pane.repl) |r| if (r.lang == lang and n < bound.len) {
- if (!replLive(p, i)) {
- gone = i;
- continue;
- }
bound[n] = i;
n += 1;
};
- if (n == 0) return if (gone) |i| replGone(p, from, p.panes[i].?) else .none;
+ if (n == 0) return .none;
if (n == 1) {
+ if (!replLive(p, bound[0])) return replGone(p, from, p.panes[bound[0]].?);
sendToRepl(p, from, bound[0], text);
return .{ .sent = bound[0] };
}
- // Several: asked on the pane's notice band, as Del asks, one key
+ // Several: always asked on the pane's notice band, as Del asks, one key
// answering; nothing is remembered of the answer.
const owned = p.gpa.dupe(u8, text) catch return .none;
if (p.repl_ask) |old| p.gpa.free(old.text);
diff --git a/src/pardes.zig b/src/pardes.zig
index 4472df8f..1e5282da 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -1717,14 +1717,20 @@ test "a REPL bound for a language takes the exec made on a body in it; tags, Exe
try std.testing.expect(p.executeBuiltinLine(2, "Repl python"));
try std.testing.expectEqualStrings("python-b", exec.replId(&idbuf, p.panes[2].?));
- // A REPL whose program has left (Ctrl-D: the shell has the tty) is
- // sent nothing, and nothing runs: it says so.
+ // Two bound always ask, whichever has a program running: one left
+ // (Ctrl-D: the shell has the tty) is still offered, and chosen, it is
+ // sent nothing, nothing runs, and that is said.
host.taken[1] = false;
- host.taken[2] = false;
_ = exec.executeFrom(p, 0, "import os", true);
+ try std.testing.expectEqual(Pane.Prompt.repl_choice, file.prompt);
+ p.update(.{ .key = .{ .cp = 'a' } });
Sent.drain(p);
try std.testing.expect(Sent.len[1] == 0 and Sent.len[2] == 0 and !Sent.spawned);
try std.testing.expect(std.mem.indexOf(u8, file.msg[0..file.msg_len], "no program running") != null);
+ host.taken[2] = false;
+ _ = exec.executeFrom(p, 0, "import os", true);
+ try std.testing.expectEqual(Pane.Prompt.repl_choice, file.prompt);
+ p.update(.{ .key = .{ .cp = Key.escape } });
host.taken[1] = true;
host.taken[2] = true;
@@ -6047,7 +6053,12 @@ pub const Pardes = struct {
// The pane offered, still that REPL and still running: it
// may have closed or been rebound while the question stood.
if (p.paneBySerial(serial)) |to| if (p.panes[to].?.repl) |r|
- if (r.lang == ask.lang and r.letter == letter and exec.replLive(p, to)) {
+ if (r.lang == ask.lang and r.letter == letter) {
+ // Offered with no program running: said so, not sent.
+ if (!exec.replLive(p, to)) {
+ _ = exec.replGone(p, id, p.panes[to].?);
+ return true;
+ }
exec.sendToRepl(p, id, to, ask.text);
return true;
};