feat(buffers): save/restore full editor state on buffer switch

This commit is contained in:
CJ van den Berg 2025-01-29 22:10:54 +01:00
parent b45b5910ee
commit e6e0301a78
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
3 changed files with 51 additions and 17 deletions

View file

@ -181,6 +181,7 @@ pub const CurSel = struct {
}
fn write(self: *const Self, writer: Buffer.MetaWriter) !void {
try cbor.writeArrayHeader(writer, 2);
try self.cursor.write(writer);
if (self.selection) |sel| {
try sel.write(writer);
@ -190,15 +191,21 @@ pub const CurSel = struct {
}
fn extract(self: *Self, iter: *[]const u8) !bool {
if (!try self.cursor.extract(iter)) return false;
var iter2 = iter.*;
if (try cbor.matchValue(&iter2, cbor.null_)) {
iter.* = iter2;
const len = cbor.decodeArrayHeader(&iter2) catch return false;
if (len != 2) return false;
if (!try self.cursor.extract(&iter2)) return false;
var iter3 = iter2;
if (try cbor.matchValue(&iter3, cbor.null_)) {
iter2 = iter3;
} else {
iter3 = iter2;
var sel: Selection = .{};
if (!try sel.extract(iter)) return false;
if (!try sel.extract(&iter3)) return false;
self.selection = sel;
iter2 = iter3;
}
iter.* = iter2;
return true;
}
@ -364,13 +371,23 @@ pub const Editor = struct {
try cbor.writeArrayHeader(writer, 0);
}
try self.view.write(writer);
try self.get_primary().cursor.write(writer);
var count_cursels: usize = 0;
for (self.cursels.items) |*cursel_| if (cursel_.*) |_| {
count_cursels += 1;
};
try cbor.writeArrayHeader(writer, count_cursels);
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
try cursel.write(writer);
};
}
pub fn extract_state(self: *Self, buf: []const u8, comptime op: enum { none, open_file }) !void {
tp.trace(tp.channel.debug, .{ "extract_state", self.file_path });
tp.trace(tp.channel.debug, tp.message{ .buf = buf });
var file_path: []const u8 = undefined;
var view_cbor: []const u8 = undefined;
var primary_cbor: []const u8 = undefined;
var cursels_cbor: []const u8 = undefined;
var clipboard: []const u8 = undefined;
var query: []const u8 = undefined;
var find_history: []const u8 = undefined;
@ -380,7 +397,7 @@ pub const Editor = struct {
tp.extract(&query),
tp.extract_cbor(&find_history),
tp.extract_cbor(&view_cbor),
tp.extract_cbor(&primary_cbor),
tp.extract_cbor(&cursels_cbor),
}))
return error.RestoreStateMatch;
if (op == .open_file)
@ -390,13 +407,22 @@ pub const Editor = struct {
if (!try self.view.extract(&view_cbor))
return error.RestoreView;
self.scroll_dest = self.view.row;
if (!try self.get_primary().cursor.extract(&primary_cbor))
return error.RestoreCursor;
var len = cbor.decodeArrayHeader(&find_history) catch return error.RestoryFindHistory;
if (cursels_cbor.len > 0)
self.clear_all_cursors();
var iter = cursels_cbor;
var len = cbor.decodeArrayHeader(&iter) catch return error.RestoreCurSels;
while (len > 0) : (len -= 1) {
var cursel: CurSel = .{};
if (!(cursel.extract(&iter) catch false)) break;
(try self.cursels.addOne()).* = cursel;
}
len = cbor.decodeArrayHeader(&find_history) catch return error.RestoreFindHistory;
while (len > 0) : (len -= 1) {
var value: []const u8 = undefined;
if (!(cbor.matchValue(&find_history, cbor.extract(&value)) catch return error.RestoryFindHistory))
return error.RestoryFindHistory;
if (!(cbor.matchValue(&find_history, cbor.extract(&value)) catch return error.RestoreFindHistory))
return error.RestoreFindHistory;
self.push_find_history(value);
}
self.clamp();
@ -433,7 +459,7 @@ pub const Editor = struct {
fn deinit(self: *Self) void {
var meta = std.ArrayList(u8).init(self.allocator);
defer meta.deinit();
self.write_state(meta.writer()) catch {};
if (self.buffer) |_| self.write_state(meta.writer()) catch {};
for (self.diagnostics.items) |*d| d.deinit(self.diagnostics.allocator);
self.diagnostics.deinit();
if (self.syntax) |syn| syn.destroy();
@ -568,6 +594,7 @@ pub const Editor = struct {
defer meta.deinit();
self.write_state(meta.writer()) catch {};
if (self.buffer) |b_mut| self.buffer_manager.retire(b_mut, meta.items);
self.cancel_all_selections();
self.buffer = null;
self.plane.erase();
self.plane.home();
@ -3809,7 +3836,6 @@ pub const Editor = struct {
const buffer_ = self.buffer;
if (buffer_) |buffer| if (buffer.is_dirty())
return tp.exit("unsaved changes");
self.cancel_all_selections();
try self.close();
if (buffer_) |buffer|
self.buffer_manager.close_buffer(buffer);
@ -3817,7 +3843,6 @@ pub const Editor = struct {
pub const close_file_meta = .{ .description = "Close file" };
pub fn close_file_without_saving(self: *Self, _: Context) Result {
self.cancel_all_selections();
const buffer_ = self.buffer;
if (buffer_) |buffer|
buffer.reset_to_last_saved();