diff --git a/src/project_manager.zig b/src/project_manager.zig index 7e9a309..e302cce 100644 --- a/src/project_manager.zig +++ b/src/project_manager.zig @@ -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 { diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index 2a76c4d..67e9d8e 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -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;