diff options
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/src/main.zig b/src/main.zig index 08beae86..b8cb6b2d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -93,15 +93,30 @@ const help_text = \\ a frontend can say which session it wants. One \\ path component: no '/' and nothing empty \\ --attach become a frontend of the one detached session - \\ that is running: draw its screen, send it input, - \\ fork its pane shells. Several frontends may be - \\ attached at once and all see the same screen + \\ that is running: draw its screen and send it + \\ input, and nothing else — the session owns its + \\ pane shells, its files and its watches. Works in + \\ both the terminal and the SDL window build. + \\ Several frontends may be attached at once and all + \\ see the same screen \\ --attach=<name> ...of the session called <name>, which is what to \\ use when more than one is running \\ -h, --help show this help and exit + \\ --version print the version and exit \\ ; +/// Built at COMPTIME, because both halves are: `version` comes out of +/// `build.zig.zon` through the options module and `commit` out of `git` at +/// configure time, so there is nothing here to format at runtime and no buffer +/// to size. The commit is in parentheses when there is one and absent +/// otherwise — a build from a tarball says `pardes 0.0.1` and is not lying +/// about a revision it never had. See `pardes.version`/`pardes.commit`. +const version_text = if (pardes.commit) |c| + "pardes " ++ pardes.version ++ " (" ++ c ++ ")\n" +else + "pardes " ++ pardes.version ++ "\n"; + const nested_text = \\pardes: this shell is already inside pardes, and a pardes inside a pardes \\is spicy. Name a file or a directory and the outer session opens it, or @@ -129,9 +144,10 @@ fn emscriptenMain(argc: c_int, argv: [*]?[*:0]u8) callconv(.c) c_int { return 0; } -// no argv in the browser: options stay default, state comes from the dump +// no argv in the browser: options stay default, state comes from the dump, and +// there is no session to attach to — a browser tab has no unix socket. fn webMain() !void { - try @import("gui/gui.zig").run(.{}); + try @import("gui/gui.zig").run(.{}, .{}, null); } fn nativeMain(init: std.process.Init) !void { @@ -159,8 +175,8 @@ fn nativeMain(init: std.process.Init) !void { // free to mean "the default name" the way opts.fs uses it for a directory. var detach: ?[]const u8 = null; // ...and `--attach[=<name>]`, the same shape: null when it was not given, - // and the empty string means "the one session there is" (tty.zig - // `sessionName`) rather than a session with no name. + // and the empty string means "the one session there is" + // (detached_client.resolve) rather than a session with no name. var attach: ?[]const u8 = null; // Kept RAW until every flag is parsed: classifying it means chdir'ing into // a directory and recording nothing, and the nested client below still @@ -216,6 +232,9 @@ fn nativeMain(init: std.process.Init) !void { } else if (std.mem.eql(u8, a, "-h") or std.mem.eql(u8, a, "--help")) { try std.Io.File.stdout().writeStreamingAll(init.io, help_text); return; + } else if (std.mem.eql(u8, a, "--version")) { + try std.Io.File.stdout().writeStreamingAll(init.io, version_text); + return; } else if (a.len > 0 and a[0] != '-' and positional == null) { positional = a; } else { @@ -285,6 +304,19 @@ fn nativeMain(init: std.process.Init) !void { // reading. Refused rather than resolved by declaration order, which would // silently drop whichever flag lost. if (detach != null and attach != null) return error.BadArgs; + // `--fs` mounts the acme control filesystem, and only a LOCAL session has + // one: `fs_service.start` is called inside tty.zig's `localSession` and + // gui.zig's equivalent, both of which an `--attach` skips entirely, and + // `detached/server.zig` never reads `opts.fs` at all. So `--fs` with either + // of these was parsed, stored, and then served by nobody. + // + // Refused for the same reason as the line above, and it is the stronger + // case: a contradiction is at least visible, whereas a silently dropped + // mount is invisible until someone waits for a directory that will never + // appear. Serving it instead would mean mounting FUSE in the detached core, + // which is a feature rather than a fix — `push_fs_reply` is one of the five + // host methods that core deliberately leaves null (docs/detached.md). + if (opts.fs != null and (detach != null or attach != null)) return error.BadArgs; // `--detach` replaces the frontend rather than choosing among them: the // core runs here, with no terminal, and the frontends are elsewhere on a // socket (src/detached/). It is checked before `platform` because it is not @@ -300,15 +332,18 @@ fn nativeMain(init: std.process.Init) !void { try std.fmt.allocPrint(arena, "{d}", .{@as(u32, @intCast(std.c.getpid()))}); return @import("detached/server.zig").run(init, opts, named); } - // A frontend is a SHELL, and only the tty one knows how to be one today. - // Comptime-folded, so a tty build carries none of this. - if (attach != null and pardes.platform != .tty) { - try std.Io.File.stderr().writeStreamingAll(init.io, "pardes: --attach needs the tty shell\n"); + // A frontend is a SHELL, and the two native ones — a terminal and an SDL + // window — both know how to be one. The browser has no unix socket to + // reach a session over and the AppKit shell is entered by its own host + // rather than through this file, so neither is wired for it; the check is + // comptime-folded, so a tty or gui build carries none of it. + if (attach != null and pardes.platform != .tty and pardes.platform != .gui) { + try std.Io.File.stderr().writeStreamingAll(init.io, "pardes: --attach needs the tty or gui shell\n"); std.process.exit(1); } switch (pardes.platform) { .tty => try @import("tty/tty.zig").run(init, opts, attach), - .gui => try @import("gui/gui.zig").run(init, opts), + .gui => try @import("gui/gui.zig").run(init, opts, attach), // Every other shell is entered by its host and never links this file // at all: the browser through src/web.zig, the macOS app through // src/macos.zig, and the ESP32-P4 firmware through src/esp32p4/app.zig, |
