diff options
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); |
