feat(buffers): add tracking of last modified and last used times for buffers
This commit is contained in:
parent
4dddadb46d
commit
efb3ab42fd
2 changed files with 40 additions and 17 deletions
|
@ -44,6 +44,9 @@ undo_history: ?*UndoNode = null,
|
||||||
redo_history: ?*UndoNode = null,
|
redo_history: ?*UndoNode = null,
|
||||||
curr_history: ?*UndoNode = null,
|
curr_history: ?*UndoNode = null,
|
||||||
|
|
||||||
|
mtime: i64,
|
||||||
|
utime: i64,
|
||||||
|
|
||||||
pub const EolMode = enum { lf, crlf };
|
pub const EolMode = enum { lf, crlf };
|
||||||
pub const EolModeTag = @typeInfo(EolMode).Enum.tag_type;
|
pub const EolModeTag = @typeInfo(EolMode).Enum.tag_type;
|
||||||
|
|
||||||
|
@ -1052,6 +1055,8 @@ pub fn create(allocator: Allocator) error{OutOfMemory}!*Self {
|
||||||
.allocator = self.arena.allocator(),
|
.allocator = self.arena.allocator(),
|
||||||
.external_allocator = allocator,
|
.external_allocator = allocator,
|
||||||
.root = try Node.new(self.allocator, &empty_leaf, &empty_leaf),
|
.root = try Node.new(self.allocator, &empty_leaf, &empty_leaf),
|
||||||
|
.mtime = std.time.milliTimestamp(),
|
||||||
|
.utime = std.time.milliTimestamp(),
|
||||||
};
|
};
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -1063,6 +1068,10 @@ pub fn deinit(self: *Self) void {
|
||||||
self.external_allocator.destroy(self);
|
self.external_allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_last_used_time(self: *Self) void {
|
||||||
|
self.utime = std.time.milliTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
fn new_file(self: *const Self, file_exists: *bool) error{OutOfMemory}!Root {
|
fn new_file(self: *const Self, file_exists: *bool) error{OutOfMemory}!Root {
|
||||||
file_exists.* = false;
|
file_exists.* = false;
|
||||||
return Leaf.new(self.allocator, "", true, false);
|
return Leaf.new(self.allocator, "", true, false);
|
||||||
|
@ -1142,6 +1151,7 @@ pub fn load_from_string_and_update(self: *Self, file_path: []const u8, s: []cons
|
||||||
self.last_save = self.root;
|
self.last_save = self.root;
|
||||||
self.last_save_eol_mode = self.file_eol_mode;
|
self.last_save_eol_mode = self.file_eol_mode;
|
||||||
self.file_exists = false;
|
self.file_exists = false;
|
||||||
|
self.mtime = std.time.milliTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const LoadFromFileError = error{
|
pub const LoadFromFileError = error{
|
||||||
|
@ -1213,12 +1223,14 @@ pub fn load_from_file_and_update(self: *Self, file_path: []const u8) LoadFromFil
|
||||||
self.file_eol_mode = eol_mode;
|
self.file_eol_mode = eol_mode;
|
||||||
self.file_utf8_sanitized = utf8_sanitized;
|
self.file_utf8_sanitized = utf8_sanitized;
|
||||||
self.last_save_eol_mode = eol_mode;
|
self.last_save_eol_mode = eol_mode;
|
||||||
|
self.mtime = std.time.milliTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_to_last_saved(self: *Self) void {
|
pub fn reset_to_last_saved(self: *Self) void {
|
||||||
if (self.last_save) |last_save| {
|
if (self.last_save) |last_save| {
|
||||||
self.store_undo(&[_]u8{}) catch {};
|
self.store_undo(&[_]u8{}) catch {};
|
||||||
self.root = last_save;
|
self.root = last_save;
|
||||||
|
self.mtime = std.time.milliTimestamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1319,6 +1331,7 @@ pub fn version(self: *const Self) usize {
|
||||||
|
|
||||||
pub fn update(self: *Self, root: Root) void {
|
pub fn update(self: *Self, root: Root) void {
|
||||||
self.root = root;
|
self.root = root;
|
||||||
|
self.mtime = std.time.milliTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store_undo(self: *Self, meta: []const u8) !void {
|
pub fn store_undo(self: *Self, meta: []const u8) !void {
|
||||||
|
@ -1369,6 +1382,7 @@ pub fn undo(self: *Self, meta: []const u8) error{Stop}![]const u8 {
|
||||||
self.curr_history = h;
|
self.curr_history = h;
|
||||||
self.root = h.root;
|
self.root = h.root;
|
||||||
self.push_redo(r);
|
self.push_redo(r);
|
||||||
|
self.mtime = std.time.milliTimestamp();
|
||||||
return h.meta;
|
return h.meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,5 +1394,6 @@ pub fn redo(self: *Self) error{Stop}![]const u8 {
|
||||||
self.curr_history = h;
|
self.curr_history = h;
|
||||||
self.root = h.root;
|
self.root = h.root;
|
||||||
self.push_undo(u);
|
self.push_undo(u);
|
||||||
|
self.mtime = std.time.milliTimestamp();
|
||||||
return h.meta;
|
return h.meta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,39 +23,47 @@ pub fn deinit(self: *Self) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_file(self: *Self, file_path: []const u8) Buffer.LoadFromFileError!*Buffer {
|
pub fn open_file(self: *Self, file_path: []const u8) Buffer.LoadFromFileError!*Buffer {
|
||||||
if (self.buffers.get(file_path)) |buffer| {
|
const buffer = if (self.buffers.get(file_path)) |buffer| buffer else blk: {
|
||||||
return buffer;
|
|
||||||
} else {
|
|
||||||
var buffer = try Buffer.create(self.allocator);
|
var buffer = try Buffer.create(self.allocator);
|
||||||
errdefer buffer.deinit();
|
errdefer buffer.deinit();
|
||||||
try buffer.load_from_file_and_update(file_path);
|
try buffer.load_from_file_and_update(file_path);
|
||||||
try self.buffers.put(self.allocator, try self.allocator.dupe(u8, file_path), buffer);
|
try self.buffers.put(self.allocator, try self.allocator.dupe(u8, file_path), buffer);
|
||||||
return buffer;
|
break :blk buffer;
|
||||||
}
|
};
|
||||||
|
buffer.update_last_used_time();
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_scratch(self: *Self, file_path: []const u8, content: []const u8) Buffer.LoadFromStringError!*Buffer {
|
pub fn open_scratch(self: *Self, file_path: []const u8, content: []const u8) Buffer.LoadFromStringError!*Buffer {
|
||||||
if (self.buffers.get(file_path)) |buffer| {
|
const buffer = if (self.buffers.get(file_path)) |buffer| buffer else blk: {
|
||||||
return buffer;
|
|
||||||
} else {
|
|
||||||
var buffer = try Buffer.create(self.allocator);
|
var buffer = try Buffer.create(self.allocator);
|
||||||
errdefer buffer.deinit();
|
errdefer buffer.deinit();
|
||||||
try buffer.load_from_string_and_update(file_path, content);
|
try buffer.load_from_string_and_update(file_path, content);
|
||||||
buffer.file_exists = true;
|
buffer.file_exists = true;
|
||||||
try self.buffers.put(self.allocator, try self.allocator.dupe(u8, file_path), buffer);
|
try self.buffers.put(self.allocator, try self.allocator.dupe(u8, file_path), buffer);
|
||||||
return buffer;
|
break :blk buffer;
|
||||||
}
|
};
|
||||||
|
buffer.update_last_used_time();
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn retire(self: *Self, buffer: *Buffer) void {
|
pub fn retire(_: *Self, buffer: *Buffer) void {
|
||||||
_ = self;
|
buffer.update_last_used_time();
|
||||||
_ = buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list(self: *Self, allocator: std.mem.Allocator) []*const Buffer {
|
pub fn list(self: *Self, allocator: std.mem.Allocator) error{OutOfMemory}![]*const Buffer {
|
||||||
_ = self;
|
var buffers: std.ArrayListUnmanaged([]*const Buffer) = .{};
|
||||||
_ = allocator;
|
var i = self.buffers.iterator();
|
||||||
unreachable;
|
while (i.next()) |kv|
|
||||||
|
(try buffers.addOne()).* = kv.value_ptr.*;
|
||||||
|
|
||||||
|
std.mem.sort(*Buffer, buffers.items, {}, struct {
|
||||||
|
fn less_fn(_: void, lhs: *Buffer, rhs: *Buffer) bool {
|
||||||
|
return lhs.mtime > rhs.mtime;
|
||||||
|
}
|
||||||
|
}.less_fn);
|
||||||
|
|
||||||
|
return buffers.toOwnedSlice(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dirty(self: *const Self) bool {
|
pub fn is_dirty(self: *const Self) bool {
|
||||||
|
|
Loading…
Add table
Reference in a new issue