diff --git a/src/config.zig b/src/config.zig index 6468324..96b00c1 100644 --- a/src/config.zig +++ b/src/config.zig @@ -114,7 +114,6 @@ pub const WhitespaceMode = enum { leading, eol, tabs, - external, visible, full, none, diff --git a/src/project_manager.zig b/src/project_manager.zig index 48111ed..7e9a309 100644 --- a/src/project_manager.zig +++ b/src/project_manager.zig @@ -58,36 +58,17 @@ pub fn shutdown() void { pid.send(.{"shutdown"}) catch {}; } -pub fn open(rel_project_directory: []const u8) (ProjectManagerError || FileSystemError || std.fs.File.OpenError || SetCwdError)!?[]const u8 { +pub fn open(rel_project_directory: []const u8) (ProjectManagerError || FileSystemError || std.fs.File.OpenError || SetCwdError)!void { 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 get_project_state(project_directory); + if (std.mem.eql(u8, current_project, project_directory)) return; 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); - 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(std.array_list.Managed(u8)); - -fn get_project_state(project_directory: []const u8) ?[]const u8 { - project_state_mutex.lock(); - defer project_state_mutex.unlock(); - return if (project_state.get(project_directory)) |state| state.items else null; -} - -pub fn store_state(project_directory: []const u8, state: std.array_list.Managed(u8)) error{OutOfMemory}!void { - project_state_mutex.lock(); - defer project_state_mutex.unlock(); - if (project_state.fetchRemove(project_directory)) |old_state| old_state.value.deinit(); - try project_state.put(project_state_allocator, try project_state_allocator.dupe(u8, project_directory), state); + return send(.{ "open", project_directory }); } pub fn close(project_directory: []const u8) (ProjectManagerError || error{CloseCurrentProject})!void { diff --git a/src/tui/editor.zig b/src/tui/editor.zig index ddcda8f..09217e3 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -1562,18 +1562,6 @@ pub const Editor = struct { cell.cell.char.grapheme = c; } }, - .external => { - if (leading) { - if (get_whitespace_char(cell_type, next_cell_type)) |c| - cell.cell.char.grapheme = c; - } - if (cell_type == .eol) - cell.cell.char.grapheme = char.eol; - if (cell_type == .tab or cell_type == .extension) { - if (get_whitespace_char(cell_type, next_cell_type)) |c| - cell.cell.char.grapheme = c; - } - }, .visible => { if (get_whitespace_char(cell_type, next_cell_type)) |c| cell.cell.char.grapheme = c; @@ -1585,7 +1573,7 @@ pub const Editor = struct { else => "#", }; }, - .none => {}, + else => {}, } if (tab_error) { cell.set_style_fg(theme.editor_error); diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index 131e558..0f7d9d3 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -356,8 +356,7 @@ const cmds = struct { pub const quit_without_saving_meta: Meta = .{ .description = "Quit without saving" }; pub fn open_project_cwd(self: *Self, _: Ctx) Result { - if (try project_manager.open(".")) |state| - try self.restore_state(state); + try project_manager.open("."); if (self.top_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" }); if (self.bottom_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" }); } @@ -367,8 +366,7 @@ const cmds = struct { var project_dir: []const u8 = undefined; if (!try ctx.args.match(.{tp.extract(&project_dir)})) return; - if (try project_manager.open(project_dir)) |state| - try self.restore_state(state); + try project_manager.open(project_dir); const project = tp.env.get().str("project"); tui.rdr().set_terminal_working_directory(project); if (self.top_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" }); @@ -396,20 +394,7 @@ const cmds = struct { if (!try ctx.args.match(.{tp.extract(&project_dir)})) return; try self.check_all_not_dirty(); - - { - 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"); - var state_al = state_writer.toArrayList(); - const state = state_al.toManaged(self.allocator); - try project_manager.store_state(old_project, state); - } - - const project_state = try project_manager.open(project_dir); - + try project_manager.open(project_dir); try self.close_all_editors(); self.delete_all_buffers(); self.clear_find_in_files_results(.diagnostics); @@ -417,15 +402,11 @@ 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" }); - if (project_state == null) - tp.self_pid().send(.{ "cmd", "open_recent" }) catch return; + tp.self_pid().send(.{ "cmd", "open_recent" }) catch return; } pub const change_project_meta: Meta = .{ .arguments = &.{.string} }; @@ -1618,49 +1599,42 @@ fn create_home_split(self: *Self) !void { tui.resize(); } -pub const WriteStateError = error{ - OutOfMemory, - Stop, - WriteFailed, -}; +pub fn write_restore_info(self: *Self) void { + var sfa = std.heap.stackFallback(512, self.allocator); + const a = sfa.get(); + var meta: std.Io.Writer.Allocating = .init(a); + defer meta.deinit(); + const writer = &meta.writer; -pub fn write_restore_info(self: *Self) WriteStateError!void { - const file_name = root.get_restore_file_name() catch return; - var file = std.fs.createFileAbsolute(file_name, .{ .truncate = true }) catch return; - defer file.close(); - var buf: [32 + 1024]u8 = undefined; - var file_writer = file.writer(&buf); - const writer = &file_writer.interface; - - try self.write_state(writer); - try writer.flush(); -} - -pub fn write_state(self: *Self, writer: *std.Io.Writer) WriteStateError!void { if (self.get_active_editor()) |editor| { - try cbor.writeValue(writer, editor.file_path); + cbor.writeValue(writer, editor.file_path) catch return; editor.update_meta(); } else { - try cbor.writeValue(writer, null); + cbor.writeValue(writer, null) catch return; } if (tui.clipboard_get_history()) |clipboard| { - try cbor.writeArrayHeader(writer, clipboard.len); + cbor.writeArrayHeader(writer, clipboard.len) catch return; for (clipboard) |item| { - try cbor.writeArrayHeader(writer, 2); - try cbor.writeValue(writer, item.group); - try cbor.writeValue(writer, item.text); + cbor.writeArrayHeader(writer, 2) catch return; + cbor.writeValue(writer, item.group) catch return; + cbor.writeValue(writer, item.text) catch return; } } else { - try cbor.writeValue(writer, null); + cbor.writeValue(writer, null) catch return; } const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); - try buffer_manager.write_state(writer); + buffer_manager.write_state(writer) catch return; if (self.widgets.get("tabs")) |tabs_widget| if (tabs_widget.dynamic_cast(@import("status/tabs.zig").TabBar)) |tabs| - try tabs.write_state(writer); + tabs.write_state(writer) catch return; + + const file_name = root.get_restore_file_name() catch return; + var file = std.fs.createFileAbsolute(file_name, .{ .truncate = true }) catch return; + defer file.close(); + file.writeAll(meta.written()) catch return; } fn read_restore_info(self: *Self) !void { @@ -1673,40 +1647,31 @@ fn read_restore_info(self: *Self) !void { const size = try file.readAll(buf); var iter: []const u8 = buf[0..size]; - 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; - if (!try cbor.matchValue(iter, cbor.extract(&editor_file_path))) return error.MatchFilePathFailed; + if (!try cbor.matchValue(&iter, cbor.extract(&editor_file_path))) return error.Stop; tui.clipboard_clear_all(); - var len = try cbor.decodeArrayHeader(iter); + var len = try cbor.decodeArrayHeader(&iter); var prev_group: usize = 0; const clipboard_allocator = tui.clipboard_allocator(); while (len > 0) : (len -= 1) { - const len_ = try cbor.decodeArrayHeader(iter); - if (len_ != 2) return error.MatchClipboardArrayFailed; + const len_ = try cbor.decodeArrayHeader(&iter); + if (len_ != 2) return error.Stop; var group: usize = 0; var text: []const u8 = undefined; - if (!try cbor.matchValue(iter, cbor.extract(&group))) return error.MatchClipboardGroupFailed; - if (!try cbor.matchValue(iter, cbor.extract(&text))) return error.MatchClipboardTextFailed; + if (!try cbor.matchValue(&iter, cbor.extract(&group))) return error.Stop; + if (!try cbor.matchValue(&iter, cbor.extract(&text))) return error.Stop; if (prev_group != group) tui.clipboard_start_group(); prev_group = group; tui.clipboard_add_chunk(try clipboard_allocator.dupe(u8, text)); } - try self.buffer_manager.extract_state(iter); + try self.buffer_manager.extract_state(&iter); if (self.widgets.get("tabs")) |tabs_widget| if (tabs_widget.dynamic_cast(@import("status/tabs.zig").TabBar)) |tabs| - tabs.extract_state(iter) catch |e| { + tabs.extract_state(&iter) catch |e| { const logger = log.logger("mainview"); defer logger.deinit(); logger.print_err("mainview", "failed to restore tabs: {}", .{e}); @@ -1718,10 +1683,10 @@ fn extract_state(self: *Self, iter: *[]const u8) !void { send_buffer_did_open(self.allocator, buffer) catch {}; if (editor_file_path) |file_path| { - if (self.buffer_manager.get_buffer_for_file(file_path)) |_| - return tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_path } }); + try tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_path } }); + } else { + try tp.self_pid().send(.{ "cmd", "close_file" }); } - try tp.self_pid().send(.{ "cmd", "close_file" }); } fn send_buffer_did_open(allocator: std.mem.Allocator, buffer: *Buffer) !void { diff --git a/src/tui/tui.zig b/src/tui/tui.zig index a61f193..20e4b21 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -397,7 +397,7 @@ fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void { } if (try m.match(.{"restart"})) { - if (mainview()) |mv| try mv.write_restore_info(); + if (mainview()) |mv| mv.write_restore_info(); project_manager.shutdown(); self.final_exit = "restart"; return; @@ -1002,8 +1002,7 @@ const cmds = struct { .indent => .leading, .leading => .eol, .eol => .tabs, - .tabs => .external, - .external => .visible, + .tabs => .visible, .visible => .full, .full => .none, };