diff options
Diffstat (limited to 'src/Pipe.zig')
| -rw-r--r-- | src/Pipe.zig | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/src/Pipe.zig b/src/Pipe.zig index 48e98b7b..850f9c64 100644 --- a/src/Pipe.zig +++ b/src/Pipe.zig @@ -8,6 +8,7 @@ const panes = @import("panes.zig"); const config = @import("config.zig"); const selection_pipe = @import("selection_pipe.zig"); const edit = @import("edit.zig"); +const edit_cmd = @import("edit_cmd.zig"); const Pane = panes.Pane; const Text = panes.Text; const Key = pardes.Key; @@ -18,6 +19,17 @@ const Pipe = @This(); seq: u32 = 0, /// The request in flight, and what it needs to apply its answer. wait: ?PendingPipe = null, +/// An Edit waiting on its `<`, `|` and `>` commands, which share the ids. +edit_run: ?*edit_cmd.Pending = null, +/// What an Edit's `w` took, for the `edit_write` effect to write. +writes: std.ArrayList(edit_cmd.Write) = .empty, + +pub fn deinit(pipe: *Pipe, gpa: std.mem.Allocator) void { + if (pipe.wait) |*wait| wait.deinit(gpa); + if (pipe.edit_run) |pending| pending.deinit(gpa); + for (pipe.writes.items) |*w| w.deinit(gpa); + pipe.writes.deinit(gpa); +} fn nextPipeEffect(p: *Pardes) ?u32 { while (p.nextEffect()) |effect| switch (effect) { @@ -164,6 +176,7 @@ pub fn pipeRequest(pipe: *const Pipe, id: u32) ?selection_pipe.Request { if (pipe.wait) |*wait| { if (wait.id == id) return wait.request(); } + if (pipe.edit_run) |pending| if (pending.id == id) return pending.request; return null; } @@ -172,26 +185,9 @@ fn pipeFailed(p: *Pardes, wait: *const PendingPipe, failure: ?selection_pipe.Fai defer out.deinit(); const w = &out.writer; w.print("| {s}\n\n", .{wait.command}) catch return; - if (failure) |fail| { - if (wait.inputs.len > 1) - w.print("selection {d} of {d}: ", .{ fail.index + 1, wait.inputs.len }) catch return; - switch (fail.kind) { - .exit => w.print("exit status {d}\n", .{fail.code}) catch return, - .signal => w.writeAll("killed by a signal\n") catch return, - .timeout => w.print( - "still running after {d} seconds, and stopped\n", - .{selection_pipe.command_timeout_seconds}, - ) catch return, - .too_large => w.writeAll("produced more output than a filter may return\n") catch return, - .spawn => w.writeAll("could not be started\n") catch return, - .io => w.writeAll("could not be read\n") catch return, - } - if (fail.stderr.len > 0) w.print("\n{s}", .{fail.stderr}) catch return; - } else { - // No diagnosis at all: nobody ran it. The detached daemon, the - // browser and the board all leave `pipe` null on purpose. - w.writeAll("this session cannot run filters\n") catch return; - } + if (wait.inputs.len > 1) if (failure) |fail| + w.print("selection {d} of {d}: ", .{ fail.index + 1, wait.inputs.len }) catch return; + writeFailure(w, failure) catch return; const content = out.toOwnedSlice() catch return; const was = p.active; panes.Output.openErrors(p, wait.pane, content) catch |err| { @@ -203,6 +199,28 @@ fn pipeFailed(p: *Pardes, wait: *const PendingPipe, failure: ?selection_pipe.Fai if (p.panes[was] != null) p.active = was; } +/// How a filter failed, a line, and the command's stderr after it: what +/// +Errors says of a `|` and of an Edit's `< | >`. +pub fn writeFailure(w: *std.Io.Writer, failure: ?selection_pipe.Failure) !void { + const fail = failure orelse { + // No diagnosis at all: nobody ran it. The detached daemon, the + // browser and the board all leave `pipe` null on purpose. + return w.writeAll("this session cannot run filters\n"); + }; + switch (fail.kind) { + .exit => try w.print("exit status {d}\n", .{fail.code}), + .signal => try w.writeAll("killed by a signal\n"), + .timeout => try w.print( + "still running after {d} seconds, and stopped\n", + .{selection_pipe.command_timeout_seconds}, + ), + .too_large => try w.writeAll("produced more output than a filter may return\n"), + .spawn => try w.writeAll("could not be started\n"), + .io => try w.writeAll("could not be read\n"), + } + if (fail.stderr.len > 0) try w.print("\n{s}", .{fail.stderr}); +} + fn pipeCut(wait: *const PendingPipe, content: []const u8, i: usize) ?struct { lo: usize, hi: usize } { const range = wait.ranges[i]; const lo = @min(range.anchor, range.head); @@ -240,6 +258,7 @@ pub fn pipeResponse( outputs: []const []const u8, failure: ?selection_pipe.Failure, ) void { + if (p.pipe.edit_run) |pending| if (pending.id == id) return edit_cmd.finish(p, success, outputs, failure); // 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; |
