summaryrefslogtreecommitdiff
path: root/src/builtins.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/builtins.zig')
-rw-r--r--src/builtins.zig36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index d6b89cf2..d06897ff 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -238,6 +238,21 @@ test "Restore asks about unsaved text as Exit does, and restores when asked agai
try std.testing.expectEqualStrings("/tmp/some.dump.zon", p.restore_req.?);
}
+test "a Restore's warning is not an Exit's: each word is warned on its own" {
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
+ defer p.deinit();
+ const pane = try p.setTestFile("saved\n");
+ pane.file.?.saved_revision = pane.file.?.revision -% 1; // modified
+ try std.testing.expect(p.executeBuiltinLine(p.active, "Restore /tmp/some.dump.zon"));
+ try std.testing.expect(p.restore_req == null);
+ // The Restore warned; an Exit after it has not been, and asks.
+ try std.testing.expect(p.executeBuiltinLine(p.active, "Exit"));
+ try std.testing.expect(!p.quit);
+ try std.testing.expect(std.mem.endsWith(u8, pane.msg[0..pane.msg_len], ": Modified (Exit again to discard)"));
+ try std.testing.expect(p.executeBuiltinLine(p.active, "Exit"));
+ try std.testing.expect(p.quit);
+}
+
test "Kill stops the commands pardes typed, bare all and by name those that match, and never quits" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 24 });
defer p.deinit();
@@ -356,21 +371,22 @@ pub const Exec = struct {
/// what would throw unsaved text away: each pane holding some nobody has
/// been told about says so, `<name>: Modified (Exit again to discard)`,
/// naming the word asking, since repeating it throws the text away, and is
-/// then clean for the
-/// asking, as winclean clears `dirty`; so the same word again, with
-/// nothing edited since, goes ahead. A scratch of under 100 bytes is no
-/// loss worth the question, as winclean does not ask for one.
-fn warnModified(c: Ctx, asking: []const u8) bool {
+/// then clean for the asking, as winclean clears `dirty`; so the same word
+/// again, with nothing edited since, goes ahead. Only the same word: a
+/// Restore a script was refused does not spend the warning an Exit owes
+/// the person at the keyboard. A scratch of under 100 bytes is no loss
+/// worth the question, as winclean does not ask for one.
+fn warnModified(c: Ctx, asking: Pane.Discarding) bool {
var modified = false;
for (c.p.panes, 0..) |slot, id| {
const pane = slot orelse continue;
const f = pane.file orelse continue;
if (f.revision == f.saved_revision or !panes.Output.fileTraits(f.output).saves) continue;
if (f.output != null and f.content.len < 100) continue;
- if (pane.discard_warned == f.revision) continue;
- pane.discard_warned = f.revision;
+ if (pane.discard_warned) |w| if (w.revision == f.revision and w.by == asking) continue;
+ 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, asking }) catch f.path);
+ c.p.reportFailure(id, std.fmt.bufPrint(&buf, "{s}: Modified ({s} again to discard)", .{ f.path, @tagName(asking) }) catch f.path);
modified = true;
}
return modified;
@@ -381,7 +397,7 @@ fn warnModified(c: Ctx, asking: []const u8) bool {
pub const Exit = struct {
pub const scope: Scope = .session;
pub fn run(c: Ctx) void {
- if (warnModified(c, "Exit")) return;
+ if (warnModified(c, .Exit)) return;
c.p.quit = true;
c.p.emit(.quit);
}
@@ -436,7 +452,7 @@ pub const Restore = struct {
if (path.len > c.p.restore_buf.len) return;
// acme's Load adds a dump's windows to the ones there; a Restore
// replaces them all, so it asks what Exit asks first.
- if (warnModified(c, "Restore")) return;
+ if (warnModified(c, .Restore)) return;
@memcpy(c.p.restore_buf[0..path.len], path);
c.p.restore_req = c.p.restore_buf[0..path.len];
}