diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-27 22:46:26 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 71a9f04342493325c10b1b9bc122a88d41143782 (patch) | |
| tree | c9b1f27a84404a8332c4066a56d922a031eec194 /src/Pipe.zig | |
| parent | d126715cd20a39dbc10870318968546f5e371b97 (diff) | |
| download | pardes-71a9f04342493325c10b1b9bc122a88d41143782.tar.gz pardes-71a9f04342493325c10b1b9bc122a88d41143782.zip | |
Give the pipe its own fields in Pipe
Not a pure move: state moves. Pardes's `pipe_seq` and `pipe_wait` become
Pipe.zig's own fields `seq` and `wait`, and Pardes embeds one as
`pipe: Pipe = .{}`. pipeRequest reads only the request in flight, so it now
takes `pipe: *const Pipe` and the four shells call
`core.pipe.pipeRequest(id)` (their Pipe imports go away again); the other
pipe functions still need the panes and keep `p: *Pardes`, writing
`p.pipe.seq/wait`. Field reads in dump.zig, the shells' tests and two test
files follow (`core.pipe_wait` becomes `core.pipe.wait`). No behaviour
change.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/Pipe.zig')
| -rw-r--r-- | src/Pipe.zig | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/Pipe.zig b/src/Pipe.zig index 0fde654a..c01098ff 100644 --- a/src/Pipe.zig +++ b/src/Pipe.zig @@ -11,6 +11,12 @@ const edit = @import("edit.zig"); const Pane = panes.Pane; const Key = pardes.Key; const Pardes = pardes.Pardes; +const Pipe = @This(); + +/// Bumped for every request, so a late answer to an older one is ignored. +seq: u32 = 0, +/// The request in flight, and what it needs to apply its answer. +wait: ?PendingPipe = null, fn nextPipeEffect(p: *Pardes) ?u32 { while (p.nextEffect()) |effect| switch (effect) { @@ -112,10 +118,10 @@ pub fn submitPipe(p: *Pardes, id: usize) void { return; }; - p.pipe_seq +%= 1; - if (p.pipe_wait) |*old| old.deinit(p.gpa); - p.pipe_wait = .{ - .id = p.pipe_seq, + p.pipe.seq +%= 1; + if (p.pipe.wait) |*old| old.deinit(p.gpa); + p.pipe.wait = .{ + .id = p.pipe.seq, .pane = id, .serial = pane.serial, .revision = f.revision, @@ -128,13 +134,13 @@ pub fn submitPipe(p: *Pardes, id: usize) void { .how = prompt.how, .nranges = @intCast(got.n), }; - p.emit(.{ .pipe = .{ .id = p.pipe_seq } }); + p.emit(.{ .pipe = .{ .id = p.pipe.seq } }); } /// Frontends call this while draining a .pipe effect, then immediately /// copy the borrowed view into a worker-owned selection_pipe.Job. -pub fn pipeRequest(p: *const Pardes, id: u32) ?selection_pipe.Request { - if (p.pipe_wait) |*wait| { +pub fn pipeRequest(pipe: *const Pipe, id: u32) ?selection_pipe.Request { + if (pipe.wait) |*wait| { if (wait.id == id) return wait.request(); } return null; @@ -215,9 +221,9 @@ pub fn pipeResponse( ) void { // A SUPERSEDED OR UNKNOWN id is the one silence worth keeping: it is // the answer to a question nobody is still asking. - if (p.pipe_wait == null or p.pipe_wait.?.id != id) return; - var wait = p.pipe_wait.?; - p.pipe_wait = null; + if (p.pipe.wait == null or p.pipe.wait.?.id != id) return; + var wait = p.pipe.wait.?; + p.pipe.wait = null; defer wait.deinit(p.gpa); if (!success or outputs.len != wait.inputs.len) return pipeFailed(p, &wait, failure); @@ -296,7 +302,7 @@ test "selection pipe prompt submits exact request and Escape cancels" { p.update(.{ .key = .{ .cp = Key.enter } }); try std.testing.expect(!pane.tag_edit and pane.prompt != .pipe); const id = nextPipeEffect(p) orelse return error.MissingPipeEffect; - const request = pipeRequest(p, id) orelse return error.MissingPipeRequest; + const request = p.pipe.pipeRequest(id) orelse return error.MissingPipeRequest; try std.testing.expectEqualStrings("tr a-z A-Z", request.command); try std.testing.expectEqualStrings("/", request.cwd); try std.testing.expectEqual(@as(usize, 1), request.inputs.len); @@ -327,7 +333,7 @@ test "selection pipe replaces all ranges atomically and undo restores them" { p.update(.{ .key = .{ .cp = 'c', .text = "cat" } }); p.update(.{ .key = .{ .cp = Key.enter } }); const id = nextPipeEffect(p) orelse return error.MissingPipeEffect; - const request = pipeRequest(p, id) orelse return error.MissingPipeRequest; + const request = p.pipe.pipeRequest(id) orelse return error.MissingPipeRequest; try std.testing.expectEqual(@as(usize, 2), request.inputs.len); try std.testing.expectEqualSlices(u8, "aa", request.inputs[0].bytes); try std.testing.expectEqualSlices(u8, "cc", request.inputs[1].bytes); @@ -399,7 +405,7 @@ test "a command with no stdin runs once and every cursor gets that one answer" { for ("date") |c| p.update(.{ .key = .{ .cp = c, .text = &.{c} } }); p.update(.{ .key = .{ .cp = Key.enter } }); const id = nextPipeEffect(p) orelse return error.MissingPipeEffect; - const request = pipeRequest(p, id) orelse return error.MissingPipeRequest; + const request = p.pipe.pipeRequest(id) orelse return error.MissingPipeRequest; try std.testing.expectEqual(@as(usize, 1), request.inputs.len); try std.testing.expectEqualSlices(u8, "", request.inputs[0].bytes); |
