summaryrefslogtreecommitdiff
path: root/src/ninep
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 04:48:12 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit009e4ab8779bc7adc7b626814d36e62231d7a0ea (patch)
treed77c04f04b1d11c62aebb4985bce36208e17075c /src/ninep
parentbda5b5f621d0edd8e26f9700043ab21cae18f329 (diff)
downloadpardes-009e4ab8779bc7adc7b626814d36e62231d7a0ea.tar.gz
pardes-009e4ab8779bc7adc7b626814d36e62231d7a0ea.zip
A chorded exec an event reader holds is told its argument, and runs with it
With event open, a 2-1 chord's exec went out as one record with flag 8 and nothing after it: the argument was freed unsaid. As acme does (exec.c:150-190), two records follow it, the argument's text and where it came from (file:#q0,#q1, empty when not known), and the pane keeps the argument, so the record written back runs with it (acme's own write-back, xfid.c:842, passes none; the reader was told, so it runs as the click would have). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep')
-rw-r--r--src/ninep/events.zig23
-rw-r--r--src/ninep/pane.zig5
2 files changed, 27 insertions, 1 deletions
diff --git a/src/ninep/events.zig b/src/ninep/events.zig
index a12cf86d..d75c399b 100644
--- a/src/ninep/events.zig
+++ b/src/ninep/events.zig
@@ -508,6 +508,16 @@ pub fn noteAction(
return true;
}
+/// A record that follows another with no place of its own, `<c>0 0 0 <n>
+/// <text>`: a chorded exec's argument and its location (acme exec.c:182).
+pub fn noteFollow(p: *Pardes, id: usize, action: Action, text: []const u8) void {
+ const pane = p.panes[id] orelse return;
+ if (pane.fs.readers == 0) return;
+ var buf: [max_record_text + 64]u8 = undefined;
+ pane.fs.events.push(p.gpa, formatRecord(&buf, p.fs.origin, action, 0, 0, 0, text));
+ p.fs.news = true;
+}
+
pub fn notePtyOutput(p: *Pardes, id: usize, bytes: []const u8) void {
if (id >= MAX_PANES or bytes.len == 0) return;
const pf = &(p.panes[id] orelse return).fs;
@@ -599,7 +609,18 @@ pub fn writeEvent(p: *Pardes, req: Req, id: usize) Reply {
// been (acme's xfideventwrite, xfid.c:842-844): a REPL bound for
// it takes it. One that came from a write to exec (`F`) was
// never a click, and runs as the command it was.
- .body_exec => _ = exec.executeFrom(p, live, text, r.origin != 'F'),
+ // The chorded exec a reader was told of runs with its argument
+ // (mouse.reportGesture), when it is that range written back.
+ .body_exec => {
+ const pf = &pane.fs;
+ const arg = if (pf.chord_arg) |a| (if (pf.chord_at.q0 == r.q0 and pf.chord_at.q1 == r.q1) a else null) else null;
+ _ = exec.executeFrom(p, live, exec.withArg(p, text, arg), r.origin != 'F');
+ if (arg != null) if (p.paneBySerial(serial)) |still| {
+ const spf = &p.panes[still].?.fs;
+ if (spf.chord_arg) |a| p.gpa.free(a);
+ spf.chord_arg = null;
+ };
+ },
.tag_exec => _ = exec.execute(p, live, text),
.body_look, .tag_look => look.lookAt(p, live, text),
else => unreachable,
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index 791cb797..8cac55d6 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -77,10 +77,15 @@ pub const State = struct {
/// Installed during this update; /log hears about it once the update ends
/// and the pane has its file, name and place.
unannounced: bool = false,
+ /// A chorded exec's argument an event reader was told of (flag 8), kept
+ /// for the record's write-back at `chord_at`, which runs with it.
+ chord_arg: ?[]u8 = null,
+ chord_at: Range = .{},
pub const Range = struct { q0: u32 = 0, q1: u32 = 0 };
pub fn deinit(pf: *State, gpa: std.mem.Allocator) void {
+ if (pf.chord_arg) |a| gpa.free(a);
pf.events.deinit(gpa);
pf.pty_out.deinit(gpa);
pf.tag_snap.deinit(gpa);