summaryrefslogtreecommitdiff
path: root/src/fs.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-11 12:38:56 -0300
committerGabriel Schneider <[email protected]>2026-09-15 17:24:42 -0300
commit682e237df7e8b22f820d14a4adee58e6e2f84268 (patch)
tree5d888cb46f1a49e89fc55e2a4c232d3af0265b1d /src/fs.zig
parent6878e1c309172d624c0d7a3555f6f0217ae6770e (diff)
downloadpardes-682e237df7e8b22f820d14a4adee58e6e2f84268.tar.gz
pardes-682e237df7e8b22f820d14a4adee58e6e2f84268.zip
trunk: resume before the Reload experiment
Empty marker on the last pre-Reload change. Keep the Reload experiment on reload (3801914), its first change on reload-start (200a1fc), and the unfinished performance investigation on reload-perf-wip.
Diffstat (limited to 'src/fs.zig')
-rw-r--r--src/fs.zig51
1 files changed, 33 insertions, 18 deletions
diff --git a/src/fs.zig b/src/fs.zig
index 50b56f76..63d2ed3a 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -2911,6 +2911,36 @@ fn writeCtl(p: *Pardes, req: Req, serial: u32) Reply {
return .{ .tag = req.tag, .written = @intCast(req.data.len) };
}
+/// Change a buffer's absolute name without writing or renaming a disk file.
+/// Tag editing preserves user commands; the 9P name operation resets its tail.
+pub fn nameBuffer(p: *Pardes, id: usize, full: []const u8, preserve_tag: bool) !void {
+ const pane = p.panes[id] orelse return error.NoPane;
+ const f = fileOf(pane) orelse return error.NotFile;
+ if (!std.fs.path.isAbsolute(full) or full.len == 0 or full.len >= 4096)
+ return error.InvalidName;
+ for (full) |c| if (c < ' ') return error.InvalidName;
+ if (std.mem.eql(u8, f.path, full)) return;
+ const copy = try p.gpa.dupe(u8, full);
+ p.gpa.free(f.path);
+ f.path = copy;
+ if (panes.Output.fileTraits(f.output).saves) {
+ f.output = null;
+ pane.clearCwd();
+ if (!preserve_tag) {
+ pane.tag_init = false;
+ pane.tag_tail_len = 0;
+ }
+ f.saved_revision = f.revision -% 1;
+ f.watch_after_save = localPath(full) != null;
+ }
+ if (f.highlights.len > 0) p.tree_sitter_gpa.free(f.highlights);
+ f.highlights = &.{};
+ f.highlight_start = 0;
+ f.syntax_dirty = true;
+ p.invalidateLookHover(id);
+ p.emit(.{ .watch = .{ .pane = @intCast(id), .on = false } });
+}
+
fn ctlVerb(p: *Pardes, id: usize, line: []const u8, apply: bool, dirty: *bool) u16 {
const pane = p.panes[id] orelse return E.INVAL;
const pf = &p.fs.panes[id];
@@ -2935,23 +2965,7 @@ fn ctlVerb(p: *Pardes, id: usize, line: []const u8, apply: bool, dirty: *bool) u
if (std.mem.eql(u8, f.path, full)) return 0;
if (panes.Output.fileTraits(f.output).saves) dirty.* = true;
if (!apply) return 0;
- const copy = p.gpa.dupe(u8, full) catch return E.NOMEM;
- p.gpa.free(f.path);
- f.path = copy;
- if (panes.Output.fileTraits(f.output).saves) {
- f.output = null;
- pane.clearCwd();
- pane.tag_init = false;
- pane.tag_tail_len = 0;
- f.saved_revision = f.revision -% 1;
- f.watch_after_save = localPath(full) != null;
- }
- if (f.highlights.len > 0) p.tree_sitter_gpa.free(f.highlights);
- f.highlights = &.{};
- f.highlight_start = 0;
- f.syntax_dirty = true;
- p.invalidateLookHover(id);
- p.emit(.{ .watch = .{ .pane = @intCast(id), .on = false } });
+ nameBuffer(p, id, full, false) catch return E.NOMEM;
return 0;
}
for (refused_verbs) |w| if (verbIs(line, w)) return E.INVAL;
@@ -3711,7 +3725,8 @@ test "index prints winctlprint's five fields then the tag" {
@memcpy(got[0..a.bytes.len], a.bytes);
const line = got[0..a.bytes.len];
- const tag = tagOf(p, pane);
+ const tag = try gpa.dupe(u8, tagOf(p, pane));
+ defer gpa.free(tag);
var want: std.ArrayList(u8) = .empty;
defer want.deinit(gpa);
try want.print(gpa, "{d:>11} {d:>11} {d:>11} {d:>11} {d:>11} {s}\n", .{