From 886a2582a3ce3d87b4b22d31eb552206e0421b05 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 5 Aug 2025 13:42:19 +0200 Subject: [PATCH] fix: re-write save_as to work properly with multiple buffers --- src/tui/editor.zig | 17 ----------------- src/tui/mainview.zig | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/tui/editor.zig b/src/tui/editor.zig index f6943c7..09e232c 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -722,15 +722,6 @@ pub const Editor = struct { self.update_event() catch {}; } - fn save_as(self: *Self, file_path: []const u8) !void { - if (self.buffer) |b_mut| try b_mut.store_to_file_and_clean(file_path); - if (self.file_path) |old_file_path| self.allocator.free(old_file_path); - self.file_path = try self.allocator.dupe(u8, file_path); - try self.send_editor_save(self.file_path.?); - self.last.dirty = false; - self.update_event() catch {}; - } - pub fn push_cursor(self: *Self) !void { const primary = self.cursels.getLastOrNull() orelse CurSel{} orelse CurSel{}; (try self.cursels.addOne(self.allocator)).* = primary; @@ -4950,14 +4941,6 @@ pub const Editor = struct { } pub const save_file_without_formatting_meta: Meta = .{ .description = "Save file without formatting" }; - pub fn save_file_as(self: *Self, ctx: Context) Result { - var file_path: []const u8 = undefined; - if (ctx.args.match(.{tp.extract(&file_path)}) catch false) { - try self.save_as(file_path); - } else return error.InvalidSafeFileAsArgument; - } - pub const save_file_as_meta: Meta = .{ .arguments = &.{.string} }; - pub fn close_file(self: *Self, _: Context) Result { const buffer_ = self.buffer; if (buffer_) |buffer| if (buffer.is_dirty()) diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index b0c2c03..0b92e31 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -564,6 +564,48 @@ const cmds = struct { } pub const create_new_file_meta: Meta = .{ .description = "New file" }; + pub fn save_file_as(self: *Self, ctx: Ctx) Result { + var file_path: []const u8 = undefined; + if (!(ctx.args.match(.{tp.extract(&file_path)}) catch false)) + return error.InvalidSafeFileAsArgument; + + if (self.get_active_editor()) |editor| { + const buffer = editor.buffer orelse return; + var content = std.ArrayListUnmanaged(u8).empty; + defer content.deinit(self.allocator); + try buffer.root.store(content.writer(self.allocator), buffer.file_eol_mode); + + var existing = false; + if (self.buffer_manager.get_buffer_for_file(file_path)) |new_buffer| { + if (new_buffer.is_dirty()) + return tp.exit("save as would overwrite unsaved changes"); + if (buffer == new_buffer) + return tp.exit("same file"); + existing = true; + } + try self.create_editor(); + try command.executeName("open_scratch_buffer", command.fmt(.{ + file_path, + "", + buffer.file_type_name, + })); + if (self.get_active_editor()) |new_editor| { + const new_buffer = new_editor.buffer orelse return; + if (existing) new_editor.update_buf(new_buffer.root) catch {}; // store an undo point + try new_buffer.reset_from_string_and_update(content.items); + new_buffer.mark_not_ephemeral(); + new_buffer.mark_dirty(); + new_editor.clamp(); + new_editor.update_buf(new_buffer.root) catch {}; + tui.need_render(); + } + try command.executeName("save_file", .{}); + if (buffer.is_ephemeral() and !buffer.is_dirty()) + _ = self.buffer_manager.close_buffer(buffer); + } + } + pub const save_file_as_meta: Meta = .{ .arguments = &.{.string} }; + pub fn delete_buffer(self: *Self, ctx: Ctx) Result { var file_path: []const u8 = undefined; if (!(ctx.args.match(.{tp.extract(&file_path)}) catch false))