From 6f48508aa08396bcf9dd4da2cab1d221bcc53f78 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 25 Aug 2026 02:07:23 -0300 Subject: acmefs: pardes --fs serves acme's control filesystem over raw Linux FUSE --- src/main.zig | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) (limited to 'src/main.zig') diff --git a/src/main.zig b/src/main.zig index be188200..69cc1715 100644 --- a/src/main.zig +++ b/src/main.zig @@ -80,6 +80,11 @@ const help_text = \\ Without it, a pardes started inside a pardes \\ hands its FILE argument to the outer one. This \\ session will not serve its own children either. + \\ --fs serve acme's control filesystem for this session + \\ under $XDG_RUNTIME_DIR/pardes/, and export + \\ PARDES_FS and PARDES_PANE into every pane shell + \\ --fs= ...at instead. Must be absolute; pardes + \\ unmounts it on exit but leaves the directory \\ -h, --help show this help and exit \\ ; @@ -120,11 +125,17 @@ fn nativeMain(init: std.process.Init) !void { var opts: pardes.Options = .{}; const arena = init.arena.allocator(); const args = try init.minimal.args.toSlice(arena); - // bare `pardes` boots straight into tty mode — and `pardes --nested` still - // counts as bare, because --nested says something about the session's - // relationship to its parent and nothing about its layout - if (args.len == 1 or (args.len == 2 and std.mem.eql(u8, args[1], "--nested"))) - opts.tty_only = true; + // bare `pardes` boots straight into tty mode — and so does a `pardes` + // carrying nothing but flags that say something about the SESSION rather + // than about its layout: --nested is about this session's relationship to + // its parent, --fs is about who may script it, and neither says anything + // about what should be on screen. Anything else (a FILE, -n, --tty) is + // layout, and answers this question itself further down. + opts.tty_only = for (args[1..]) |a| { + if (!std.mem.eql(u8, a, "--nested") and + !std.mem.eql(u8, a, "--fs") and + !std.mem.startsWith(u8, a, "--fs=")) break false; + } else true; // Kept RAW until every flag is parsed: classifying it means chdir'ing into // a directory and recording nothing, and the nested client below still // needs the word itself to resolve. @@ -148,6 +159,16 @@ fn nativeMain(init: std.process.Init) !void { i += 1; if (i >= args.len) return error.BadArgs; opts.load_path = args[i]; + } else if (std.mem.eql(u8, a, "--fs")) { + opts.fs = ""; + } else if (std.mem.startsWith(u8, a, "--fs=")) { + // `--fs=` and NEVER `--fs `, which is the one place this + // parser cannot follow --tty-toggle: --tty-toggle's argument is + // mandatory, so consuming the next word is unambiguous. `--fs` is + // useful bare, so a two-word form would make `pardes --fs README` + // mount at ./README and open no file — the flag would silently eat + // the FILE argument. One spelling, and it carries its own value. + opts.fs = a["--fs=".len..]; } else if (std.mem.eql(u8, a, "--nested")) { opts.nested = true; } else if (std.mem.eql(u8, a, "-h") or std.mem.eql(u8, a, "--help")) { @@ -241,6 +262,20 @@ fn parseCtrlKey(raw: []const u8) ?u21 { test { _ = @import("user_config.zig"); _ = @import("allocators.zig"); + _ = @import("fs_service.zig"); + // acme's control filesystem, both halves, and NOT their own b.addTest + // modules in build.zig the way temp_file/nested/fonts are: both reach + // src/pardes.zig (acmefs takes a *Pardes, fuse.zig speaks its Req/Reply), + // so a standalone module would have to re-wire ghostty-vt, tree-sitter, the + // themes and every option the core imports. This module already has them. + // + // fuse.zig genuinely needs its name here (nothing the core analyses reaches + // it — only the shells import it). acmefs.zig does not today, because + // pardes.zig re-exports it unconditionally; it is named anyway, because the + // day that re-export grows a comptime gate is the day 23 tests disappear in + // silence. That is the fonts.zig story above, told once already. + _ = @import("acmefs.zig"); + _ = @import("fuse.zig"); if (comptime pardes.platform == .tty) { _ = @import("tty/tty.zig"); // tty.zig calls the compositor only from its runtime loop, so merely -- cgit v1.3