diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/builtins.zig | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/builtins.zig b/src/builtins.zig index 97f7817f..ef425c91 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -240,6 +240,28 @@ test "Exit asks once about unsaved text, and quits when asked again" { try std.testing.expect(p.quit); } +test "Exit over a ctl write names every pane it asks about, and the next Exit discards them all" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + const first = try p.setTestFile("saved\n"); + first.file.?.saved_revision = first.file.?.revision -% 1; + p.newScratchBelow(p.active); + const second = p.panes[p.active].?; + panes.File.setContent(p, &second.file.?, try std.testing.allocator.dupe(u8, "x" ** 120)); + try std.testing.expect(second.file.?.revision != second.file.?.saved_revision); + p.fs.no_prompt = true; + defer p.fs.no_prompt = false; + try std.testing.expect(p.executeBuiltinLine(p.active, "Exit")); + try std.testing.expect(!p.quit); + const said = p.fs.failure[0..p.fs.failure_len]; + try std.testing.expect(std.mem.indexOf(u8, said, first.file.?.path) != null); + try std.testing.expect(std.mem.indexOf(u8, said, second.file.?.path) != null); + try std.testing.expect(std.mem.endsWith(u8, said, ": Modified (Exit again to discard them all)")); + p.fs.failure_len = 0; + try std.testing.expect(p.executeBuiltinLine(p.active, "Exit")); + try std.testing.expect(p.quit); +} + /// A dump file that exists, for a Restore to get past reading it. fn testDump(buf: []u8) ![]const u8 { var tmp = std.testing.tmpDir(.{}); @@ -419,6 +441,10 @@ pub const Exec = struct { /// worth the question, as winclean does not ask for one. fn warnModified(c: Ctx, asking: Pane.Discarding) bool { var modified = false; + // Every pane asked about is named in the one refusal a ctl write gets, + // as acme's rowclean names them all (wind.c:511). + var all_buf: [256]u8 = undefined; + var all = std.Io.Writer.fixed(&all_buf); for (c.p.panes, 0..) |slot, id| { const pane = slot orelse continue; const f = pane.file orelse continue; @@ -428,8 +454,15 @@ fn warnModified(c: Ctx, asking: Pane.Discarding) bool { pane.discard_warned = .{ .revision = f.revision, .by = asking }; var buf: [limits.host_path_cap + 48]u8 = undefined; c.p.reportFailure(id, std.fmt.bufPrint(&buf, "{s}: Modified ({s} again to discard)", .{ f.path, @tagName(asking) }) catch f.path); + all.print("{s}{s}", .{ if (modified) ", " else "", f.path }) catch {}; modified = true; } + if (modified and c.p.fs.no_prompt) { + all.print(": Modified ({s} again to discard them all)", .{@tagName(asking)}) catch {}; + const said = @import("Messages.zig").clip(all.buffered(), c.p.fs.failure.len); + @memcpy(c.p.fs.failure[0..said.len], said); + c.p.fs.failure_len = @intCast(said.len); + } return modified; } |
