summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ninep/ctl.zig28
-rw-r--r--src/pardes.zig22
2 files changed, 50 insertions, 0 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index d815632d..db058ff2 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -2408,6 +2408,34 @@ test "/recent shows a name as /index does, a newline in it escaped" {
try testing.expect(std.mem.indexOf(u8, text, "closed /tmp/a\\nb\\\\c\n") != null);
}
+test "Back over a closed file deleted since skips it, says so, and goes on to the place before" {
+ const p = try withFile(testing.allocator, "x\n");
+ defer p.deinit();
+ var tmp = testing.tmpDir(.{});
+ defer tmp.cleanup();
+ for ([_][]const u8{ "a.txt", "gone.txt", "c.txt" }) |name| try tmp.dir.writeFile(testing.io, .{ .sub_path = name, .data = "text\n" });
+ var dir_buf: [4096]u8 = undefined;
+ const dir = dir_buf[0..try tmp.dir.realPath(testing.io, &dir_buf)];
+ var line: [4200]u8 = undefined;
+ _ = wr(p, root_look, try std.fmt.bufPrint(&line, "{s}/a.txt\n", .{dir}));
+ p.sync();
+ const a_serial = p.panes[p.active].?.serial;
+ _ = wr(p, root_look, try std.fmt.bufPrint(&line, "{s}/gone.txt\n", .{dir}));
+ p.sync();
+ const gone = p.active;
+ _ = wr(p, root_look, try std.fmt.bufPrint(&line, "{s}/c.txt\n", .{dir}));
+ p.sync();
+ const c_id = p.active;
+ _ = wr(p, Node.of(p.panes[gone].?.serial, .ctl), "Del\n");
+ p.sync();
+ try tmp.dir.deleteFile(testing.io, "gone.txt");
+ p.active = c_id;
+ p.jumpBy(-1);
+ p.sync();
+ try testing.expectEqual(a_serial, p.panes[p.active].?.serial);
+ try testing.expect(std.mem.indexOf(u8, p.panes[c_id].?.msg[0..p.panes[c_id].?.msg_len], "gone.txt: deleted, skipped") != null);
+}
+
test "a remembered place is clamped to the file as it is now, its selection's two ends kept where they fit" {
const p = try withFile(testing.allocator, "x\n");
defer p.deinit();
diff --git a/src/pardes.zig b/src/pardes.zig
index 135823e4..4147032b 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -6817,6 +6817,28 @@ pub const Pardes = struct {
// places it, and the entry is that pane from here on.
if (j.serial == 0) {
const e = p.recentByHash(j.path_hash) orelse return;
+ // Deleted since: its entries go, it is said, and the step goes
+ // on to the next place, never stuck on one that cannot open.
+ if (!recentKeeps(e.path)) {
+ var said: [recent_path_cap + 32]u8 = undefined;
+ p.setMessage(p.active, std.fmt.bufPrint(&said, "{s}: deleted, skipped", .{e.path}) catch "deleted, skipped");
+ const hash = j.path_hash;
+ var w: usize = 0;
+ var cur = p.jcur;
+ for (p.jumps[0..p.njumps], 0..) |k, i| {
+ if (k.serial == 0 and k.path_hash == hash) {
+ if (i < p.jcur) cur -= 1;
+ continue;
+ }
+ p.jumps[w] = k;
+ w += 1;
+ }
+ p.njumps = w;
+ p.jcur = @min(cur, w -| 1);
+ // The same step again, over the list without them: each
+ // round takes one file's entries away, so it ends.
+ return p.jumpBy(delta);
+ }
const from = p.active;
look.reopenAt(p, from, e.path, .{ .line = @max(1, j.line), .col = @max(1, j.col) });
const opened = p.panes[p.active] orelse return;