diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/look.zig | 26 | ||||
| -rw-r--r-- | src/pdf_view.zig | 10 |
2 files changed, 34 insertions, 2 deletions
diff --git a/src/look.zig b/src/look.zig index 11c77760..0f5103ba 100644 --- a/src/look.zig +++ b/src/look.zig @@ -1260,6 +1260,20 @@ fn missedPage(p: *Pardes, id: usize, path: []const u8, page: usize) void { missed(p, id, "{s} has no page {d}", .{ missText(path, &cut), page }); } +/// `file.pdf:P:H` names hit H of the pane's search on page P: none there, +/// or no search, is a miss as a page past the last is. +fn missedHit(p: *Pardes, id: usize, path: []const u8, page: usize, hit: usize) void { + var cut: [miss_path_cap + "…".len]u8 = undefined; + missed(p, id, "{s} has no search hit {d} on page {d}", .{ missText(path, &cut), hit, page }); +} + +/// The open PDF pane showing `path`, if one does. +fn pdfPaneOf(p: *Pardes, path: []const u8) ?*panes.Pdf.State { + if (comptime !pdf_enabled) return null; + for (p.panes) |slot| if (slot) |pane| if (pane.pdf) |*pv| if (std.mem.eql(u8, pv.path, path)) return pv; + return null; +} + 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 }); @@ -1505,6 +1519,7 @@ fn lookPdfPage(p: *Pardes, id: usize, target: usize, pv: anytype, expr: []const return missed(p, id, no_text, .{missText(pv.path, &cut)}) else 0; if (page == 0) return missedPage(p, id, pv.path, 0); if (page > pv.page_count) return missedPage(p, id, pv.path, page); + if (!pv.hitExists(p.pdf_gpa, page, hit)) return missedHit(p, id, pv.path, page, hit); const pane = p.panes[target].?; clearNavigationSelection(p, pane); if (pv.focusLocation(p.pdf_gpa, page, hit)) panes.Pdf.resetPageChrome(pane); @@ -1761,8 +1776,10 @@ pub fn lookAt(p: *Pardes, id: usize, operand_raw: []const u8) void { // 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); + if (comptime pdf_enabled) if (target.pdf) |*pv| { + if (t.at.line > pv.page_count) return missedPage(p, id, pv.path, t.at.line); + if (!pv.hitExists(p.pdf_gpa, @max(1, t.at.line), t.at.col)) return missedHit(p, id, pv.path, @max(1, t.at.line), t.at.col); + }; const before = p.active; clearNavigationSelection(p, target); focusPaneLine(p, t.id, t.at, .center); @@ -1791,6 +1808,11 @@ pub fn lookAt(p: *Pardes, id: usize, operand_raw: []const u8) void { }, .file => |target| { if (comptime pdf_enabled) if (target.kind == .pdf) { + // A hit of a search: one of the open pane's, checked by + // focusPaneByPath's pane; a PDF not open has none. + if (target.at.col > 0) if (pdfPaneOf(p, target.path)) |pv| { + if (!pv.hitExists(p.pdf_gpa, @max(1, target.at.line), target.at.col)) return missedHit(p, id, target.path, @max(1, target.at.line), target.at.col); + } else return missedHit(p, id, target.path, @max(1, target.at.line), target.at.col); 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 diff --git a/src/pdf_view.zig b/src/pdf_view.zig index b307d1f3..d5769ad3 100644 --- a/src/pdf_view.zig +++ b/src/pdf_view.zig @@ -547,6 +547,16 @@ pub const State = if (enabled) struct { state.search_results = results; } + /// Whether page `page` (one-based) holds search hit `hit` (one-based) of + /// the pane's search: none asked, no hit is there. + pub fn hitExists(state: *@This(), gpa: std.mem.Allocator, page: usize, hit: usize) bool { + if (hit == 0) return true; + if (state.search_query.len == 0 or page == 0 or page > state.page_count) return false; + var results = state.document.search(gpa, page - 1, state.search_query) catch return false; + defer results.deinit(gpa); + return hit <= results.hit_count; + } + pub fn ensureOutline(state: *@This(), gpa: std.mem.Allocator) ?*const pdf.Outline { if (!state.outline_tried) { state.outline_tried = true; |
