summaryrefslogtreecommitdiff
path: root/src/Output.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 10:30:38 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit2d0c506583d18d6f004fc117282deb2faea1d17e (patch)
tree683d1dd2820df31222360c0308fb3333b64aae1e /src/Output.zig
parentf207f1d4d56d1012766e6206e713f2b3da70579d (diff)
downloadpardes-2d0c506583d18d6f004fc117282deb2faea1d17e.tar.gz
pardes-2d0c506583d18d6f004fc117282deb2faea1d17e.zip
Recent lists the files opened lately, closed ones too, and a jump back to a closed file reopens it
A file closed by accident, its path forgotten, could not be found again: the jumplist dropped closed panes. Every file opened (a look, a Save of a scratch, a Restore, a rename) goes first in a list of 200, kept once, its dot noted when it closes, kept across sessions in $XDG_STATE_HOME/pardes/ recent. `Recent` (SPC f r) shows it in a reused +Recent, each row `path:line:col open|closed` a look reopens; /recent reads `open|closed <path>`. The jumplist keeps a closed file's entries, +Jumps marks them `(closed)`, and Back to one opens the file at its place. acme has no such thing; its dump and Load are the nearest. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/Output.zig')
-rw-r--r--src/Output.zig49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/Output.zig b/src/Output.zig
index 37d25168..dd6ab92a 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -505,6 +505,12 @@ pub fn openJumps(p: *Pardes, id: usize) !void {
var out: std.Io.Writer.Allocating = .init(p.gpa);
errdefer out.deinit();
for (p.jumps[0..p.njumps]) |j| {
+ // A closed file's entry: marked, and a look at it opens it again.
+ if (j.serial == 0) {
+ const e = p.recentByHash(j.path_hash) orelse continue;
+ try out.writer.print("{s}:{d}:{d} (closed)\n", .{ e.path, @max(1, j.line), @max(1, j.col) });
+ continue;
+ }
const jp = p.panes[j.pane] orelse continue;
var idbuf: [16]u8 = undefined;
const pdf_path: ?[]const u8 = if (comptime pardes.pdf_enabled) jp.pdfPath() else null;
@@ -532,6 +538,49 @@ pub fn openJumps(p: *Pardes, id: usize) !void {
try openStepped(p, id, .{ .cmd = .Jumplist }, content);
}
+/// The recent list as rows: `<path>:<line>:<col> open|closed`, most recent
+/// first; a look at a row opens the file there, as a +Jumps row does.
+pub fn recentText(p: *Pardes, w: *std.Io.Writer, look_rows: bool) !void {
+ for (p.recent.entries.items) |e| {
+ var is_open = false;
+ for (p.panes) |slot| if (slot) |pane| if (pane.file) |f| if (f.output == null and std.mem.eql(u8, f.path, e.path)) {
+ is_open = true;
+ };
+ const state: []const u8 = if (is_open) "open" else "closed";
+ if (!look_rows)
+ try w.print("{s} {s}\n", .{ state, e.path })
+ else if (e.line == 0)
+ try w.print("{s} {s}\n", .{ e.path, state })
+ else
+ try w.print("{s}:{d}:{d} {s}\n", .{ e.path, e.line, e.col, state });
+ }
+}
+
+/// Recent: the one +Recent, filled again when it is there (as Find and
+/// Grep's +Search is), else opened below the asking pane.
+pub fn openRecent(p: *Pardes, id: usize) !void {
+ var out: std.Io.Writer.Allocating = .init(p.gpa);
+ errdefer out.deinit();
+ try recentText(p, &out.writer, true);
+ const content = try out.toOwnedSlice();
+ for (p.panes, 0..) |slot, i| {
+ const rp = slot orelse continue;
+ const rf = if (rp.file) |*f| f else continue;
+ const o = rf.output orelse continue;
+ if (!std.meta.eql(o.from, Origin{ .cmd = .Recent })) continue;
+ File.setContent(p, rf, content);
+ resetBody(p, rp);
+ p.fs.refilled = rp.serial;
+ if (p.panes[id]) |pane| {
+ pane.search_pane = i;
+ pane.search_row = null;
+ }
+ look.armLookWalk(p, i);
+ return;
+ }
+ try openStepped(p, id, .{ .cmd = .Recent }, content);
+}
+
pub fn openThemes(p: *Pardes, id: usize) !void {
var out: std.Io.Writer.Allocating = .init(p.gpa);
errdefer out.deinit();