From 682e237df7e8b22f820d14a4adee58e6e2f84268 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Fri, 11 Sep 2026 12:38:56 -0300 Subject: 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. --- src/fs.zig | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'src/fs.zig') 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", .{ -- cgit v1.3