feat: save and restore mainview state when switching projects
This commit is contained in:
parent
bbeba10fe5
commit
20129ea773
2 changed files with 47 additions and 7 deletions
|
|
@ -58,17 +58,35 @@ pub fn shutdown() void {
|
|||
pid.send(.{"shutdown"}) catch {};
|
||||
}
|
||||
|
||||
pub fn open(rel_project_directory: []const u8) (ProjectManagerError || FileSystemError || std.fs.File.OpenError || SetCwdError)!void {
|
||||
pub fn open(rel_project_directory: []const u8) (ProjectManagerError || FileSystemError || std.fs.File.OpenError || SetCwdError)!?[]const u8 {
|
||||
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const project_directory = std.fs.cwd().realpath(rel_project_directory, &path_buf) catch "(none)";
|
||||
const current_project = tp.env.get().str("project");
|
||||
if (std.mem.eql(u8, current_project, project_directory)) return;
|
||||
if (std.mem.eql(u8, current_project, project_directory)) return get_project_state(project_directory);
|
||||
if (!root.is_directory(project_directory)) return error.InvalidProjectDirectory;
|
||||
var dir = try std.fs.openDirAbsolute(project_directory, .{});
|
||||
try dir.setAsCwd();
|
||||
dir.close();
|
||||
tp.env.get().str_set("project", project_directory);
|
||||
return send(.{ "open", project_directory });
|
||||
try send(.{ "open", project_directory });
|
||||
return get_project_state(project_directory);
|
||||
}
|
||||
|
||||
const project_state_allocator = std.heap.c_allocator;
|
||||
var project_state_mutex: std.Thread.Mutex = .{};
|
||||
var project_state: ProjectStateMap = .empty;
|
||||
const ProjectStateMap = std.StringHashMapUnmanaged([]const u8);
|
||||
|
||||
fn get_project_state(project_directory: []const u8) ?[]const u8 {
|
||||
project_state_mutex.lock();
|
||||
defer project_state_mutex.unlock();
|
||||
return project_state.get(project_directory);
|
||||
}
|
||||
|
||||
pub fn store_state(project_directory: []const u8, state: []const u8) error{OutOfMemory}!void {
|
||||
project_state_mutex.lock();
|
||||
defer project_state_mutex.unlock();
|
||||
try project_state.put(project_state_allocator, try project_state_allocator.dupe(u8, project_directory), state);
|
||||
}
|
||||
|
||||
pub fn close(project_directory: []const u8) (ProjectManagerError || error{CloseCurrentProject})!void {
|
||||
|
|
|
|||
|
|
@ -356,7 +356,8 @@ const cmds = struct {
|
|||
pub const quit_without_saving_meta: Meta = .{ .description = "Quit without saving" };
|
||||
|
||||
pub fn open_project_cwd(self: *Self, _: Ctx) Result {
|
||||
try project_manager.open(".");
|
||||
if (try project_manager.open(".")) |state|
|
||||
try self.restore_state(state);
|
||||
if (self.top_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" });
|
||||
if (self.bottom_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" });
|
||||
}
|
||||
|
|
@ -366,7 +367,8 @@ const cmds = struct {
|
|||
var project_dir: []const u8 = undefined;
|
||||
if (!try ctx.args.match(.{tp.extract(&project_dir)}))
|
||||
return;
|
||||
try project_manager.open(project_dir);
|
||||
if (try project_manager.open(project_dir)) |state|
|
||||
try self.restore_state(state);
|
||||
const project = tp.env.get().str("project");
|
||||
tui.rdr().set_terminal_working_directory(project);
|
||||
if (self.top_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" });
|
||||
|
|
@ -394,7 +396,18 @@ const cmds = struct {
|
|||
if (!try ctx.args.match(.{tp.extract(&project_dir)}))
|
||||
return;
|
||||
try self.check_all_not_dirty();
|
||||
try project_manager.open(project_dir);
|
||||
|
||||
{
|
||||
var state_writer: std.Io.Writer.Allocating = .init(self.allocator);
|
||||
defer state_writer.deinit();
|
||||
try self.write_state(&state_writer.writer);
|
||||
try state_writer.writer.flush();
|
||||
const old_project = tp.env.get().str("project");
|
||||
try project_manager.store_state(old_project, try state_writer.toOwnedSlice());
|
||||
}
|
||||
|
||||
const project_state = try project_manager.open(project_dir);
|
||||
|
||||
try self.close_all_editors();
|
||||
self.delete_all_buffers();
|
||||
self.clear_find_in_files_results(.diagnostics);
|
||||
|
|
@ -402,11 +415,15 @@ const cmds = struct {
|
|||
try self.toggle_panel_view(filelist_view, false);
|
||||
self.buffer_manager.deinit();
|
||||
self.buffer_manager = Buffer.Manager.init(self.allocator);
|
||||
|
||||
const project = tp.env.get().str("project");
|
||||
tui.rdr().set_terminal_working_directory(project);
|
||||
if (project_state) |state| try self.restore_state(state);
|
||||
|
||||
if (self.top_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" });
|
||||
if (self.bottom_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" });
|
||||
tp.self_pid().send(.{ "cmd", "open_recent" }) catch return;
|
||||
if (project_state == null)
|
||||
tp.self_pid().send(.{ "cmd", "open_recent" }) catch return;
|
||||
}
|
||||
pub const change_project_meta: Meta = .{ .arguments = &.{.string} };
|
||||
|
||||
|
|
@ -1657,6 +1674,11 @@ fn read_restore_info(self: *Self) !void {
|
|||
try self.extract_state(&iter);
|
||||
}
|
||||
|
||||
fn restore_state(self: *Self, state: []const u8) !void {
|
||||
var iter = state;
|
||||
try self.extract_state(&iter);
|
||||
}
|
||||
|
||||
fn extract_state(self: *Self, iter: *[]const u8) !void {
|
||||
tp.trace(tp.channel.debug, .{ "mainview", "extract" });
|
||||
var editor_file_path: ?[]const u8 = undefined;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue