From 062523f4684e81715dec844bb1983b7bde7df5fc Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 16:08:36 -0300 Subject: Whether an exec came from a body travels with it, so every selection goes to the REPL The execute key and the middle click marked a global flag that the first execute cleared, so of several selections executed at once only the first reached a bound REPL and the rest ran as commands. Where an exec came from now goes with it, as acme's execute() asks of its Text (exec.c:122,169): builtins.Ctx carries from_body, runBuiltinFrom and executeFrom take it, the gestures set it, and chordEachSel sets it for each selection. Co-Authored-By: Claude Opus 5.5 --- src/exec.zig | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'src/exec.zig') diff --git a/src/exec.zig b/src/exec.zig index 57eaad8f..dfef2dfd 100644 --- a/src/exec.zig +++ b/src/exec.zig @@ -69,7 +69,8 @@ pub fn chordEachSel(p: *Pardes, pane: *Pane, cmd: Builtin) bool { var primary_active: ?usize = null; for (texts[0..made], 0..) |txt, i| { - runBuiltin(p, cmd, id, "", txt); + // Every selection is the body's, each one sent as the first is. + runBuiltinFrom(p, cmd, id, "", txt, true); if (i == got.pri) primary_active = p.active; const still = p.panes[id] orelse break; if (still.serial != serial) break; @@ -498,12 +499,15 @@ const max_exec_depth = 8; /// child is `$SHELL -c` the line, which shows its output and `exit N` when /// done, and which Kill signals. Answers the pane it went to. pub fn execute(p: *Pardes, id: usize, txt: []const u8) ?usize { + return executeFrom(p, id, txt, false); +} + +/// `execute` for text a gesture took from `id`'s body when `from_body`: +/// such text may be a bound REPL's. Run by name (`Exec ...`, whose line +/// comes back through `execute`) or written as a command word, never. +pub fn executeFrom(p: *Pardes, id: usize, txt: []const u8, from_body: bool) ?usize { const pane = p.panes[id] orelse return null; - // Made by a gesture on a body, it may be a bound REPL's; run by name - // (`Exec ...`, which runs through here again) or written in a command - // word, it never is. - const gesture = p.exec_from_body and config.commandWord(std.mem.trim(u8, txt, " \t\r\n")) == null; - p.exec_from_body = false; + const gesture = from_body and config.commandWord(std.mem.trim(u8, txt, " \t\r\n")) == null; const cmd = commandText(txt); if (cmd.len == 0) return null; if (p.exec_depth == 0) p.noteHaptic(.exec); @@ -663,6 +667,11 @@ pub fn applyStartupConfig(p: *Pardes) void { } pub fn runBuiltin(p: *Pardes, b: Builtin, id: usize, txt: []const u8, arg: ?[]const u8) void { + runBuiltinFrom(p, b, id, txt, arg, false); +} + +/// `runBuiltin` saying whether a gesture on the pane's body made it. +pub fn runBuiltinFrom(p: *Pardes, b: Builtin, id: usize, txt: []const u8, arg: ?[]const u8, from_body: bool) void { if (!normal.multiOnce(p)) return; // a builtin is per-keystroke, never per-cursor const pane = p.panes[id] orelse return; // A builtin says its own name before it runs, so a tagline click is @@ -672,7 +681,7 @@ pub fn runBuiltin(p: *Pardes, b: Builtin, id: usize, txt: []const u8, arg: ?[]co p.setMessage(id, @tagName(b)); pane.msg_announcement = true; } - const c: builtins.Ctx = .{ .p = p, .pane = pane, .id = id, .txt = txt, .arg = arg }; + const c: builtins.Ctx = .{ .p = p, .pane = pane, .id = id, .txt = txt, .arg = arg, .from_body = from_body }; builtins.registry.dispatch(b, c); } -- cgit v1.3