From c3d0b84b7961ae26d2d654e7120821cc2d83d20d Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 24 Aug 2026 10:56:05 -0300 Subject: host: the core owns the event loop; every platform becomes a vtable of optional methods --- src/builtins.zig | 60 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 18 deletions(-) (limited to 'src/builtins.zig') diff --git a/src/builtins.zig b/src/builtins.zig index ca3cf931..b4447289 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -520,38 +520,37 @@ pub const ClipReplace = struct { pub const Save = struct { pub fn run(c: Ctx) void { - // an output buffer has no file behind it — nothing to write if (c.pane.file) |*f| { - if (!output_pane.fileTraits(f.output).saves) return; + if (f.output != null) { + // an unsavable output (search/help) has nothing to write; a + // scratch (savable output) asks for a path and becomes a file + if (output_pane.fileTraits(f.output).saves) c.p.startSavePrompt(c.pane); + return; + } + // a real file: write in place, and this edit is now on disk c.p.emit(.{ .save_file = .{ .pane = @intCast(c.id) } }); - // ...and this edit is now the one on disk. See File.saved_revision - // for why the mark goes here rather than after the write. f.saved_revision = f.revision; + return; } + // a terminal: write its plaintext scrollback to a prompted path + if (c.pane.isTerminal()) c.p.startSavePrompt(c.pane); } }; -/// Ask the native shell for an atomically-created empty temporary file. The -/// pane and its lifetime serial are the placement token: by the time IO -/// finishes another column may be active, or this slot may even have been -/// reused, and neither is permission to put the document somewhere else. +/// An empty scratch buffer below the calling pane, inheriting its directory. +/// No file exists yet, so Save asks for a path prefilled with that directory +/// and, once written, the buffer becomes an ordinary file pane. pub const New = struct { + pub const output: OutputTraits = .{ .name = config.scratch_buffer, .doc = true, .saves = true }; pub fn run(c: Ctx) void { - if (c.p.freeSlot() == null) return; - c.p.emit(.{ .new_file = .{ .pane = @intCast(c.id), .serial = c.pane.serial } }); + c.p.newScratchBelow(c.id); } }; +/// The same empty scratch, opened in a fresh column beside the calling pane. pub const Newcol = struct { pub fn run(c: Ctx) void { - const free = c.p.freeSlot() orelse return; - if (!c.p.layoutCanSplitColumn(c.id)) return; - const nt = c.p.newShell(free, "") catch return; - nt.greet = true; - // The shared preflight above is the complete geometry refusal set. - // Pane creation does not alter layout, so the same split is infallible. - std.debug.assert(c.p.layoutSplitColumn(c.id, free, false)); - c.p.active = free; + c.p.newScratchColumn(c.id); } }; @@ -601,6 +600,22 @@ pub const Delcol = struct { } }; +/// A shell in the calling pane's directory, raw from the first frame. On every +/// pane's tagline: the fast path from wherever you are to a prompt there. +pub const Newtty = struct { + pub fn run(c: Ctx) void { + c.p.spawnTty(c.id); + } +}; + +/// Fold the active pane's column into the one on its right, keeping its panes. +/// The horizontal mirror of the vertical stacking `New` does. +pub const Joincol = struct { + pub fn run(c: Ctx) void { + c.p.joinCol(); + } +}; + pub const Tutor = struct { pub fn run(c: Ctx) void { const free = c.p.freeSlot() orelse return; @@ -633,6 +648,15 @@ pub const Config = struct { } }; +/// This build's version and what changed to reach it, printed into an output +/// buffer the same way Config prints the live settings. +pub const Changelog = struct { + pub const output: OutputTraits = .{ .name = config.changelog_buffer }; + pub fn run(c: Ctx) void { + output_pane.openChangelog(c.p, c.id) catch |err| c.p.reportError(c.id, "changelog", err); + } +}; + /// Source code for the concrete backend implementation of a Panel*/scene /// effect. The bytes are embedded at build time, so this works from an /// installed executable rather than depending on a source checkout. -- cgit v1.3