summaryrefslogtreecommitdiff
path: root/src/Pipe.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-27 22:46:26 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit71a9f04342493325c10b1b9bc122a88d41143782 (patch)
treec9b1f27a84404a8332c4066a56d922a031eec194 /src/Pipe.zig
parentd126715cd20a39dbc10870318968546f5e371b97 (diff)
downloadpardes-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.zig32
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);