summaryrefslogtreecommitdiff
path: root/src/Output.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Output.zig')
-rw-r--r--src/Output.zig35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/Output.zig b/src/Output.zig
index f2ab1bda..b8dd5e34 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -609,6 +609,41 @@ pub fn openUnsaved(p: *Pardes, id: usize, content: []u8) void {
p.active = id;
}
+/// Pane `gone` closed: its row goes from +Unsaved, which lists only panes
+/// still there to lose.
+pub fn dropUnsaved(p: *Pardes, gone: *const Pane) void {
+ const gf = gone.file orelse return;
+ if (gf.output != null and !(gf.output.?.from == .cmd and gf.output.?.from.cmd == .New)) return;
+ for (p.panes) |slot| {
+ const rp = slot orelse continue;
+ if (rp == gone) continue;
+ const rf = if (rp.file) |*f| f else continue;
+ const o = rf.output orelse continue;
+ if (o.from != .unsaved) continue;
+ var scratch_name: [limits.host_path_cap + 24]u8 = undefined;
+ const as_scratch = std.fmt.bufPrint(&scratch_name, "{s} (pane {d}): Modified", .{ gf.path, gone.serial }) catch "";
+ var out: std.ArrayList(u8) = .empty;
+ var lines = std.mem.splitScalar(u8, rf.content, '\n');
+ var dropped = false;
+ var first = true;
+ while (lines.next()) |line| {
+ const is_it = std.mem.startsWith(u8, line, gf.path) and std.mem.eql(u8, line[gf.path.len..], ": Modified");
+ if (is_it or (as_scratch.len > 0 and std.mem.eql(u8, line, as_scratch))) {
+ dropped = true;
+ continue;
+ }
+ if (!first) out.append(p.gpa, '\n') catch return out.deinit(p.gpa);
+ out.appendSlice(p.gpa, line) catch return out.deinit(p.gpa);
+ first = false;
+ }
+ if (!dropped) return out.deinit(p.gpa);
+ const content = out.toOwnedSlice(p.gpa) catch return out.deinit(p.gpa);
+ File.setContent(p, rf, content);
+ resetBody(p, rp);
+ return;
+ }
+}
+
/// Recent: the one +Recent, filled again when it is there (as Find and
/// Grep's +Search is), else opened below the asking pane.
pub fn openRecent(p: *Pardes, id: usize) !void {