summaryrefslogtreecommitdiff
path: root/src/look.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 11:09:17 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit5db9e71ba32dd6f0a0292eaa341d1d8ba805483c (patch)
treefeaf11471f49fdba5122922a960889ea4cb4f549 /src/look.zig
parent6b46d0797003585a99f8e5b99b3e8cff635ebebc (diff)
downloadpardes-5db9e71ba32dd6f0a0292eaa341d1d8ba805483c.tar.gz
pardes-5db9e71ba32dd6f0a0292eaa341d1d8ba805483c.zip
A remembered place is clamped to the file as it is now, its selection's two ends kept
A Recent row or a jumplist entry for a line the file no longer has failed the look; now it opens at the last line. The selection's anchor is remembered too, so a reopen restores both ends where they fit, and Recent and Jumplist share the (closed) marker. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/look.zig')
-rw-r--r--src/look.zig44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/look.zig b/src/look.zig
index ca9aa80a..0baa9afc 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -1381,8 +1381,52 @@ fn spotAt(text: []const u8, q: u32) struct { line: usize, col: usize } {
return .{ .line = line, .col = upto.len - start + 1 };
}
+/// A remembered place in `path` (Recent, the jumplist): the file opened or
+/// focused, then `at` clamped to it as it is now, a line past the end its
+/// last line, never a miss; a selection's two ends restored where they
+/// still fit.
+pub fn reopenAt(p: *Pardes, from: usize, path: []const u8, at: Spot) void {
+ lookAt(p, from, path);
+ const id = p.active;
+ const pane = p.panes[id] orelse return;
+ const f = if (pane.file) |*file| file else return;
+ if (!std.mem.eql(u8, f.path, path)) return;
+ const n = @max(1, panes.File.nlines(p.gpa, f));
+ const clamp = struct {
+ fn spot(text: []const u8, lines: usize, line: usize, col: usize) [2]usize {
+ const l = std.math.clamp(line, 1, lines);
+ const width = modal.lineSlice(text, l - 1).len + 1;
+ return .{ l, std.math.clamp(col, 1, width) };
+ }
+ };
+ const head = clamp.spot(f.content, n, at.line, at.col);
+ var to: Spot = .{ .line = head[0], .col = head[1] };
+ if (at.end_line != 0) {
+ const end = clamp.spot(f.content, n, at.end_line, at.end_col);
+ to.end_line = end[0];
+ to.end_col = end[1];
+ }
+ clearNavigationSelection(p, pane);
+ focusPaneLine(p, id, to, .center);
+}
+
+/// Whether `pane` is the +Recent list, whose rows are remembered places.
+fn isRecentList(pane: *const Pane) bool {
+ const f = pane.file orelse return false;
+ const o = f.output orelse return false;
+ return std.meta.eql(o.from, panes.Output.Origin{ .cmd = .Recent });
+}
+
pub fn lookAt(p: *Pardes, id: usize, operand: []const u8) void {
const pane = p.panes[id] orelse return;
+ // A +Recent row is a remembered place: reopened and clamped to the file
+ // as it is now, never a miss for a line the file no longer has.
+ if (isRecentList(pane)) {
+ const row = std.mem.trim(u8, operand, " \t\r\n");
+ const loc = row[0 .. std.mem.indexOfScalar(u8, row, ' ') orelse row.len];
+ const pl = parsePathLine(loc);
+ if (pl.path.len > 0 and pl.path[0] == '/' and pl.at.line != 0) return reopenAt(p, id, pl.path, pl.at);
+ }
p.noteHaptic(.look);
noteLookSource(p, id);
const command = std.mem.trim(u8, operand, " \t\r\n");