diff options
Diffstat (limited to 'src/builtins.zig')
| -rw-r--r-- | src/builtins.zig | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/builtins.zig b/src/builtins.zig index b4447289..5a6b6ea9 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -133,6 +133,11 @@ pub const OutputTraits = struct { jumps: bool = false, commands: bool = false, doc: bool = false, + /// the buffer BECOMES an ordinary file once written (the New scratch, and a + /// real file, which is one already). Every other output buffer is a + /// RENDERING: Save writes its text out and the buffer stays what it is, + /// refillable and steppable, because a saved copy of a search is a copy of + /// a search and not the search. saves: bool = false, }; @@ -518,22 +523,27 @@ pub const ClipReplace = struct { // ---- panes and columns ---- +/// Write this pane's text out. A pane with a real file behind it writes THAT +/// file with no argument — acme's Put, what `:w<Tab>` has always meant — and +/// that is the only pane Save can serve without being told where. +/// +/// Everywhere else the path is REQUIRED, so a bare `Save` asks for one exactly +/// the way Find and Grep ask for a pattern: the tag input arms prefilled with +/// the pane's directory and Enter commits it. A terminal writes its plaintext +/// scrollback and stays a terminal; an output buffer writes its rows and stays +/// an output buffer, still refillable and still walked by n/N — with the one +/// exception the New scratch has always been, an empty buffer whose whole +/// purpose is to become the file you name (output traits: `saves`). +/// +/// Images and PDFs hold nothing of their own that is unwritten, so the word is +/// inert there and absent from their tag. pub const Save = struct { + pub const takes_arg = true; pub fn run(c: Ctx) void { - if (c.pane.file) |*f| { - 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) } }); - 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); + const path = std.mem.trim(u8, c.arg orelse "", " \t\r\n"); + if (path.len > 0) return c.p.saveTo(c.id, path); + if (c.pane.file) |file| if (file.output == null) return c.p.saveFile(c.id); + if (c.pane.file != null or c.pane.isTerminal()) c.p.startSavePrompt(c.pane); } }; |
