summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 19:19:00 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commit045e9e748d02c0417263655999b459ad351916d7 (patch)
treefc85b5a0e257abd8ae86cdf9459f18f14a4b7841 /src
parent3189900c13b98298776d0da8dcbcb4e0d88858cf (diff)
downloadpardes-045e9e748d02c0417263655999b459ad351916d7.tar.gz
pardes-045e9e748d02c0417263655999b459ad351916d7.zip
Save and Save path on a PDF or image pane are refused, "a PDF pane has no text to save", never a silent success
A bare Save on a PDF or an image did nothing, and `Save path` returned without writing, both answered as done. Such a pane shows a file it does not hold as text, so there is nothing of its own to write. Save now refuses it with why ("Save: a PDF pane has no text to save", or an image pane's), and so fails the write that asked. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/builtins.zig5
-rw-r--r--src/ninep/ctl.zig13
2 files changed, 18 insertions, 0 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index 27a1d36d..4d257a9e 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -986,6 +986,11 @@ pub const ClipReplace = struct {
pub const Save = struct {
pub const takes_arg = true;
pub fn run(c: Ctx) void {
+ // A PDF or an image shows a file it does not hold as text: there
+ // is nothing of its own to write, bare or to a path. Said, never a
+ // silent success.
+ if (c.pane.file == null and !c.pane.isTerminal())
+ return c.p.reportFailure(c.id, if (c.pane.hasPdf()) "Save: a PDF pane has no text to save" else "Save: an image pane has no text to save");
const path = std.mem.trim(u8, c.arg orelse "", " \t\r\n");
if (path.len > 0) return exec.saveTo(c.p, c.id, path);
if (c.pane.file) |file| if (file.output == null) return exec.saveFile(c.p, c.id);
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 118b6488..a0a363b5 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -1658,6 +1658,19 @@ test "Save path of a file pane logs a save record naming that path" {
try testing.expect(th.logHas(p, try std.fmt.bufPrint(&want, "save {d} /tmp/pardes-save-copy.txt\n", .{serial})));
}
+test "Save and Save path on an image pane are refused with why, never a silent success" {
+ const p = try withFile(testing.allocator, "x\n");
+ defer p.deinit();
+ const id = p.freeSlot().?;
+ const doc = try p.newDocPane(id);
+ doc.image = .{ .path = try p.gpa.dupe(u8, "/tmp/pardes-pic.ppm") };
+ for ([_][]const u8{ "Save\n", "Save /tmp/pardes-copy.ppm\n" }) |line| {
+ const r = wr(p, Node.of(doc.serial, .ctl), line);
+ try testing.expectEqual(Status.err, r.reply.status);
+ try testing.expectEqualStrings("Save: an image pane has no text to save", r.reply.ename);
+ }
+}
+
test "exec Save writes the named file through the host" {
const gpa = testing.allocator;
const p = try withFile(gpa, "one\ntwo\n");