summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dump.zig2
-rw-r--r--src/look.zig16
-rw-r--r--src/pardes.zig2
-rw-r--r--src/pdf_view.zig4
4 files changed, 20 insertions, 4 deletions
diff --git a/src/dump.zig b/src/dump.zig
index 8e767240..4194f628 100644
--- a/src/dump.zig
+++ b/src/dump.zig
@@ -918,7 +918,7 @@ fn initDump(gpa: std.mem.Allocator, opts: Options, zon_bytes: []const u8, previo
&.{};
errdefer if (raw.len > 0) gpa.free(raw);
if (comptime pdf_enabled) {
- if (pardes.panes.Pdf.openPane(p, i, im.path, src.scroll + 1) catch null) |restored| {
+ if (pardes.panes.Pdf.openPane(p, i, im.path, src.scroll + 1, .last) catch null) |restored| {
if (raw.len > 0) gpa.free(raw);
raw = &.{};
restored.cols = @max(1, src.cols);
diff --git a/src/look.zig b/src/look.zig
index 454074c8..2e8a4b39 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -1238,6 +1238,11 @@ test "a miss names a long path by its start and its end, its middle given up to
try std.testing.expectEqualStrings("short/path.txt", missText("short/path.txt", &cut));
}
+fn missedPage(p: *Pardes, id: usize, path: []const u8, page: usize) void {
+ var cut: [miss_path_cap + "…".len]u8 = undefined;
+ missed(p, id, "{s} has no page {d}", .{ missText(path, &cut), page });
+}
+
fn missedLine(p: *Pardes, id: usize, path: []const u8, line: anytype) void {
var cut: [miss_path_cap + "…".len]u8 = undefined;
missed(p, id, "{s} has no line {d}", .{ missText(path, &cut), line });
@@ -1688,6 +1693,11 @@ pub fn lookAt(p: *Pardes, id: usize, operand_raw: []const u8) void {
// `@p<serial>` names no open pane: a miss, said.
if (t.id >= MAX_PANES or p.panes[t.id] == null) return missed(p, id, "no pane {s}", .{pl.path[0..@min(pl.path.len, 32)]});
const target = p.panes[t.id].?;
+ // A PDF's page past its last is a miss, as a line past a file's
+ // end is: never the last page in its place (opening one, the
+ // same: Pdf.openPane's .refuse).
+ if (comptime pdf_enabled) if (target.pdf) |pv| if (t.at.line > pv.page_count)
+ return missedPage(p, id, pv.path, t.at.line);
const before = p.active;
clearNavigationSelection(p, target);
focusPaneLine(p, t.id, t.at, .center);
@@ -1718,8 +1728,10 @@ pub fn lookAt(p: *Pardes, id: usize, operand_raw: []const u8) void {
if (comptime pdf_enabled) if (target.kind == .pdf) {
if (focusPaneByPath(p, target.path, target.at)) return;
const free = p.freeSlot() orelse return p.reportError(id, "look", error.NoPaneSlots);
- // Said with its path and why, as an image that cannot be read is.
- _ = panes.Pdf.openPane(p, free, target.path, target.at.line) catch |err| {
+ // Said with its path and why, as an image that cannot be read
+ // is; a page past its last is a miss, as for an open one.
+ _ = panes.Pdf.openPane(p, free, target.path, target.at.line, .refuse) catch |err| {
+ if (err == error.NoSuchPage) return missedPage(p, id, target.path, target.at.line);
var said: [miss_path_cap + 64]u8 = undefined;
var cut: [miss_path_cap + "…".len]u8 = undefined;
return p.reportError(id, std.fmt.bufPrint(&said, "look: {s}: not a PDF pardes can read", .{missText(target.path, &cut)}) catch "look: not a PDF pardes can read", err);
diff --git a/src/pardes.zig b/src/pardes.zig
index c8fffd80..bea79b18 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -4574,7 +4574,7 @@ pub const Pardes = struct {
const path = opts.file.?;
const opened = initial_doc: {
if (comptime pdf_enabled) if (look.isPdfPath(path))
- break :initial_doc panes.Pdf.openPane(p, 0, path, opts.file_line);
+ break :initial_doc panes.Pdf.openPane(p, 0, path, opts.file_line, .last);
if (look.isImagePath(path))
break :initial_doc panes.Image.create(p, 0, path, &.{});
break :initial_doc panes.File.open(p, 0, path, opts.file_line);
diff --git a/src/pdf_view.zig b/src/pdf_view.zig
index 5646a92f..e435d777 100644
--- a/src/pdf_view.zig
+++ b/src/pdf_view.zig
@@ -1877,6 +1877,9 @@ pub fn openPane(
id: usize,
path: []const u8,
page_one_based: usize,
+ /// A page past the last: the last page (a restore, a start-up), or
+ /// refused with error.NoSuchPage (a look, which names a place).
+ past_end: enum { last, refuse },
) !*pardes.Pane {
if (comptime !enabled) return error.PdfDisabled;
// The slot stays ours across the read: another request may make a
@@ -1891,6 +1894,7 @@ pub fn openPane(
break :virtual try State.openBytes(core.pdf_gpa, path, bytes, page_one_based);
};
errdefer state.deinit(core.pdf_gpa);
+ if (past_end == .refuse and page_one_based > state.page_count) return error.NoSuchPage;
const pane = try core.newDocPane(id);
pane.pdf = state;
pane.body.cur_pinned = true;