From c1990b3e6e196ad41379aa432bf3ccca8a65d9f0 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Sun, 20 Sep 2026 00:36:50 -0300 Subject: Flatten the 9P control tree and move it out of fs.zig The served tree loses the self/ level: /index /ctl /new /log /screen /listeners /pane//... /os, with /src only in -Dembed-sources=true builds (default off, on for esp32p4). ctl speaks the editor's own language with two lowercase verbs, look TEXT and exec TEXT, plus acme's addr verbs; the new/ factory directory becomes one clone file; cons is gone (exec Msg); name and sel are files; stats report real lengths, modes and mtimes; /log streams pane new/del/rename/save events. The tree code lives in src/ninep/ (tree, pane, ctl, addr, pty, events, screen, sources); fs.zig keeps host access, mounts, resolution and find/grep. Same engine and transports. README (fs-help.txt) and docs rewritten; tests updated and extended. Co-Authored-By: Claude Fable 5.1 --- src/panes.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/panes.zig') diff --git a/src/panes.zig b/src/panes.zig index 49e5d624..edd7038f 100644 --- a/src/panes.zig +++ b/src/panes.zig @@ -1014,6 +1014,8 @@ pub const File = struct { /// Equal means the screen matches disk. saved_revision: u32 = 0, watch_after_save: bool = false, + /// Seconds of the last content change, for the filesystem's stat; zero until edited. + mtime: u32 = 0, /// Non-null for a generated output buffer rather than an on-disk file. output: ?Output.State = null, mini: ?Mini.State = null, @@ -1702,7 +1704,7 @@ pub const File = struct { const pane = slot orelse continue; if (pane.file) |*state| if (state == f) break i; } else return; - pardes.filesystem.noteReplace(p, id, false, f.content, new); + pardes.ctlfs.events.noteReplace(p, id, false, f.content, new); } pub fn setContent(p: *Pardes, f: *State, new: []u8) void { @@ -1722,6 +1724,7 @@ pub const File = struct { p.gpa.free(f.content); f.content = new; f.revision +%= 1; + f.mtime = pardes.ctlfs.events.now(); if (f.line_starts.len > 0) p.gpa.free(f.line_starts); f.line_starts = &.{}; if (f.highlights.len > 0) p.tree_sitter_gpa.free(f.highlights); @@ -2876,6 +2879,8 @@ pub const Output = struct { else => return error.NotAnEffect, } if (!setting.enabled(builtins.capabilities)) return error.EffectUnavailable; + // Without -Dembed-sources the paths would name nothing this build can open. + if (!limits.embedded_sources) return error.EffectUnavailable; const paths = effect_sources.forSetting(setting) orelse return error.EffectUnavailable; -- cgit v1.3