diff --git a/build.zig.zon b/build.zig.zon index e5e8458..609206b 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -16,8 +16,8 @@ .hash = "1220220dbc7fe91c1c54438193ca765cebbcb7d58f35cdcaee404a9d2245a42a4362", }, .thespian = .{ - .url = "https://github.com/neurocyte/thespian/archive/3ace3163087a0260b30e2c420de76235dd82451f.tar.gz", - .hash = "1220ffbfff37c24b68424a3c9223cf57daed5debdbb6b7751a36b9dca318825cff4c", + .url = "https://github.com/neurocyte/thespian/archive/f1a89bdf9d9fac2cd7d6c1479e5bc99c8dd4c904.tar.gz", + .hash = "1220f1f69aaad041ca96e5a06fb14ff510c3775d809a37a83b8651e7f0f71be8deaf", }, .themes = .{ .url = "https://github.com/neurocyte/flow-themes/releases/download/master-15e8cad1619429bf2547a6819b5b999510d5c1e5/flow-themes.tar.gz", diff --git a/src/LSP.zig b/src/LSP.zig index bc92919..f23d2f4 100644 --- a/src/LSP.zig +++ b/src/LSP.zig @@ -11,9 +11,8 @@ const Self = @This(); const module_name = @typeName(Self); const sp_tag = "child"; const debug_lsp = true; -pub const Error = error{ OutOfMemory, Exit }; -pub fn open(a: std.mem.Allocator, project: []const u8, cmd: tp.message) Error!Self { +pub fn open(a: std.mem.Allocator, project: []const u8, cmd: tp.message) !Self { return .{ .a = a, .pid = try Process.create(a, project, cmd) }; } @@ -27,23 +26,23 @@ pub fn term(self: *Self) void { self.pid.deinit(); } -pub fn send_request(self: Self, a: std.mem.Allocator, method: []const u8, m: anytype) error{Exit}!tp.message { +pub fn send_request(self: Self, a: std.mem.Allocator, method: []const u8, m: anytype) !tp.message { // const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".send_request" }); // defer frame.deinit(); var cb = std.ArrayList(u8).init(self.a); defer cb.deinit(); - cbor.writeValue(cb.writer(), m) catch |e| return tp.exit_error(e); - return self.pid.call(a, std.time.ns_per_s / 2, .{ "REQ", method, cb.items }) catch |e| return tp.exit_error(e); + try cbor.writeValue(cb.writer(), m); + return self.pid.call(a, std.time.ns_per_s / 2, .{ "REQ", method, cb.items }); } -pub fn send_notification(self: Self, method: []const u8, m: anytype) tp.result { +pub fn send_notification(self: Self, method: []const u8, m: anytype) !void { var cb = std.ArrayList(u8).init(self.a); defer cb.deinit(); - cbor.writeValue(cb.writer(), m) catch |e| return tp.exit_error(e); + try cbor.writeValue(cb.writer(), m); return self.send_notification_raw(method, cb.items); } -pub fn send_notification_raw(self: Self, method: []const u8, cb: []const u8) tp.result { +pub fn send_notification_raw(self: Self, method: []const u8, cb: []const u8) !void { return self.pid.send(.{ "NTFY", method, cb }); } @@ -67,7 +66,7 @@ const Process = struct { const Receiver = tp.Receiver(*Process); - pub fn create(a: std.mem.Allocator, project: []const u8, cmd: tp.message) Error!tp.pid { + pub fn create(a: std.mem.Allocator, project: []const u8, cmd: tp.message) !tp.pid { var tag: []const u8 = undefined; if (try cmd.match(.{tp.extract(&tag)})) { // @@ -92,7 +91,7 @@ const Process = struct { .requests = std.AutoHashMap(i32, tp.pid).init(a), .sp_tag = try sp_tag_.toOwnedSliceSentinel(0), }; - return tp.spawn_link(self.a, self, Process.start, self.tag) catch |e| tp.exit_error(e); + return tp.spawn_link(self.a, self, Process.start, self.tag); } fn deinit(self: *Process) void { @@ -126,17 +125,21 @@ const Process = struct { const frame = tracy.initZone(@src(), .{ .name = module_name ++ " start" }); defer frame.deinit(); _ = tp.set_trap(true); - self.sp = tp.subprocess.init(self.a, self.cmd, self.sp_tag, .Pipe) catch |e| return tp.exit_error(e); + self.sp = tp.subprocess.init(self.a, self.cmd, self.sp_tag, .Pipe) catch |e| return tp.exit_error(e, @errorReturnTrace()); tp.receive(&self.receiver); var log_file_path = std.ArrayList(u8).init(self.a); defer log_file_path.deinit(); - const state_dir = root.get_state_dir() catch |e| return tp.exit_error(e); - log_file_path.writer().print("{s}/lsp-{s}.log", .{ state_dir, self.tag }) catch |e| return tp.exit_error(e); - self.log_file = std.fs.createFileAbsolute(log_file_path.items, .{ .truncate = true }) catch |e| return tp.exit_error(e); + const state_dir = root.get_state_dir() catch |e| return tp.exit_error(e, @errorReturnTrace()); + log_file_path.writer().print("{s}/lsp-{s}.log", .{ state_dir, self.tag }) catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.log_file = std.fs.createFileAbsolute(log_file_path.items, .{ .truncate = true }) catch |e| return tp.exit_error(e, @errorReturnTrace()); } fn receive(self: *Process, from: tp.pid_ref, m: tp.message) tp.result { + return self.receive_safe(from, m) catch |e| return tp.exit_error(e, @errorReturnTrace()); + } + + fn receive_safe(self: *Process, from: tp.pid_ref, m: tp.message) !void { const frame = tracy.initZone(@src(), .{ .name = module_name }); defer frame.deinit(); errdefer self.deinit(); @@ -146,9 +149,9 @@ const Process = struct { var code: u32 = 0; if (try m.match(.{ "REQ", tp.extract(&method), tp.extract(&bytes) })) { - self.send_request(from, method, bytes) catch |e| return tp.exit_error(e); + try self.send_request(from, method, bytes); } else if (try m.match(.{ "NTFY", tp.extract(&method), tp.extract(&bytes) })) { - self.send_notification(method, bytes) catch |e| return tp.exit_error(e); + try self.send_notification(method, bytes); } else if (try m.match(.{"close"})) { self.write_log("### LSP close ###\n", .{}); try self.close(); @@ -156,9 +159,9 @@ const Process = struct { self.write_log("### LSP terminated ###\n", .{}); try self.term(); } else if (try m.match(.{ self.sp_tag, "stdout", tp.extract(&bytes) })) { - self.handle_output(bytes) catch |e| return tp.exit_error(e); + try self.handle_output(bytes); } else if (try m.match(.{ self.sp_tag, "term", tp.extract(&err), tp.extract(&code) })) { - self.handle_terminated(err, code) catch |e| return tp.exit_error(e); + try self.handle_terminated(err, code); } else if (try m.match(.{ self.sp_tag, "stderr", tp.extract(&bytes) })) { self.write_log("{s}\n", .{bytes}); } else if (try m.match(.{ "exit", "normal" })) { diff --git a/src/Project.zig b/src/Project.zig index bdc1989..6913b51 100644 --- a/src/Project.zig +++ b/src/Project.zig @@ -132,7 +132,7 @@ pub fn request_recent_files(self: *Self, from: tp.pid_ref, max: usize) error{ Ou } } -fn simple_query_recent_files(self: *Self, from: tp.pid_ref, max: usize, query: []const u8) error{ OutOfMemory, Exit }!usize { +fn simple_query_recent_files(self: *Self, from: tp.pid_ref, max: usize, query: []const u8) error{Exit}!usize { var i: usize = 0; defer from.send(.{ "PRJ", "recent_done", query }) catch {}; for (self.files.items) |file| { @@ -155,12 +155,15 @@ pub fn query_recent_files(self: *Self, from: tp.pid_ref, max: usize, query: []co return self.simple_query_recent_files(from, max, query); defer from.send(.{ "PRJ", "recent_done", query }) catch {}; - var searcher = try fuzzig.Ascii.init( + var searcher = fuzzig.Ascii.init( self.a, std.fs.max_path_bytes, // haystack max size std.fs.max_path_bytes, // needle max size .{ .case_sensitive = false }, - ); + ) catch |e| switch (e) { + error.OutOfMemory => @panic("OOM in fussiz.Ascii.init"), + else => |e_| return e_, + }; defer searcher.deinit(); const Match = struct { @@ -251,14 +254,14 @@ pub fn get_mru_position(self: *Self, from: tp.pid_ref, file_path: []const u8) !v } } -pub fn did_open(self: *Self, file_path: []const u8, file_type: []const u8, language_server: []const u8, version: usize, text: []const u8) tp.result { +pub fn did_open(self: *Self, file_path: []const u8, file_type: []const u8, language_server: []const u8, version: usize, text: []const u8) !void { self.update_mru(file_path, 0, 0) catch {}; - const lsp = self.get_lsp(language_server) catch |e| return tp.exit_error(e); + const lsp = try self.get_lsp(language_server); if (!self.file_language_server.contains(file_path)) { - const key = self.a.dupe(u8, file_path) catch |e| return tp.exit_error(e); - self.file_language_server.put(key, lsp) catch |e| return tp.exit_error(e); + const key = try self.a.dupe(u8, file_path); + try self.file_language_server.put(key, lsp); } - const uri = self.make_URI(file_path) catch |e| return tp.exit_error(e); + const uri = try self.make_URI(file_path); defer self.a.free(uri); try lsp.send_notification("textDocument/didOpen", .{ .textDocument = .{ .uri = uri, .languageId = file_type, .version = version, .text = text }, @@ -267,7 +270,7 @@ pub fn did_open(self: *Self, file_path: []const u8, file_type: []const u8, langu pub fn did_change(self: *Self, file_path: []const u8, version: usize, root_dst_addr: usize, root_src_addr: usize) !void { const lsp = try self.get_file_lsp(file_path); - const uri = self.make_URI(file_path) catch |e| return tp.exit_error(e); + const uri = try self.make_URI(file_path); defer self.a.free(uri); const root_dst: Buffer.Root = if (root_dst_addr == 0) return else @ptrFromInt(root_dst_addr); @@ -359,18 +362,18 @@ fn scan_char(chars: []const u8, lines: *usize, char: u8, last_offset: ?*usize) v } } -pub fn did_save(self: *Self, file_path: []const u8) tp.result { +pub fn did_save(self: *Self, file_path: []const u8) !void { const lsp = try self.get_file_lsp(file_path); - const uri = self.make_URI(file_path) catch |e| return tp.exit_error(e); + const uri = try self.make_URI(file_path); defer self.a.free(uri); try lsp.send_notification("textDocument/didSave", .{ .textDocument = .{ .uri = uri }, }); } -pub fn did_close(self: *Self, file_path: []const u8) tp.result { +pub fn did_close(self: *Self, file_path: []const u8) !void { const lsp = try self.get_file_lsp(file_path); - const uri = self.make_URI(file_path) catch |e| return tp.exit_error(e); + const uri = try self.make_URI(file_path); defer self.a.free(uri); try lsp.send_notification("textDocument/didClose", .{ .textDocument = .{ .uri = uri }, @@ -379,7 +382,7 @@ pub fn did_close(self: *Self, file_path: []const u8) tp.result { pub fn goto_definition(self: *Self, from: tp.pid_ref, file_path: []const u8, row: usize, col: usize) !void { const lsp = try self.get_file_lsp(file_path); - const uri = self.make_URI(file_path) catch |e| return tp.exit_error(e); + const uri = try self.make_URI(file_path); defer self.a.free(uri); const response = try lsp.send_request(self.a, "textDocument/definition", .{ .textDocument = .{ .uri = uri }, @@ -454,7 +457,7 @@ fn navigate_to_location_link(_: *Self, from: tp.pid_ref, location_link: []const pub fn completion(self: *Self, _: tp.pid_ref, file_path: []const u8, row: usize, col: usize) !void { const lsp = try self.get_file_lsp(file_path); - const uri = self.make_URI(file_path) catch |e| return tp.exit_error(e); + const uri = try self.make_URI(file_path); defer self.a.free(uri); const response = try lsp.send_request(self.a, "textDocument/completion", .{ .textDocument = .{ .uri = uri }, @@ -613,7 +616,7 @@ pub fn show_message(_: *Self, _: tp.pid_ref, params_cb: []const u8) !void { logger.print("{s}", .{msg}); } -fn send_lsp_init_request(self: *Self, lsp: LSP, project_path: []const u8, project_basename: []const u8, project_uri: []const u8) error{Exit}!tp.message { +fn send_lsp_init_request(self: *Self, lsp: LSP, project_path: []const u8, project_basename: []const u8, project_uri: []const u8) !tp.message { return lsp.send_request(self.a, "initialize", .{ .processId = if (builtin.os.tag == .linux) std.os.linux.getpid() else null, .rootPath = project_path, diff --git a/src/diff.zig b/src/diff.zig index f35f20d..8e4d61d 100644 --- a/src/diff.zig +++ b/src/diff.zig @@ -7,7 +7,6 @@ const cbor = @import("cbor"); const Self = @This(); const module_name = @typeName(Self); -pub const Error = error{ OutOfMemory, Exit }; pub const Kind = enum { insert, delete }; pub const Edit = struct { @@ -19,7 +18,7 @@ pub const Edit = struct { pid: ?tp.pid, -pub fn create() Error!Self { +pub fn create() !Self { return .{ .pid = try Process.create() }; } @@ -39,14 +38,14 @@ const Process = struct { const Receiver = tp.Receiver(*Process); const outer_a = std.heap.page_allocator; - pub fn create() Error!tp.pid { + pub fn create() !tp.pid { const self = try outer_a.create(Process); self.* = .{ .arena = std.heap.ArenaAllocator.init(outer_a), .a = self.arena.allocator(), .receiver = Receiver.init(Process.receive, self), }; - return tp.spawn_link(self.a, self, Process.start, module_name) catch |e| tp.exit_error(e); + return tp.spawn_link(self.a, self, Process.start, module_name); } fn start(self: *Process) tp.result { @@ -67,7 +66,7 @@ const Process = struct { var root_src: usize = 0; return if (try m.match(.{ "D", tp.extract(&cb), tp.extract(&root_dst), tp.extract(&root_src) })) - self.diff(from, cb, root_dst, root_src) catch |e| tp.exit_error(e) + self.diff(from, cb, root_dst, root_src) catch |e| tp.exit_error(e, @errorReturnTrace()) else if (try m.match(.{"shutdown"})) tp.exit_normal(); } diff --git a/src/location_history.zig b/src/location_history.zig index a6a0ee3..951ba01 100644 --- a/src/location_history.zig +++ b/src/location_history.zig @@ -3,7 +3,6 @@ const tp = @import("thespian"); const Self = @This(); const module_name = @typeName(Self); -pub const Error = error{ OutOfMemory, Exit }; pid: ?tp.pid, @@ -17,7 +16,7 @@ pub const Selection = struct { end: Cursor = Cursor{}, }; -pub fn create() Error!Self { +pub fn create() !Self { return .{ .pid = try Process.create() }; } @@ -46,7 +45,7 @@ const Process = struct { selection: ?Selection = null, }; - pub fn create() Error!tp.pid { + pub fn create() !tp.pid { const self = try outer_a.create(Process); self.* = .{ .arena = std.heap.ArenaAllocator.init(outer_a), @@ -55,7 +54,7 @@ const Process = struct { .forwards = std.ArrayList(Entry).init(self.a), .receiver = Receiver.init(Process.receive, self), }; - return tp.spawn_link(self.a, self, Process.start, module_name) catch |e| tp.exit_error(e); + return tp.spawn_link(self.a, self, Process.start, module_name); } fn start(self: *Process) tp.result { @@ -87,6 +86,10 @@ const Process = struct { } fn receive(self: *Process, from: tp.pid_ref, m: tp.message) tp.result { + self.receive_safe(from, m) catch |e| return tp.exit_error(e, @errorReturnTrace()); + } + + fn receive_safe(self: *Process, from: tp.pid_ref, m: tp.message) !void { errdefer self.deinit(); var c: Cursor = .{}; @@ -106,9 +109,9 @@ const Process = struct { tp.exit_normal(); } - fn update(self: *Process, entry_: Entry) tp.result { + fn update(self: *Process, entry_: Entry) !void { const entry: Entry = .{ - .file_path = self.a.dupe(u8, entry_.file_path) catch |e| return tp.exit_error(e), + .file_path = try self.a.dupe(u8, entry_.file_path), .cursor = entry_.cursor, .selection = entry_.selection, }; @@ -129,7 +132,7 @@ const Process = struct { self.a.free(top.file_path); tp.trace(tp.channel.all, tp.message.fmt(.{ "location", "forward", entry.file_path, entry.cursor.row, entry.cursor.col, self.backwards.items.len, self.forwards.items.len })); } else if (self.current) |current| { - self.backwards.append(current) catch |e| return tp.exit_error(e); + try self.backwards.append(current); tp.trace(tp.channel.all, tp.message.fmt(.{ "location", "new", current.file_path, current.cursor.row, current.cursor.col, self.backwards.items.len, self.forwards.items.len })); self.clear_forwards(); } diff --git a/src/log.zig b/src/log.zig index 1725d9e..d9c0210 100644 --- a/src/log.zig +++ b/src/log.zig @@ -28,7 +28,7 @@ pub fn spawn(ctx: *tp.context, a: std.mem.Allocator, env: ?*const tp.env) !tp.pi fn start(args: StartArgs) tp.result { _ = tp.set_trap(true); - var this = Self.init(args) catch |e| return tp.exit_error(e); + var this = Self.init(args) catch |e| return tp.exit_error(e, @errorReturnTrace()); errdefer this.deinit(); tp.receive(&this.receiver); } @@ -135,15 +135,27 @@ pub const Logger = struct { error.Exit => { const msg_: tp.message = .{ .buf = tp.error_message() }; var msg__: []const u8 = undefined; - if (!(msg_.match(.{ "exit", tp.extract(&msg__) }) catch false)) + var trace__: []const u8 = ""; + if (msg_.match(.{ "exit", tp.extract(&msg__) }) catch false) { + // + } else if (msg_.match(.{ "exit", tp.extract(&msg__), tp.extract(&trace__) }) catch false) { + // + } else { msg__ = msg_.buf; + } if (msg__.len > buf.len) { self.proc.send(.{ "log", "error", self.tag, context, "->", "MESSAGE TOO LARGE" }) catch {}; return; } const msg___ = buf[0..msg__.len]; @memcpy(msg___, msg__); - msg = msg___; + if (buf.len - msg___.len > trace__.len) { + const msg____ = buf[0 .. msg__.len + trace__.len]; + @memcpy(msg____[msg__.len..], trace__); + msg = msg____; + } else { + msg = msg___; + } }, else => { msg = @errorName(e); diff --git a/src/project_manager.zig b/src/project_manager.zig index 820fa7c..546c3fc 100644 --- a/src/project_manager.zig +++ b/src/project_manager.zig @@ -13,13 +13,13 @@ pid: tp.pid_ref, const Self = @This(); const module_name = @typeName(Self); -pub fn get() error{Exit}!Self { +pub fn get() !Self { const pid = tp.env.get().proc(module_name); return if (pid.expired()) create() else .{ .pid = pid }; } -fn create() error{Exit}!Self { - const pid = Process.create() catch |e| return tp.exit_error(e); +fn create() !Self { + const pid = try Process.create(); defer pid.deinit(); tp.env.get().proc_set(module_name, pid.ref()); return .{ .pid = tp.env.get().proc(module_name) }; @@ -34,35 +34,35 @@ pub fn shutdown() void { pid.send(.{"shutdown"}) catch {}; } -pub fn open_cwd() tp.result { +pub fn open_cwd() !void { return open("."); } -pub fn open(rel_project_directory: []const u8) tp.result { +pub fn open(rel_project_directory: []const u8) !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)"; - var dir = std.fs.openDirAbsolute(project_directory, .{}) catch |e| return tp.exit_error(e); - dir.setAsCwd() catch |e| return tp.exit_error(e); + var dir = try std.fs.openDirAbsolute(project_directory, .{}); + try dir.setAsCwd(); dir.close(); tp.env.get().str_set("project", project_directory); return (try get()).pid.send(.{ "open", project_directory }); } -pub fn request_recent_files(max: usize) tp.result { +pub fn request_recent_files(max: usize) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "request_recent_files", project, max }); } -pub fn query_recent_files(max: usize, query: []const u8) tp.result { +pub fn query_recent_files(max: usize, query: []const u8) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "query_recent_files", project, max, query }); } -pub fn did_open(file_path: []const u8, file_type: *const FileType, version: usize, text: []const u8) tp.result { +pub fn did_open(file_path: []const u8, file_type: *const FileType, version: usize, text: []const u8) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); @@ -70,49 +70,49 @@ pub fn did_open(file_path: []const u8, file_type: *const FileType, version: usiz return (try get()).pid.send(.{ "did_open", project, file_path, file_type.name, file_type.language_server, version, text_ptr, text.len }); } -pub fn did_change(file_path: []const u8, version: usize, root_dst: usize, root_src: usize) tp.result { +pub fn did_change(file_path: []const u8, version: usize, root_dst: usize, root_src: usize) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "did_change", project, file_path, version, root_dst, root_src }); } -pub fn did_save(file_path: []const u8) tp.result { +pub fn did_save(file_path: []const u8) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "did_save", project, file_path }); } -pub fn did_close(file_path: []const u8) tp.result { +pub fn did_close(file_path: []const u8) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "did_close", project, file_path }); } -pub fn goto_definition(file_path: []const u8, row: usize, col: usize) tp.result { +pub fn goto_definition(file_path: []const u8, row: usize, col: usize) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "goto_definition", project, file_path, row, col }); } -pub fn completion(file_path: []const u8, row: usize, col: usize) tp.result { +pub fn completion(file_path: []const u8, row: usize, col: usize) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "completion", project, file_path, row, col }); } -pub fn update_mru(file_path: []const u8, row: usize, col: usize) tp.result { +pub fn update_mru(file_path: []const u8, row: usize, col: usize) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); return (try get()).pid.send(.{ "update_mru", project, file_path, row, col }); } -pub fn get_mru_position(file_path: []const u8) tp.result { +pub fn get_mru_position(file_path: []const u8) !void { const project = tp.env.get().str("project"); if (project.len == 0) return tp.exit("No project"); @@ -140,7 +140,7 @@ const Process = struct { .receiver = Receiver.init(Process.receive, self), .projects = ProjectsMap.init(a), }; - return tp.spawn_link(self.a, self, Process.start, module_name) catch |e| tp.exit_error(e); + return tp.spawn_link(self.a, self, Process.start, module_name); } fn deinit(self: *Process) void { @@ -166,11 +166,11 @@ const Process = struct { self.receive_safe(from, m) catch |e| { if (std.mem.eql(u8, "normal", tp.error_text())) return e; - self.logger.err("receive", e); + self.logger.err("receive", tp.exit_error(e, @errorReturnTrace())); }; } - fn receive_safe(self: *Process, from: tp.pid_ref, m: tp.message) tp.result { + fn receive_safe(self: *Process, from: tp.pid_ref, m: tp.message) !void { var project_directory: []const u8 = undefined; var path: []const u8 = undefined; var query: []const u8 = undefined; @@ -201,9 +201,9 @@ const Process = struct { } else if (try m.match(.{ "walk_tree_done", tp.extract(&project_directory) })) { if (self.walker) |pid| pid.deinit(); self.walker = null; - self.loaded(project_directory) catch |e| return from.forward_error(e); + self.loaded(project_directory) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "update_mru", tp.extract(&project_directory), tp.extract(&path), tp.extract(&row), tp.extract(&col) })) { - self.update_mru(project_directory, path, row, col) catch |e| return from.forward_error(e); + self.update_mru(project_directory, path, row, col) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "child", tp.extract(&project_directory), tp.extract(&language_server), "notify", tp.extract(&method), tp.extract_cbor(¶ms_cb) })) { self.dispatch_notify(project_directory, language_server, method, params_cb) catch |e| return self.logger.err("lsp-handling", e); } else if (try m.match(.{ "child", tp.extract(&project_directory), tp.extract(&language_server), "request", tp.extract(&method), tp.extract(&id), tp.extract_cbor(¶ms_cb) })) { @@ -211,26 +211,26 @@ const Process = struct { } else if (try m.match(.{ "child", tp.extract(&path), "done" })) { self.logger.print_err("lsp-handling", "child '{s}' terminated", .{path}); } else if (try m.match(.{ "open", tp.extract(&project_directory) })) { - self.open(project_directory) catch |e| return from.forward_error(e); + self.open(project_directory) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "request_recent_files", tp.extract(&project_directory), tp.extract(&max) })) { - self.request_recent_files(from, project_directory, max) catch |e| return from.forward_error(e); + self.request_recent_files(from, project_directory, max) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "query_recent_files", tp.extract(&project_directory), tp.extract(&max), tp.extract(&query) })) { - self.query_recent_files(from, project_directory, max, query) catch |e| return from.forward_error(e); + self.query_recent_files(from, project_directory, max, query) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "did_open", tp.extract(&project_directory), tp.extract(&path), tp.extract(&file_type), tp.extract_cbor(&language_server), tp.extract(&version), tp.extract(&text_ptr), tp.extract(&text_len) })) { const text = if (text_len > 0) @as([*]const u8, @ptrFromInt(text_ptr))[0..text_len] else ""; - self.did_open(project_directory, path, file_type, language_server, version, text) catch |e| return from.forward_error(e); + self.did_open(project_directory, path, file_type, language_server, version, text) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "did_change", tp.extract(&project_directory), tp.extract(&path), tp.extract(&version), tp.extract(&root_dst), tp.extract(&root_src) })) { - self.did_change(project_directory, path, version, root_dst, root_src) catch |e| return from.forward_error(e); + self.did_change(project_directory, path, version, root_dst, root_src) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "did_save", tp.extract(&project_directory), tp.extract(&path) })) { - self.did_save(project_directory, path) catch |e| return from.forward_error(e); + self.did_save(project_directory, path) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "did_close", tp.extract(&project_directory), tp.extract(&path) })) { - self.did_close(project_directory, path) catch |e| return from.forward_error(e); + self.did_close(project_directory, path) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "goto_definition", tp.extract(&project_directory), tp.extract(&path), tp.extract(&row), tp.extract(&col) })) { - self.goto_definition(from, project_directory, path, row, col) catch |e| return from.forward_error(e); + self.goto_definition(from, project_directory, path, row, col) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "completion", tp.extract(&project_directory), tp.extract(&path), tp.extract(&row), tp.extract(&col) })) { - self.completion(from, project_directory, path, row, col) catch |e| return from.forward_error(e); + self.completion(from, project_directory, path, row, col) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{ "get_mru_position", tp.extract(&project_directory), tp.extract(&path) })) { - self.get_mru_position(from, project_directory, path) catch |e| return from.forward_error(e); + self.get_mru_position(from, project_directory, path) catch |e| return from.forward_error(e, @errorReturnTrace()); } else if (try m.match(.{"shutdown"})) { if (self.walker) |pid| pid.send(.{"stop"}) catch {}; self.persist_projects(); @@ -245,7 +245,7 @@ const Process = struct { } } - fn open(self: *Process, project_directory: []const u8) error{ OutOfMemory, Exit }!void { + fn open(self: *Process, project_directory: []const u8) !void { if (self.projects.get(project_directory) == null) { self.logger.print("opening: {s}", .{project_directory}); const project = try self.a.create(Project); @@ -282,72 +282,72 @@ const Process = struct { self.logger.print("query \"{s}\" matched {d}/{d} in {d} ms", .{ query, matched, project.files.items.len, query_time }); } - fn did_open(self: *Process, project_directory: []const u8, file_path: []const u8, file_type: []const u8, language_server: []const u8, version: usize, text: []const u8) tp.result { + fn did_open(self: *Process, project_directory: []const u8, file_path: []const u8, file_type: []const u8, language_server: []const u8, version: usize, text: []const u8) !void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".did_open" }); defer frame.deinit(); const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); return project.did_open(file_path, file_type, language_server, version, text); } - fn did_change(self: *Process, project_directory: []const u8, file_path: []const u8, version: usize, root_dst: usize, root_src: usize) tp.result { + fn did_change(self: *Process, project_directory: []const u8, file_path: []const u8, version: usize, root_dst: usize, root_src: usize) !void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".did_change" }); defer frame.deinit(); const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); - return project.did_change(file_path, version, root_dst, root_src) catch |e| tp.exit_error(e); + return project.did_change(file_path, version, root_dst, root_src); } - fn did_save(self: *Process, project_directory: []const u8, file_path: []const u8) tp.result { + fn did_save(self: *Process, project_directory: []const u8, file_path: []const u8) !void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".did_save" }); defer frame.deinit(); const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); return project.did_save(file_path); } - fn did_close(self: *Process, project_directory: []const u8, file_path: []const u8) tp.result { + fn did_close(self: *Process, project_directory: []const u8, file_path: []const u8) !void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".did_close" }); defer frame.deinit(); const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); return project.did_close(file_path); } - fn goto_definition(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8, row: usize, col: usize) tp.result { + fn goto_definition(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8, row: usize, col: usize) !void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".goto_definition" }); defer frame.deinit(); const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); - return project.goto_definition(from, file_path, row, col) catch |e| tp.exit_error(e); + return project.goto_definition(from, file_path, row, col); } - fn completion(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8, row: usize, col: usize) tp.result { + fn completion(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8, row: usize, col: usize) !void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".completion" }); defer frame.deinit(); const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); - return project.completion(from, file_path, row, col) catch |e| tp.exit_error(e); + return project.completion(from, file_path, row, col); } - fn get_mru_position(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8) tp.result { + fn get_mru_position(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8) !void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".get_mru_position" }); defer frame.deinit(); const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); - return project.get_mru_position(from, file_path) catch |e| tp.exit_error(e); + return project.get_mru_position(from, file_path); } - fn update_mru(self: *Process, project_directory: []const u8, file_path: []const u8, row: usize, col: usize) tp.result { + fn update_mru(self: *Process, project_directory: []const u8, file_path: []const u8, row: usize, col: usize) !void { const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); - return project.update_mru(file_path, row, col) catch |e| tp.exit_error(e); + return project.update_mru(file_path, row, col); } - fn dispatch_notify(self: *Process, project_directory: []const u8, language_server: []const u8, method: []const u8, params_cb: []const u8) tp.result { + fn dispatch_notify(self: *Process, project_directory: []const u8, language_server: []const u8, method: []const u8, params_cb: []const u8) !void { _ = language_server; const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project"); return if (std.mem.eql(u8, method, "textDocument/publishDiagnostics")) - project.publish_diagnostics(self.parent.ref(), params_cb) catch |e| tp.exit_error(e) + project.publish_diagnostics(self.parent.ref(), params_cb) else if (std.mem.eql(u8, method, "window/showMessage")) - project.show_message(self.parent.ref(), params_cb) catch |e| tp.exit_error(e) + project.show_message(self.parent.ref(), params_cb) else tp.exit_fmt("unsupported LSP notification: {s}", .{method}); } - fn dispatch_request(self: *Process, project_directory: []const u8, language_server: []const u8, method: []const u8, id: i32, params_cb: []const u8) tp.result { + fn dispatch_request(self: *Process, project_directory: []const u8, language_server: []const u8, method: []const u8, id: i32, params_cb: []const u8) !void { _ = self; _ = project_directory; _ = language_server; @@ -410,7 +410,7 @@ const Process = struct { } }; -fn walk_tree_async(a_: std.mem.Allocator, root_path_: []const u8) error{Exit}!tp.pid { +fn walk_tree_async(a_: std.mem.Allocator, root_path_: []const u8) !tp.pid { return struct { a: std.mem.Allocator, root_path: []const u8, @@ -422,17 +422,17 @@ fn walk_tree_async(a_: std.mem.Allocator, root_path_: []const u8) error{Exit}!tp const tree_walker = @This(); const Receiver = tp.Receiver(*tree_walker); - fn spawn_link(a: std.mem.Allocator, root_path: []const u8) error{Exit}!tp.pid { - const self = a.create(tree_walker) catch |e| return tp.exit_error(e); + fn spawn_link(a: std.mem.Allocator, root_path: []const u8) !tp.pid { + const self = try a.create(tree_walker); self.* = .{ .a = a, - .root_path = a.dupe(u8, root_path) catch |e| return tp.exit_error(e), + .root_path = try a.dupe(u8, root_path), .parent = tp.self_pid().clone(), .receiver = Receiver.init(tree_walker.receive, self), - .dir = std.fs.cwd().openDir(self.root_path, .{ .iterate = true }) catch |e| return tp.exit_error(e), - .walker = walk_filtered(self.dir, self.a) catch |e| return tp.exit_error(e), + .dir = try std.fs.cwd().openDir(self.root_path, .{ .iterate = true }), + .walker = try walk_filtered(self.dir, self.a), }; - return tp.spawn_link(a, self, tree_walker.start, module_name ++ ".tree_walker") catch |e| return tp.exit_error(e); + return tp.spawn_link(a, self, tree_walker.start, module_name ++ ".tree_walker"); } fn start(self: *tree_walker) tp.result { @@ -440,7 +440,7 @@ fn walk_tree_async(a_: std.mem.Allocator, root_path_: []const u8) error{Exit}!tp const frame = tracy.initZone(@src(), .{ .name = "project scan" }); defer frame.deinit(); tp.receive(&self.receiver); - self.next() catch |e| return tp.exit_error(e); + self.next() catch |e| return tp.exit_error(e, @errorReturnTrace()); } fn deinit(self: *tree_walker) void { @@ -456,7 +456,7 @@ fn walk_tree_async(a_: std.mem.Allocator, root_path_: []const u8) error{Exit}!tp defer frame.deinit(); if (try m.match(.{"next"})) { - self.next() catch |e| return tp.exit_error(e); + self.next() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"stop"})) { return tp.exit_normal(); } else { diff --git a/src/ripgrep.zig b/src/ripgrep.zig index 7c13415..ed7419d 100644 --- a/src/ripgrep.zig +++ b/src/ripgrep.zig @@ -11,9 +11,9 @@ stdin_behavior: std.process.Child.StdIo, const Self = @This(); const module_name = @typeName(Self); pub const max_chunk_size = tp.subprocess.max_chunk_size; -pub const Writer = std.io.Writer(*Self, error{Exit}, write); +pub const Writer = std.io.Writer(*Self, Error, write); pub const BufferedWriter = std.io.BufferedWriter(max_chunk_size, Writer); -pub const Error = error{ OutOfMemory, Exit }; +pub const Error = error{ OutOfMemory, Exit, ThespianSpawnFailed, Closed }; pub const FindF = fn (a: std.mem.Allocator, query: []const u8, tag: [:0]const u8) Error!Self; @@ -21,11 +21,11 @@ pub fn find_in_stdin(a: std.mem.Allocator, query: []const u8, tag: [:0]const u8) return create(a, query, tag, .Pipe); } -pub fn find_in_files(a: std.mem.Allocator, query: []const u8, tag: [:0]const u8) Error!Self { +pub fn find_in_files(a: std.mem.Allocator, query: []const u8, tag: [:0]const u8) !Self { return create(a, query, tag, .Close); } -fn create(a: std.mem.Allocator, query: []const u8, tag: [:0]const u8, stdin_behavior: std.process.Child.StdIo) Error!Self { +fn create(a: std.mem.Allocator, query: []const u8, tag: [:0]const u8, stdin_behavior: std.process.Child.StdIo) !Self { return .{ .pid = try Process.create(a, query, tag, stdin_behavior), .stdin_behavior = stdin_behavior }; } @@ -38,13 +38,13 @@ pub fn deinit(self: *Self) void { } } -pub fn write(self: *Self, bytes: []const u8) error{Exit}!usize { +pub fn write(self: *Self, bytes: []const u8) !usize { try self.input(bytes); return bytes.len; } -pub fn input(self: *const Self, bytes: []const u8) tp.result { - const pid = if (self.pid) |pid| pid else return tp.exit_error(error.Closed); +pub fn input(self: *const Self, bytes: []const u8) !void { + const pid = if (self.pid) |pid| pid else return error.Closed; var remaining = bytes; while (remaining.len > 0) remaining = loop: { @@ -83,7 +83,7 @@ const Process = struct { const Receiver = tp.Receiver(*Process); - pub fn create(a: std.mem.Allocator, query: []const u8, tag: [:0]const u8, stdin_behavior: std.process.Child.StdIo) Error!tp.pid { + pub fn create(a: std.mem.Allocator, query: []const u8, tag: [:0]const u8, stdin_behavior: std.process.Child.StdIo) !tp.pid { const self = try a.create(Process); self.* = .{ .a = a, @@ -95,7 +95,7 @@ const Process = struct { .logger = log.logger(@typeName(Self)), .stdin_behavior = stdin_behavior, }; - return tp.spawn_link(self.a, self, Process.start, tag) catch |e| tp.exit_error(e); + return tp.spawn_link(self.a, self, Process.start, tag); } fn deinit(self: *Process) void { @@ -121,7 +121,7 @@ const Process = struct { "--json", self.query, }); - self.sp = tp.subprocess.init(self.a, args, module_name, self.stdin_behavior) catch |e| return tp.exit_error(e); + self.sp = tp.subprocess.init(self.a, args, module_name, self.stdin_behavior) catch |e| return tp.exit_error(e, @errorReturnTrace()); tp.receive(&self.receiver); } @@ -130,14 +130,14 @@ const Process = struct { var bytes: []u8 = ""; if (try m.match(.{ "input", tp.extract(&bytes) })) { - const sp = if (self.sp) |sp| sp else return tp.exit_error(error.Closed); + const sp = if (self.sp) |sp| sp else return tp.exit_error(error.Closed, null); try sp.send(bytes); } else if (try m.match(.{"close"})) { try self.close(); } else if (try m.match(.{ module_name, "stdout", tp.extract(&bytes) })) { - self.handle_output(bytes) catch |e| return tp.exit_error(e); + self.handle_output(bytes) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ module_name, "term", tp.more })) { - self.handle_terminated() catch |e| return tp.exit_error(e); + self.handle_terminated() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ module_name, "stderr", tp.extract(&bytes) })) { self.logger.print("ERR: {s}", .{bytes}); } else if (try m.match(.{ "exit", "normal" })) { diff --git a/src/tui/MessageFilter.zig b/src/tui/MessageFilter.zig index d4ada18..3769e9d 100644 --- a/src/tui/MessageFilter.zig +++ b/src/tui/MessageFilter.zig @@ -123,7 +123,7 @@ pub const List = struct { pub fn filter(self: *const List, from: tp.pid_ref, m: tp.message) error{Exit}!bool { var sfa = std.heap.stackFallback(4096, self.a); const a = sfa.get(); - const buf = a.alloc(u8, m.buf.len) catch |e| return tp.exit_error(e); + const buf = a.alloc(u8, m.buf.len) catch |e| return tp.exit_error(e, @errorReturnTrace()); defer a.free(buf); @memcpy(buf[0..m.buf.len], m.buf); const m_: tp.message = .{ .buf = buf[0..m.buf.len] }; diff --git a/src/tui/command.zig b/src/tui/command.zig index 223bfb1..38f7974 100644 --- a/src/tui/command.zig +++ b/src/tui/command.zig @@ -7,6 +7,7 @@ const tui = @import("tui.zig"); pub const ID = usize; pub const ID_unknown = std.math.maxInt(ID); +pub const Result = anyerror!void; pub const Context = struct { args: tp.message = .{}, @@ -29,7 +30,7 @@ pub fn Closure(comptime T: type) type { f: FunT, data: T, - const FunT: type = *const fn (T, ctx: Context) tp.result; + const FunT: type = *const fn (T, ctx: Context) Result; const Self = @This(); pub fn init(f: FunT, data: T, name: []const u8) Self { @@ -61,7 +62,7 @@ pub fn Closure(comptime T: type) type { fn run(vtbl: *Vtable, ctx: Context) tp.result { const self: *Self = fromVtable(vtbl); - return self.f(self.data, ctx); + return self.f(self.data, ctx) catch |e| tp.exit_error(e, @errorReturnTrace()); } fn fromVtable(vtbl: *Vtable) *Self { @@ -96,7 +97,7 @@ pub fn execute(id: ID, ctx: Context) tp.result { const cmd = commands.items[id]; if (cmd) |p| { // var buf: [tp.max_message_size]u8 = undefined; - // log.print("cmd", "execute({s}) {s}", .{ p.name, ctx.args.to_json(&buf) catch "" }) catch |e| return tp.exit_error(e); + // log.print("cmd", "execute({s}) {s}", .{ p.name, ctx.args.to_json(&buf) catch "" }) catch |e| return tp.exit_error(e, @errorReturnTrace()); return p.run(p, ctx); } else { return tp.exit_fmt("CommandNotAvailable: {d}", .{id}); @@ -129,7 +130,7 @@ pub fn executeName(name: []const u8, ctx: Context) tp.result { fn CmdDef(comptime T: type) type { return struct { - const Fn = fn (T, Context) tp.result; + const Fn = fn (T, Context) anyerror!void; name: [:0]const u8, f: *const Fn, }; diff --git a/src/tui/editor.zig b/src/tui/editor.zig index 0ad3665..f845100 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -260,6 +260,9 @@ pub const Editor = struct { const StyleCache = std.AutoHashMap(u32, ?Widget.Theme.Token); + const Context = command.Context; + const Result = command.Result; + pub fn write_state(self: *const Self, writer: Buffer.MetaWriter) !void { try cbor.writeArrayHeader(writer, 6); try cbor.writeValue(writer, self.file_path orelse ""); @@ -454,7 +457,7 @@ pub const Editor = struct { (try self.cursels.addOne()).* = primary; } - pub fn pop_cursor(self: *Self, _: command.Context) tp.result { + pub fn pop_cursor(self: *Self, _: Context) Result { if (self.cursels.items.len > 1) _ = self.cursels.popOrNull(); self.clamp(); @@ -572,7 +575,7 @@ pub const Editor = struct { root: Buffer.Root, sel: Selection, writer: anytype, - map_error: fn (e: anyerror) @TypeOf(writer).Error, + map_error: fn (e: anyerror, stack_trace: ?*std.builtin.StackTrace) @TypeOf(writer).Error, wcwidth_: ?*usize, plane_: Plane, ) @TypeOf(writer).Error!void { @@ -610,7 +613,7 @@ pub const Editor = struct { ctx.sel.normalize(); if (sel.begin.eql(sel.end)) return; - root.walk_egc_forward(sel.begin.row, Ctx.walker, &ctx, plane_) catch |e| return map_error(e); + root.walk_egc_forward(sel.begin.row, Ctx.walker, &ctx, plane_) catch |e| return map_error(e, @errorReturnTrace()); if (wcwidth_) |p| p.* = ctx.wcwidth; } @@ -1267,13 +1270,13 @@ pub const Editor = struct { self.matches.clearAndFree(); } - pub fn clear_matches(self: *Self) tp.result { + pub fn clear_matches(self: *Self) void { self.cancel_all_matches(); self.match_token += 1; self.match_done_token = self.match_token; } - fn init_matches_update(self: *Self) tp.result { + fn init_matches_update(self: *Self) void { self.cancel_all_matches(); self.match_token += 1; } @@ -1290,11 +1293,11 @@ pub const Editor = struct { self.collapse_cursors(); } - fn with_cursor_const_arg(root: Buffer.Root, move: cursor_operator_const_arg, cursel: *CurSel, ctx: command.Context, plane: Plane) error{Stop}!void { + fn with_cursor_const_arg(root: Buffer.Root, move: cursor_operator_const_arg, cursel: *CurSel, ctx: Context, plane: Plane) error{Stop}!void { try move(root, &cursel.cursor, ctx, plane); } - fn with_cursors_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: command.Context) error{Stop}!void { + fn with_cursors_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: Context) error{Stop}!void { for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { cursel.selection = null; try with_cursor_const_arg(root, move, cursel, ctx, self.plane); @@ -1347,14 +1350,14 @@ pub const Editor = struct { return if (someone_stopped) error.Stop else {}; } - fn with_selection_const_arg(root: Buffer.Root, move: cursor_operator_const_arg, cursel: *CurSel, ctx: command.Context, plane: Plane) error{Stop}!void { + fn with_selection_const_arg(root: Buffer.Root, move: cursor_operator_const_arg, cursel: *CurSel, ctx: Context, plane: Plane) error{Stop}!void { const sel = cursel.enable_selection(); try move(root, &sel.end, ctx, plane); cursel.cursor = sel.end; cursel.check_selection(); } - fn with_selections_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: command.Context) error{Stop}!void { + fn with_selections_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: Context) error{Stop}!void { var someone_stopped = false; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| with_selection_const_arg(root, move, cursel, ctx, self.plane) catch { @@ -1491,7 +1494,7 @@ pub const Editor = struct { const cursor_predicate = *const fn (root: Buffer.Root, cursor: *Cursor, plane: Plane) bool; const cursor_operator_const = *const fn (root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void; - const cursor_operator_const_arg = *const fn (root: Buffer.Root, cursor: *Cursor, ctx: command.Context, plane: Plane) error{Stop}!void; + const cursor_operator_const_arg = *const fn (root: Buffer.Root, cursor: *Cursor, ctx: Context, plane: Plane) error{Stop}!void; const cursor_view_operator_const = *const fn (root: Buffer.Root, cursor: *Cursor, view: *const View, plane: Plane) error{Stop}!void; const cursel_operator_const = *const fn (root: Buffer.Root, cursel: *CurSel) error{Stop}!void; const cursor_operator = *const fn (root: Buffer.Root, cursor: *Cursor, a: Allocator) error{Stop}!Buffer.Root; @@ -1674,9 +1677,9 @@ pub const Editor = struct { cursor.move_page_down(root, view, plane); } - pub fn primary_click(self: *Self, y: c_int, x: c_int) tp.result { + pub fn primary_click(self: *Self, y: c_int, x: c_int) !void { if (self.fast_scroll) - self.push_cursor() catch |e| return tp.exit_error(e) + try self.push_cursor() else self.cancel_all_selections(); const primary = self.get_primary(); @@ -1690,27 +1693,27 @@ pub const Editor = struct { if (self.jump_mode) try self.goto_definition(.{}); } - pub fn primary_double_click(self: *Self, y: c_int, x: c_int) tp.result { + pub fn primary_double_click(self: *Self, y: c_int, x: c_int) !void { const primary = self.get_primary(); primary.selection = null; self.selection_mode = .word; const root = self.buf_root() catch return; primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane) catch return; - _ = self.select_word_at_cursor(primary) catch |e| return tp.exit_error(e); + _ = try self.select_word_at_cursor(primary); self.clamp_mouse(); } - pub fn primary_triple_click(self: *Self, y: c_int, x: c_int) tp.result { + pub fn primary_triple_click(self: *Self, y: c_int, x: c_int) !void { const primary = self.get_primary(); primary.selection = null; self.selection_mode = .line; const root = self.buf_root() catch return; primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane) catch return; - self.select_line_at_cursor(primary) catch |e| return tp.exit_error(e); + try self.select_line_at_cursor(primary); self.clamp_mouse(); } - pub fn primary_drag(self: *Self, y: c_int, x: c_int) tp.result { + pub fn primary_drag(self: *Self, y: c_int, x: c_int) void { const y_ = if (y < 0) 0 else y; const x_ = if (x < 0) 0 else x; const primary = self.get_primary(); @@ -1735,19 +1738,19 @@ pub const Editor = struct { self.clamp_mouse(); } - pub fn drag_to(self: *Self, ctx: command.Context) tp.result { + pub fn drag_to(self: *Self, ctx: Context) !void { var y: i32 = 0; var x: i32 = 0; if (!try ctx.args.match(.{ tp.extract(&y), tp.extract(&x) })) - return tp.exit_error(error.InvalidArgument); + return error.InvalidArgument; return self.primary_drag(y, x); } - pub fn secondary_click(self: *Self, y: c_int, x: c_int) tp.result { + pub fn secondary_click(self: *Self, y: c_int, x: c_int) !void { return self.primary_drag(y, x); } - pub fn secondary_drag(self: *Self, y: c_int, x: c_int) tp.result { + pub fn secondary_drag(self: *Self, y: c_int, x: c_int) !void { return self.primary_drag(y, x); } @@ -1829,14 +1832,14 @@ pub const Editor = struct { self.update_scroll_dest_abs(dest.row); } - pub fn scroll_up_pageup(self: *Self, _: command.Context) tp.result { + pub fn scroll_up_pageup(self: *Self, _: Context) Result { if (self.fast_scroll) self.scroll_pageup() else self.scroll_up(); } - pub fn scroll_down_pagedown(self: *Self, _: command.Context) tp.result { + pub fn scroll_down_pagedown(self: *Self, _: Context) Result { if (self.fast_scroll) self.scroll_pagedown() else @@ -1847,21 +1850,21 @@ pub const Editor = struct { self.update_scroll_dest_abs(row); } - fn scroll_view_offset(self: *Self, offset: usize) tp.result { + fn scroll_view_offset(self: *Self, offset: usize) void { const primary = self.get_primary(); const row = if (primary.cursor.row > offset) primary.cursor.row - offset else 0; self.update_scroll_dest_abs(row); } - pub fn scroll_view_center(self: *Self, _: command.Context) tp.result { + pub fn scroll_view_center(self: *Self, _: Context) Result { return self.scroll_view_offset(self.view.rows / 2); } - pub fn scroll_view_top(self: *Self, _: command.Context) tp.result { + pub fn scroll_view_top(self: *Self, _: Context) Result { return self.scroll_view_offset(scroll_cursor_min_border_distance); } - pub fn scroll_view_bottom(self: *Self, _: command.Context) tp.result { + pub fn scroll_view_bottom(self: *Self, _: Context) Result { return self.scroll_view_offset(if (self.view.rows > scroll_cursor_min_border_distance) self.view.rows - scroll_cursor_min_border_distance else 0); } @@ -1884,10 +1887,10 @@ pub const Editor = struct { } fn copy_word_at_cursor(self: *Self, text_a: Allocator) ![]const u8 { - const root = self.buf_root() catch |e| return tp.exit_error(e); + const root = try self.buf_root(); const primary = self.get_primary(); - const sel = if (primary.selection) |*sel| sel else self.select_word_at_cursor(primary) catch |e| return tp.exit_error(e); - return copy_selection(root, sel.*, text_a, self.plane) catch |e| return tp.exit_error(e); + const sel = if (primary.selection) |*sel| sel else try self.select_word_at_cursor(primary); + return try copy_selection(root, sel.*, text_a, self.plane); } pub fn cut_selection(self: *Self, root: Buffer.Root, cursel: *CurSel) !struct { []const u8, Buffer.Root } { @@ -1919,46 +1922,46 @@ pub const Editor = struct { return root_; } - pub fn cut(self: *Self, _: command.Context) tp.result { + pub fn cut(self: *Self, _: Context) Result { const primary = self.get_primary(); const b = self.buf_for_update() catch return; var root = b.root; if (self.cursels.items.len == 1) if (primary.selection) |_| {} else { const sel = primary.enable_selection(); - move_cursor_begin(root, &sel.begin, self.plane) catch |e| return tp.exit_error(e); - move_cursor_end(root, &sel.end, self.plane) catch |e| return tp.exit_error(e); - move_cursor_right(root, &sel.end, self.plane) catch |e| return tp.exit_error(e); + try move_cursor_begin(root, &sel.begin, self.plane); + try move_cursor_end(root, &sel.end, self.plane); + try move_cursor_right(root, &sel.end, self.plane); }; var first = true; var text = std.ArrayList(u8).init(self.a); for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { - const cut_text, root = self.cut_selection(root, cursel) catch |e| return tp.exit_error(e); + const cut_text, root = try self.cut_selection(root, cursel); if (first) { first = false; } else { - text.appendSlice("\n") catch |e| return tp.exit_error(e); + try text.appendSlice("\n"); } - text.appendSlice(cut_text) catch |e| return tp.exit_error(e); + try text.appendSlice(cut_text); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.set_clipboard(text.items); self.clamp(); } - pub fn copy(self: *Self, _: command.Context) tp.result { + pub fn copy(self: *Self, _: Context) Result { const root = self.buf_root() catch return; var first = true; var text = std.ArrayList(u8).init(self.a); for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { if (cursel.selection) |sel| { - const copy_text = copy_selection(root, sel, self.a, self.plane) catch |e| return tp.exit_error(e); + const copy_text = try copy_selection(root, sel, self.a, self.plane); if (first) { first = false; } else { - text.appendSlice("\n") catch |e| return tp.exit_error(e); + try text.appendSlice("\n"); } - text.appendSlice(copy_text) catch |e| return tp.exit_error(e); + try text.appendSlice(copy_text); } }; if (text.items.len > 0) { @@ -1971,102 +1974,102 @@ pub const Editor = struct { } } - pub fn paste(self: *Self, ctx: command.Context) tp.result { + pub fn paste(self: *Self, ctx: Context) Result { var text: []const u8 = undefined; if (!try ctx.args.match(.{tp.extract(&text)})) { if (self.clipboard) |text_| text = text_ else return; } self.logger.print("paste: {d} bytes", .{text.len}); - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + const b = try self.buf_for_update(); var root = b.root; if (self.cursels.items.len == 1) { const primary = self.get_primary(); - root = self.insert(root, primary, text, b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, primary, text, b.a); } else { if (std.mem.indexOfScalar(u8, text, '\n')) |_| { var pos: usize = 0; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { if (std.mem.indexOfScalarPos(u8, text, pos, '\n')) |next| { - root = self.insert(root, cursel, text[pos..next], b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, cursel, text[pos..next], b.a); pos = next + 1; } else { - root = self.insert(root, cursel, text[pos..], b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, cursel, text[pos..], b.a); pos = 0; } }; } else { for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { - root = self.insert(root, cursel, text, b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, cursel, text, b.a); }; } } - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); self.need_render(); } - pub fn system_paste(_: *Self, _: command.Context) tp.result { + pub fn system_paste(_: *Self, _: Context) Result { tui.current().rdr.request_system_clipboard(); } - pub fn delete_forward(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.delete_to(move_cursor_right, b.root, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn delete_forward(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.delete_to(move_cursor_right, b.root, b.a); + try self.update_buf(root); self.clamp(); } - pub fn delete_backward(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.delete_to(move_cursor_left, b.root, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn delete_backward(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.delete_to(move_cursor_left, b.root, b.a); + try self.update_buf(root); self.clamp(); } - pub fn delete_word_left(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.delete_to(move_cursor_word_left_space, b.root, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn delete_word_left(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.delete_to(move_cursor_word_left_space, b.root, b.a); + try self.update_buf(root); self.clamp(); } - pub fn delete_word_right(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.delete_to(move_cursor_word_right_space, b.root, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn delete_word_right(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.delete_to(move_cursor_word_right_space, b.root, b.a); + try self.update_buf(root); self.clamp(); } - pub fn delete_to_begin(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.delete_to(move_cursor_begin, b.root, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn delete_to_begin(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.delete_to(move_cursor_begin, b.root, b.a); + try self.update_buf(root); self.clamp(); } - pub fn delete_to_end(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.delete_to(move_cursor_end, b.root, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn delete_to_end(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.delete_to(move_cursor_end, b.root, b.a); + try self.update_buf(root); self.clamp(); } - pub fn join_next_line(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - self.with_cursors_const(b.root, move_cursor_end) catch |e| return tp.exit_error(e); - const root = self.delete_to(move_cursor_right, b.root, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn join_next_line(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + try self.with_cursors_const(b.root, move_cursor_end); + const root = try self.delete_to(move_cursor_right, b.root, b.a); + try self.update_buf(root); self.clamp(); } - pub fn move_left(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_left(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_left) catch {}; self.clamp(); } - pub fn move_right(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_right(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_right) catch {}; self.clamp(); } @@ -2079,14 +2082,14 @@ pub const Editor = struct { move_cursor_right_unless(root, cursor, is_eol_right_vim, plane); } - pub fn move_left_vim(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_left_vim(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_left_vim) catch {}; self.clamp(); } - pub fn move_right_vim(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_right_vim(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_right_vim) catch {}; self.clamp(); } @@ -2150,25 +2153,25 @@ pub const Editor = struct { try move_cursor_right(root, cursor, plane); } - pub fn move_word_left(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_word_left(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_word_left) catch {}; self.clamp(); } - pub fn move_word_right(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_word_right(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_word_right) catch {}; self.clamp(); } - pub fn move_word_right_vim(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_word_right_vim(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_word_right_vim) catch {}; self.clamp(); } - fn move_cursor_to_char_left(root: Buffer.Root, cursor: *Cursor, ctx: command.Context, plane: Plane) error{Stop}!void { + fn move_cursor_to_char_left(root: Buffer.Root, cursor: *Cursor, ctx: Context, plane: Plane) error{Stop}!void { var egc: []const u8 = undefined; if (!(ctx.args.match(.{tp.extract(&egc)}) catch return error.Stop)) return error.Stop; @@ -2183,7 +2186,7 @@ pub const Editor = struct { } } - pub fn move_cursor_to_char_right(root: Buffer.Root, cursor: *Cursor, ctx: command.Context, plane: Plane) error{Stop}!void { + pub fn move_cursor_to_char_right(root: Buffer.Root, cursor: *Cursor, ctx: Context, plane: Plane) error{Stop}!void { var egc: []const u8 = undefined; if (!(ctx.args.match(.{tp.extract(&egc)}) catch return error.Stop)) return error.Stop; @@ -2198,54 +2201,54 @@ pub const Editor = struct { } } - pub fn move_to_char_left(self: *Self, ctx: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_to_char_left(self: *Self, ctx: Context) Result { + const root = try self.buf_root(); self.with_cursors_const_arg(root, move_cursor_to_char_left, ctx) catch {}; self.clamp(); } - pub fn move_to_char_right(self: *Self, ctx: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_to_char_right(self: *Self, ctx: Context) Result { + const root = try self.buf_root(); self.with_cursors_const_arg(root, move_cursor_to_char_right, ctx) catch {}; self.clamp(); } - pub fn move_up(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_up(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_up) catch {}; self.clamp(); } - pub fn add_cursor_up(self: *Self, _: command.Context) tp.result { - self.push_cursor() catch |e| return tp.exit_error(e); + pub fn add_cursor_up(self: *Self, _: Context) Result { + try self.push_cursor(); const primary = self.get_primary(); - const root = self.buf_root() catch |e| return tp.exit_error(e); + const root = try self.buf_root(); move_cursor_up(root, &primary.cursor, self.plane) catch {}; self.clamp(); } - pub fn move_down(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_down(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_down) catch {}; self.clamp(); } - pub fn add_cursor_down(self: *Self, _: command.Context) tp.result { - self.push_cursor() catch |e| return tp.exit_error(e); + pub fn add_cursor_down(self: *Self, _: Context) Result { + try self.push_cursor(); const primary = self.get_primary(); - const root = self.buf_root() catch |e| return tp.exit_error(e); + const root = try self.buf_root(); move_cursor_down(root, &primary.cursor, self.plane) catch {}; self.clamp(); } - pub fn add_cursor_next_match(self: *Self, _: command.Context) tp.result { + pub fn add_cursor_next_match(self: *Self, _: Context) Result { try self.send_editor_jump_source(); if (self.matches.items.len == 0) { const root = self.buf_root() catch return; self.with_cursors_const(root, move_cursor_word_begin) catch {}; - self.with_selections_const(root, move_cursor_word_end) catch |e| return tp.exit_error(e); + try self.with_selections_const(root, move_cursor_word_end); } else if (self.get_next_match(self.get_primary().cursor)) |match| { - self.push_cursor() catch |e| return tp.exit_error(e); + try self.push_cursor(); const primary = self.get_primary(); const root = self.buf_root() catch return; primary.selection = match.to_selection(); @@ -2256,11 +2259,11 @@ pub const Editor = struct { try self.send_editor_jump_destination(); } - pub fn add_cursor_all_matches(self: *Self, _: command.Context) tp.result { + pub fn add_cursor_all_matches(self: *Self, _: Context) Result { if (self.matches.items.len == 0) return; try self.send_editor_jump_source(); while (self.get_next_match(self.get_primary().cursor)) |match| { - self.push_cursor() catch |e| return tp.exit_error(e); + try self.push_cursor(); const primary = self.get_primary(); const root = self.buf_root() catch return; primary.selection = match.to_selection(); @@ -2288,12 +2291,12 @@ pub const Editor = struct { } } - pub fn add_cursors_to_line_ends(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - const cursels = self.cursels.toOwnedSlice() catch |e| return tp.exit_error(e); + pub fn add_cursors_to_line_ends(self: *Self, _: Context) Result { + const root = try self.buf_root(); + const cursels = try self.cursels.toOwnedSlice(); defer self.cursels.allocator.free(cursels); for (cursels) |*cursel_| if (cursel_.*) |*cursel| - self.add_cursors_to_cursel_line_ends(root, cursel) catch |e| return tp.exit_error(e); + try self.add_cursors_to_cursel_line_ends(root, cursel); self.collapse_cursors(); self.clamp(); } @@ -2317,10 +2320,10 @@ pub const Editor = struct { return root; } - pub fn pull_up(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, pull_cursel_up, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn pull_up(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, pull_cursel_up, b.a); + try self.update_buf(root); self.clamp(); } @@ -2343,10 +2346,10 @@ pub const Editor = struct { return root; } - pub fn pull_down(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, pull_cursel_down, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn pull_down(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, pull_cursel_down, b.a); + try self.update_buf(root); self.clamp(); } @@ -2364,10 +2367,10 @@ pub const Editor = struct { return root; } - pub fn dupe_up(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, dupe_cursel_up, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn dupe_up(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, dupe_cursel_up, b.a); + try self.update_buf(root); self.clamp(); } @@ -2384,10 +2387,10 @@ pub const Editor = struct { return root; } - pub fn dupe_down(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, dupe_cursel_down, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn dupe_down(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, dupe_cursel_down, b.a); + try self.update_buf(root); self.clamp(); } @@ -2406,18 +2409,18 @@ pub const Editor = struct { return root; } - pub fn toggle_prefix(self: *Self, ctx: command.Context) tp.result { + pub fn toggle_prefix(self: *Self, ctx: Context) Result { var prefix: []const u8 = undefined; if (!try ctx.args.match(.{tp.extract(&prefix)})) return; @memcpy(self.prefix_buf[0..prefix.len], prefix); self.prefix = self.prefix_buf[0..prefix.len]; - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, toggle_cursel_prefix, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, toggle_cursel_prefix, b.a); + try self.update_buf(root); } - pub fn toggle_comment(self: *Self, _: command.Context) tp.result { + pub fn toggle_comment(self: *Self, _: Context) Result { const comment = if (self.syntax) |syn| syn.file_type.comment else "//"; return self.toggle_prefix(command.fmt(.{comment})); } @@ -2444,11 +2447,11 @@ pub const Editor = struct { } else return try self.indent_cursor(root_, cursel.cursor, a); } - pub fn indent(self: *Self, _: command.Context) tp.result { + pub fn indent(self: *Self, _: Context) Result { defer self.reset_syntax(); - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, indent_cursel, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, indent_cursel, b.a); + try self.update_buf(root); } fn unindent_cursor(self: *Self, root: Buffer.Root, cursel: *CurSel, cursor: Cursor, a: Allocator) error{Stop}!Buffer.Root { @@ -2485,38 +2488,38 @@ pub const Editor = struct { } else return self.unindent_cursor(root_, cursel, cursel.cursor, a); } - pub fn unindent(self: *Self, _: command.Context) tp.result { + pub fn unindent(self: *Self, _: Context) Result { defer self.reset_syntax(); - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, unindent_cursel, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, unindent_cursel, b.a); + try self.update_buf(root); } - pub fn move_scroll_up(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_scroll_up(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_up) catch {}; self.view.move_up() catch {}; self.clamp(); } - pub fn move_scroll_down(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn move_scroll_down(self: *Self, _: Context) Result { + const root = try self.buf_root(); self.with_cursors_const(root, move_cursor_down) catch {}; self.view.move_down(root) catch {}; self.clamp(); } - pub fn move_scroll_left(self: *Self, _: command.Context) tp.result { + pub fn move_scroll_left(self: *Self, _: Context) Result { self.view.move_left() catch {}; } - pub fn move_scroll_right(self: *Self, _: command.Context) tp.result { + pub fn move_scroll_right(self: *Self, _: Context) Result { self.view.move_right() catch {}; } - pub fn move_scroll_page_up(self: *Self, _: command.Context) tp.result { + pub fn move_scroll_page_up(self: *Self, _: Context) Result { if (self.screen_cursor(&self.get_primary().cursor)) |cursor| { - const root = self.buf_root() catch |e| return tp.exit_error(e); + const root = try self.buf_root(); self.with_cursors_and_view_const(root, move_cursor_page_up, &self.view) catch {}; const new_cursor_row = self.get_primary().cursor.row; self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row); @@ -2525,9 +2528,9 @@ pub const Editor = struct { } } - pub fn move_scroll_page_down(self: *Self, _: command.Context) tp.result { + pub fn move_scroll_page_down(self: *Self, _: Context) Result { if (self.screen_cursor(&self.get_primary().cursor)) |cursor| { - const root = self.buf_root() catch |e| return tp.exit_error(e); + const root = try self.buf_root(); self.with_cursors_and_view_const(root, move_cursor_page_down, &self.view) catch {}; const new_cursor_row = self.get_primary().cursor.row; self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row); @@ -2536,40 +2539,40 @@ pub const Editor = struct { } } - pub fn smart_move_begin(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_cursors_const(root, smart_move_cursor_begin) catch |e| return tp.exit_error(e); + pub fn smart_move_begin(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_cursors_const(root, smart_move_cursor_begin); self.clamp(); } - pub fn move_begin(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_cursors_const(root, move_cursor_begin) catch |e| return tp.exit_error(e); + pub fn move_begin(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_cursors_const(root, move_cursor_begin); self.clamp(); } - pub fn move_end(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_cursors_const(root, move_cursor_end) catch |e| return tp.exit_error(e); + pub fn move_end(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_cursors_const(root, move_cursor_end); self.clamp(); } - pub fn move_page_up(self: *Self, _: command.Context) tp.result { + pub fn move_page_up(self: *Self, _: Context) Result { try self.send_editor_jump_source(); - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_cursors_and_view_const(root, move_cursor_page_up, &self.view) catch |e| return tp.exit_error(e); + const root = try self.buf_root(); + try self.with_cursors_and_view_const(root, move_cursor_page_up, &self.view); self.clamp(); } - pub fn move_page_down(self: *Self, _: command.Context) tp.result { + pub fn move_page_down(self: *Self, _: Context) Result { try self.send_editor_jump_source(); - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_cursors_and_view_const(root, move_cursor_page_down, &self.view) catch |e| return tp.exit_error(e); + const root = try self.buf_root(); + try self.with_cursors_and_view_const(root, move_cursor_page_down, &self.view); self.clamp(); try self.send_editor_jump_destination(); } - pub fn move_buffer_begin(self: *Self, _: command.Context) tp.result { + pub fn move_buffer_begin(self: *Self, _: Context) Result { try self.send_editor_jump_source(); self.cancel_all_selections(); self.get_primary().cursor.move_buffer_begin(); @@ -2577,7 +2580,7 @@ pub const Editor = struct { try self.send_editor_jump_destination(); } - pub fn move_buffer_end(self: *Self, _: command.Context) tp.result { + pub fn move_buffer_end(self: *Self, _: Context) Result { try self.send_editor_jump_source(); self.cancel_all_selections(); const root = self.buf_root() catch return; @@ -2586,142 +2589,142 @@ pub const Editor = struct { try self.send_editor_jump_destination(); } - pub fn cancel(self: *Self, _: command.Context) tp.result { + pub fn cancel(self: *Self, _: Context) Result { self.cancel_all_selections(); self.cancel_all_matches(); } - pub fn select_up(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_up) catch |e| return tp.exit_error(e); + pub fn select_up(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_up); self.clamp(); } - pub fn select_down(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_down) catch |e| return tp.exit_error(e); + pub fn select_down(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_down); self.clamp(); } - pub fn select_scroll_up(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_up) catch |e| return tp.exit_error(e); + pub fn select_scroll_up(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_up); self.view.move_up() catch {}; self.clamp(); } - pub fn select_scroll_down(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_down) catch |e| return tp.exit_error(e); + pub fn select_scroll_down(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_down); self.view.move_down(root) catch {}; self.clamp(); } - pub fn select_left(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_left) catch |e| return tp.exit_error(e); + pub fn select_left(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_left); self.clamp(); } - pub fn select_right(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_right) catch |e| return tp.exit_error(e); + pub fn select_right(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_right); self.clamp(); } - pub fn select_word_left(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_word_left) catch |e| return tp.exit_error(e); + pub fn select_word_left(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_word_left); self.clamp(); } - pub fn select_word_right(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_word_right) catch |e| return tp.exit_error(e); + pub fn select_word_right(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_word_right); self.clamp(); } - pub fn select_word_begin(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_word_begin) catch |e| return tp.exit_error(e); + pub fn select_word_begin(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_word_begin); self.clamp(); } - pub fn select_word_end(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_word_end) catch |e| return tp.exit_error(e); + pub fn select_word_end(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_word_end); self.clamp(); } - pub fn select_to_char_left(self: *Self, ctx: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn select_to_char_left(self: *Self, ctx: Context) Result { + const root = try self.buf_root(); self.with_selections_const_arg(root, move_cursor_to_char_left, ctx) catch {}; self.clamp(); } - pub fn select_to_char_right(self: *Self, ctx: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + pub fn select_to_char_right(self: *Self, ctx: Context) Result { + const root = try self.buf_root(); self.with_selections_const_arg(root, move_cursor_to_char_right, ctx) catch {}; self.clamp(); } - pub fn select_begin(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_begin) catch |e| return tp.exit_error(e); + pub fn select_begin(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_begin); self.clamp(); } - pub fn smart_select_begin(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, smart_move_cursor_begin) catch |e| return tp.exit_error(e); + pub fn smart_select_begin(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, smart_move_cursor_begin); self.clamp(); } - pub fn select_end(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_end) catch |e| return tp.exit_error(e); + pub fn select_end(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_end); self.clamp(); } - pub fn select_buffer_begin(self: *Self, _: command.Context) tp.result { + pub fn select_buffer_begin(self: *Self, _: Context) Result { try self.send_editor_jump_source(); - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_buffer_begin) catch |e| return tp.exit_error(e); + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_buffer_begin); self.clamp(); try self.send_editor_jump_destination(); } - pub fn select_buffer_end(self: *Self, _: command.Context) tp.result { + pub fn select_buffer_end(self: *Self, _: Context) Result { try self.send_editor_jump_source(); - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_const(root, move_cursor_buffer_end) catch |e| return tp.exit_error(e); + const root = try self.buf_root(); + try self.with_selections_const(root, move_cursor_buffer_end); self.clamp(); try self.send_editor_jump_destination(); } - pub fn select_page_up(self: *Self, _: command.Context) tp.result { + pub fn select_page_up(self: *Self, _: Context) Result { try self.send_editor_jump_source(); - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_and_view_const(root, move_cursor_page_up, &self.view) catch |e| return tp.exit_error(e); + const root = try self.buf_root(); + try self.with_selections_and_view_const(root, move_cursor_page_up, &self.view); self.clamp(); try self.send_editor_jump_destination(); } - pub fn select_page_down(self: *Self, _: command.Context) tp.result { + pub fn select_page_down(self: *Self, _: Context) Result { try self.send_editor_jump_source(); - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_selections_and_view_const(root, move_cursor_page_down, &self.view) catch |e| return tp.exit_error(e); + const root = try self.buf_root(); + try self.with_selections_and_view_const(root, move_cursor_page_down, &self.view); self.clamp(); try self.send_editor_jump_destination(); } - pub fn select_all(self: *Self, _: command.Context) tp.result { + pub fn select_all(self: *Self, _: Context) Result { try self.send_editor_jump_source(); self.cancel_all_selections(); const primary = self.get_primary(); const sel = primary.enable_selection(); - const root = self.buf_root() catch |e| return tp.exit_error(e); - expand_selection_to_all(root, sel, self.plane) catch |e| tp.exit_error(e); + const root = try self.buf_root(); + try expand_selection_to_all(root, sel, self.plane); primary.cursor = sel.end; self.clamp(); try self.send_editor_jump_destination(); @@ -2739,7 +2742,7 @@ pub const Editor = struct { } fn select_line_at_cursor(self: *Self, cursel: *CurSel) !void { - const root = self.buf_root() catch |e| return tp.exit_error(e); + const root = try self.buf_root(); const sel = cursel.enable_selection(); sel.normalize(); try move_cursor_begin(root, &sel.begin, self.plane); @@ -2754,37 +2757,37 @@ pub const Editor = struct { } } - pub fn selections_reverse(self: *Self, _: command.Context) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); - self.with_cursels_const(root, selection_reverse) catch |e| return tp.exit_error(e); + pub fn selections_reverse(self: *Self, _: Context) Result { + const root = try self.buf_root(); + try self.with_cursels_const(root, selection_reverse); self.clamp(); } - pub fn insert_chars(self: *Self, ctx: command.Context) tp.result { + pub fn insert_chars(self: *Self, ctx: Context) Result { var chars: []const u8 = undefined; if (!try ctx.args.match(.{tp.extract(&chars)})) - return tp.exit_error(error.InvalidArgument); - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + return error.InvalidArgument; + const b = try self.buf_for_update(); var root = b.root; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { - root = self.insert(root, cursel, chars, b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, cursel, chars, b.a); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); } - pub fn insert_line(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + pub fn insert_line(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); var root = b.root; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { - root = self.insert(root, cursel, "\n", b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, cursel, "\n", b.a); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); } - pub fn smart_insert_line(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + pub fn smart_insert_line(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); var root = b.root; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { var leading_ws = @min(find_first_non_ws(root, cursel.cursor.row, self.plane), cursel.cursor.col); @@ -2793,95 +2796,95 @@ pub const Editor = struct { var stream = std.ArrayList(u8).init(a); defer stream.deinit(); var writer = stream.writer(); - _ = writer.write("\n") catch |e| return tp.exit_error(e); + _ = try writer.write("\n"); while (leading_ws > 0) : (leading_ws -= 1) - _ = writer.write(" ") catch |e| return tp.exit_error(e); - root = self.insert(root, cursel, stream.items, b.a) catch |e| return tp.exit_error(e); + _ = try writer.write(" "); + root = try self.insert(root, cursel, stream.items, b.a); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); } - pub fn insert_line_before(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + pub fn insert_line_before(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); var root = b.root; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { - move_cursor_begin(root, &cursel.cursor, self.plane) catch |e| return tp.exit_error(e); - root = self.insert(root, cursel, "\n", b.a) catch |e| return tp.exit_error(e); - move_cursor_left(root, &cursel.cursor, self.plane) catch |e| return tp.exit_error(e); + try move_cursor_begin(root, &cursel.cursor, self.plane); + root = try self.insert(root, cursel, "\n", b.a); + try move_cursor_left(root, &cursel.cursor, self.plane); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); } - pub fn smart_insert_line_before(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + pub fn smart_insert_line_before(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); var root = b.root; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { var leading_ws = @min(find_first_non_ws(root, cursel.cursor.row, self.plane), cursel.cursor.col); - move_cursor_begin(root, &cursel.cursor, self.plane) catch |e| return tp.exit_error(e); - root = self.insert(root, cursel, "\n", b.a) catch |e| return tp.exit_error(e); - move_cursor_left(root, &cursel.cursor, self.plane) catch |e| return tp.exit_error(e); + try move_cursor_begin(root, &cursel.cursor, self.plane); + root = try self.insert(root, cursel, "\n", b.a); + try move_cursor_left(root, &cursel.cursor, self.plane); var sfa = std.heap.stackFallback(512, self.a); const a = sfa.get(); var stream = std.ArrayList(u8).init(a); defer stream.deinit(); var writer = stream.writer(); while (leading_ws > 0) : (leading_ws -= 1) - _ = writer.write(" ") catch |e| return tp.exit_error(e); + _ = try writer.write(" "); if (stream.items.len > 0) - root = self.insert(root, cursel, stream.items, b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, cursel, stream.items, b.a); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); } - pub fn insert_line_after(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + pub fn insert_line_after(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); var root = b.root; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { - move_cursor_end(root, &cursel.cursor, self.plane) catch |e| return tp.exit_error(e); - root = self.insert(root, cursel, "\n", b.a) catch |e| return tp.exit_error(e); + try move_cursor_end(root, &cursel.cursor, self.plane); + root = try self.insert(root, cursel, "\n", b.a); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); } - pub fn smart_insert_line_after(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + pub fn smart_insert_line_after(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); var root = b.root; for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { var leading_ws = @min(find_first_non_ws(root, cursel.cursor.row, self.plane), cursel.cursor.col); - move_cursor_end(root, &cursel.cursor, self.plane) catch |e| return tp.exit_error(e); + try move_cursor_end(root, &cursel.cursor, self.plane); var sfa = std.heap.stackFallback(512, self.a); const a = sfa.get(); var stream = std.ArrayList(u8).init(a); defer stream.deinit(); var writer = stream.writer(); - _ = writer.write("\n") catch |e| return tp.exit_error(e); + _ = try writer.write("\n"); while (leading_ws > 0) : (leading_ws -= 1) - _ = writer.write(" ") catch |e| return tp.exit_error(e); + _ = try writer.write(" "); if (stream.items.len > 0) - root = self.insert(root, cursel, stream.items, b.a) catch |e| return tp.exit_error(e); + root = try self.insert(root, cursel, stream.items, b.a); }; - self.update_buf(root) catch |e| return tp.exit_error(e); + try self.update_buf(root); self.clamp(); } - pub fn enable_fast_scroll(self: *Self, _: command.Context) tp.result { + pub fn enable_fast_scroll(self: *Self, _: Context) Result { self.fast_scroll = true; } - pub fn disable_fast_scroll(self: *Self, _: command.Context) tp.result { + pub fn disable_fast_scroll(self: *Self, _: Context) Result { self.fast_scroll = false; } - pub fn enable_jump_mode(self: *Self, _: command.Context) tp.result { + pub fn enable_jump_mode(self: *Self, _: Context) Result { self.jump_mode = true; tui.current().rdr.request_mouse_cursor_pointer(true); } - pub fn disable_jump_mode(self: *Self, _: command.Context) tp.result { + pub fn disable_jump_mode(self: *Self, _: Context) Result { self.jump_mode = false; tui.current().rdr.request_mouse_cursor_text(true); } @@ -2915,7 +2918,7 @@ pub const Editor = struct { if (self.syntax) |_| self.syntax_refresh_full = true; } - pub fn dump_current_line(self: *Self, _: command.Context) tp.result { + pub fn dump_current_line(self: *Self, _: Context) Result { const root = self.buf_root() catch return; const primary = self.get_primary(); var tree = std.ArrayList(u8).init(self.a); @@ -2925,7 +2928,7 @@ pub const Editor = struct { self.logger.print("line {d}:{s}", .{ primary.cursor.row, std.fmt.fmtSliceEscapeLower(tree.items) }); } - pub fn dump_current_line_tree(self: *Self, _: command.Context) tp.result { + pub fn dump_current_line_tree(self: *Self, _: Context) Result { const root = self.buf_root() catch return; const primary = self.get_primary(); var tree = std.ArrayList(u8).init(self.a); @@ -2935,66 +2938,66 @@ pub const Editor = struct { self.logger.print("line {d} ast:{s}", .{ primary.cursor.row, std.fmt.fmtSliceEscapeLower(tree.items) }); } - pub fn undo(self: *Self, _: command.Context) tp.result { - self.restore_undo() catch |e| return tp.exit_error(e); + pub fn undo(self: *Self, _: Context) Result { + try self.restore_undo(); self.clamp(); } - pub fn redo(self: *Self, _: command.Context) tp.result { - self.restore_redo() catch |e| return tp.exit_error(e); + pub fn redo(self: *Self, _: Context) Result { + try self.restore_redo(); self.clamp(); } - pub fn open_file(self: *Self, ctx: command.Context) tp.result { + pub fn open_file(self: *Self, ctx: Context) Result { var file_path: []const u8 = undefined; if (ctx.args.match(.{tp.extract(&file_path)}) catch false) { - self.open(file_path) catch |e| return tp.exit_error(e); + try self.open(file_path); self.clamp(); - } else return tp.exit_error(error.InvalidArgument); + } else return error.InvalidArgument; } - pub fn open_scratch_buffer(self: *Self, ctx: command.Context) tp.result { + pub fn open_scratch_buffer(self: *Self, ctx: Context) Result { var file_path: []const u8 = undefined; var content: []const u8 = undefined; if (ctx.args.match(.{ tp.extract(&file_path), tp.extract(&content) }) catch false) { - self.open_scratch(file_path, content) catch |e| return tp.exit_error(e); + try self.open_scratch(file_path, content); self.clamp(); - } else return tp.exit_error(error.InvalidArgument); + } else return error.InvalidArgument; } - pub fn save_file(self: *Self, _: command.Context) tp.result { - self.save() catch |e| return tp.exit_error(e); + pub fn save_file(self: *Self, _: Context) Result { + try self.save(); } - pub fn close_file(self: *Self, _: command.Context) tp.result { + pub fn close_file(self: *Self, _: Context) Result { self.cancel_all_selections(); - self.close() catch |e| return tp.exit_error(e); + try self.close(); } - pub fn close_file_without_saving(self: *Self, _: command.Context) tp.result { + pub fn close_file_without_saving(self: *Self, _: Context) Result { self.cancel_all_selections(); - self.close_dirty() catch |e| return tp.exit_error(e); + try self.close_dirty(); } - pub fn find(self: *Self, ctx: command.Context) tp.result { + pub fn find(self: *Self, ctx: Context) Result { var query: []const u8 = undefined; if (ctx.args.match(.{tp.extract(&query)}) catch false) { try self.find_in_buffer(query); self.clamp(); - } else return tp.exit_error(error.InvalidArgument); + } else return error.InvalidArgument; } - fn find_in(self: *Self, query: []const u8, comptime find_f: ripgrep.FindF, write_buffer: bool) tp.result { - const root = self.buf_root() catch |e| return tp.exit_error(e); + fn find_in(self: *Self, query: []const u8, comptime find_f: ripgrep.FindF, write_buffer: bool) !void { + const root = try self.buf_root(); self.cancel_all_matches(); if (std.mem.indexOfScalar(u8, query, '\n')) |_| return; self.logger.print("find:{s}", .{std.fmt.fmtSliceEscapeLower(query)}); - var rg = find_f(self.a, query, "A") catch |e| return tp.exit_error(e); + var rg = try find_f(self.a, query, "A"); defer rg.deinit(); if (write_buffer) { var rg_buffer = rg.bufferedWriter(); - root.store(rg_buffer.writer()) catch |e| return tp.exit_error(e); - rg_buffer.flush() catch |e| return tp.exit_error(e); + try root.store(rg_buffer.writer()); + try rg_buffer.flush(); } } @@ -3020,12 +3023,12 @@ pub const Editor = struct { } else self.last_find_query = self.a.dupe(u8, query) catch return; } - pub fn find_in_buffer(self: *Self, query: []const u8) tp.result { + pub fn find_in_buffer(self: *Self, query: []const u8) !void { self.set_last_find_query(query); return self.find_in_buffer_async(query); } - fn find_in_buffer_sync(self: *Self, query: []const u8) tp.result { + fn find_in_buffer_sync(self: *Self, query: []const u8) !void { const Ctx = struct { matches: usize = 0, self: *Self, @@ -3037,14 +3040,14 @@ pub const Editor = struct { return error.Stop; } }; - const root = self.buf_root() catch |e| return tp.exit_error(e); + const root = try self.buf_root(); defer tp.self_pid().send(.{ "A", "done", self.match_token }) catch {}; var ctx: Ctx = .{ .self = self }; self.init_matches_update() catch {}; - root.find_all_ranges(query, &ctx, Ctx.cb, self.a) catch |e| return tp.exit_error(e); + try root.find_all_ranges(query, &ctx, Ctx.cb, self.a); } - fn find_in_buffer_async(self: *Self, query: []const u8) tp.result { + fn find_in_buffer_async(self: *Self, query: []const u8) !void { const finder = struct { a: Allocator, query: []const u8, @@ -3060,7 +3063,7 @@ pub const Editor = struct { return tp.exit_normal(); } - fn find(fdr: *finder) tp.result { + fn find(fdr: *finder) !void { const Ctx = struct { matches: usize = 0, fdr: *finder, @@ -3079,8 +3082,8 @@ pub const Editor = struct { defer fdr.parent.send(.{ "A", "done", fdr.token }) catch {}; defer fdr.a.free(fdr.query); var ctx: Ctx = .{ .fdr = fdr }; - fdr.root.find_all_ranges(fdr.query, &ctx, Ctx.cb, fdr.a) catch |e| return tp.exit_error(e); - fdr.send_batch() catch |e| return tp.exit_error(e); + try fdr.root.find_all_ranges(fdr.query, &ctx, Ctx.cb, fdr.a); + try fdr.send_batch(); } fn send_batch(fdr: *finder) !void { @@ -3101,29 +3104,29 @@ pub const Editor = struct { fdr.matches.clearRetainingCapacity(); } }; - self.init_matches_update() catch {}; - const fdr = self.a.create(finder) catch |e| return tp.exit_error(e); + self.init_matches_update(); + const fdr = try self.a.create(finder); fdr.* = .{ .a = self.a, - .query = self.a.dupe(u8, query) catch |e| return tp.exit_error(e), + .query = try self.a.dupe(u8, query), .parent = tp.self_pid(), - .root = self.buf_root() catch |e| return tp.exit_error(e), + .root = try self.buf_root(), .token = self.match_token, .matches = Match.List.init(self.a), }; - const pid = tp.spawn_link(self.a, fdr, finder.start, "editor.find") catch |e| return tp.exit_error(e); + const pid = try tp.spawn_link(self.a, fdr, finder.start, "editor.find"); pid.deinit(); } - pub fn find_in_buffer_ext(self: *Self, query: []const u8) tp.result { + pub fn find_in_buffer_ext(self: *Self, query: []const u8) !void { return self.find_in(query, ripgrep.find_in_stdin, true); } - pub fn find_in_files(self: *Self, query: []const u8) tp.result { + pub fn find_in_files(self: *Self, query: []const u8) !void { return self.find_in(query, ripgrep.find_in_files, false); } - pub fn add_match(self: *Self, m: tp.message) tp.result { + pub fn add_match(self: *Self, m: tp.message) !void { var path: []const u8 = undefined; var begin_line: usize = undefined; var begin_pos: usize = undefined; @@ -3134,7 +3137,7 @@ pub const Editor = struct { if (try m.match(.{ "A", "done", self.match_token })) { self.add_match_done(); } else if (try m.match(.{ tp.any, "batch", self.match_token, tp.extract_cbor(&batch_cbor) })) { - self.add_match_batch(batch_cbor) catch |e| return tp.exit_error(e); + try self.add_match_batch(batch_cbor); } else if (try m.match(.{ tp.any, self.match_token, tp.extract(&begin_line), tp.extract(&begin_pos), tp.extract(&end_line), tp.extract(&end_pos) })) { self.add_match_internal(begin_line, begin_pos, end_line, end_pos); } else if (try m.match(.{ tp.any, tp.extract(&begin_line), tp.extract(&begin_pos), tp.extract(&end_line), tp.extract(&end_pos) })) { @@ -3229,7 +3232,7 @@ pub const Editor = struct { return self.scan_prev_match(cursor_); } - pub fn move_cursor_next_match(self: *Self, _: command.Context) tp.result { + pub fn move_cursor_next_match(self: *Self, _: Context) Result { const primary = self.get_primary(); if (self.get_next_match(primary.cursor)) |match| { const root = self.buf_root() catch return; @@ -3239,7 +3242,7 @@ pub const Editor = struct { } } - pub fn goto_next_match(self: *Self, ctx: command.Context) tp.result { + pub fn goto_next_match(self: *Self, ctx: Context) Result { try self.send_editor_jump_source(); self.cancel_all_selections(); if (self.matches.items.len == 0) { @@ -3252,7 +3255,7 @@ pub const Editor = struct { try self.send_editor_jump_destination(); } - pub fn move_cursor_prev_match(self: *Self, _: command.Context) tp.result { + pub fn move_cursor_prev_match(self: *Self, _: Context) Result { const primary = self.get_primary(); if (self.get_prev_match(primary.cursor)) |match| { const root = self.buf_root() catch return; @@ -3263,7 +3266,7 @@ pub const Editor = struct { } } - pub fn goto_prev_match(self: *Self, ctx: command.Context) tp.result { + pub fn goto_prev_match(self: *Self, ctx: Context) Result { try self.send_editor_jump_source(); self.cancel_all_selections(); if (self.matches.items.len == 0) { @@ -3276,7 +3279,7 @@ pub const Editor = struct { try self.send_editor_jump_destination(); } - pub fn goto_next_diagnostic(self: *Self, _: command.Context) tp.result { + pub fn goto_next_diagnostic(self: *Self, _: Context) Result { if (self.diagnostics.items.len == 0) return; self.sort_diagnostics(); const primary = self.get_primary(); @@ -3287,7 +3290,7 @@ pub const Editor = struct { return self.goto_diagnostic(&self.diagnostics.items[0]); } - pub fn goto_prev_diagnostic(self: *Self, _: command.Context) tp.result { + pub fn goto_prev_diagnostic(self: *Self, _: Context) Result { if (self.diagnostics.items.len == 0) return; self.sort_diagnostics(); const primary = self.get_primary(); @@ -3300,12 +3303,12 @@ pub const Editor = struct { } } - fn goto_diagnostic(self: *Self, diag: *const Diagnostic) tp.result { + fn goto_diagnostic(self: *Self, diag: *const Diagnostic) !void { const root = self.buf_root() catch return; const primary = self.get_primary(); try self.send_editor_jump_source(); self.cancel_all_selections(); - primary.cursor.move_to(root, diag.sel.begin.row, diag.sel.begin.col, self.plane) catch |e| return tp.exit_error(e); + try primary.cursor.move_to(root, diag.sel.begin.row, diag.sel.begin.col, self.plane); self.clamp(); try self.send_editor_jump_destination(); } @@ -3322,30 +3325,30 @@ pub const Editor = struct { std.mem.sort(Diagnostic, self.diagnostics.items, {}, less_fn); } - pub fn goto_line(self: *Self, ctx: command.Context) tp.result { + pub fn goto_line(self: *Self, ctx: Context) Result { try self.send_editor_jump_source(); var line: usize = 0; if (!try ctx.args.match(.{tp.extract(&line)})) - return tp.exit_error(error.InvalidArgument); + return error.InvalidArgument; const root = self.buf_root() catch return; self.cancel_all_selections(); const primary = self.get_primary(); - primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.plane) catch |e| return tp.exit_error(e); + try primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.plane); self.clamp(); try self.send_editor_jump_destination(); } - pub fn goto_column(self: *Self, ctx: command.Context) tp.result { + pub fn goto_column(self: *Self, ctx: Context) Result { var column: usize = 0; if (!try ctx.args.match(.{tp.extract(&column)})) - return tp.exit_error(error.InvalidArgument); + return error.InvalidArgument; const root = self.buf_root() catch return; const primary = self.get_primary(); - primary.cursor.move_to(root, primary.cursor.row, @intCast(if (column < 1) 0 else column - 1), self.plane) catch |e| return tp.exit_error(e); + try primary.cursor.move_to(root, primary.cursor.row, @intCast(if (column < 1) 0 else column - 1), self.plane); self.clamp(); } - pub fn goto(self: *Self, ctx: command.Context) tp.result { + pub fn goto(self: *Self, ctx: Context) Result { try self.send_editor_jump_source(); var line: usize = 0; var column: usize = 0; @@ -3366,16 +3369,16 @@ pub const Editor = struct { })) { // self.logger.print("goto: l:{d} c:{d} {any}", .{ line, column, sel }); have_sel = true; - } else return tp.exit_error(error.InvalidArgument); + } else return error.InvalidArgument; self.cancel_all_selections(); const root = self.buf_root() catch return; const primary = self.get_primary(); - primary.cursor.move_to( + try primary.cursor.move_to( root, @intCast(if (line < 1) 0 else line - 1), @intCast(if (column < 1) 0 else column - 1), self.plane, - ) catch |e| return tp.exit_error(e); + ); if (have_sel) primary.selection = sel; if (self.view.is_visible(&primary.cursor)) self.clamp() @@ -3385,21 +3388,21 @@ pub const Editor = struct { self.need_render(); } - pub fn goto_definition(self: *Self, _: command.Context) tp.result { + pub fn goto_definition(self: *Self, _: Context) Result { const file_path = self.file_path orelse return; const primary = self.get_primary(); return project_manager.goto_definition(file_path, primary.cursor.row, primary.cursor.col); } - pub fn completion(self: *Self, _: command.Context) tp.result { + pub fn completion(self: *Self, _: Context) Result { const file_path = self.file_path orelse return; const primary = self.get_primary(); return project_manager.completion(file_path, primary.cursor.row, primary.cursor.col); } - pub fn clear_diagnostics(self: *Self, ctx: command.Context) tp.result { + pub fn clear_diagnostics(self: *Self, ctx: Context) Result { var file_path: []const u8 = undefined; - if (!try ctx.args.match(.{tp.extract(&file_path)})) return tp.exit_error(error.InvalidArgument); + if (!try ctx.args.match(.{tp.extract(&file_path)})) return error.InvalidArgument; file_path = project_manager.normalize_file_path(file_path); if (!std.mem.eql(u8, file_path, self.file_path orelse return)) return; for (self.diagnostics.items) |*d| d.deinit(self.diagnostics.allocator); @@ -3412,7 +3415,7 @@ pub const Editor = struct { self.need_render(); } - pub fn add_diagnostic(self: *Self, ctx: command.Context) tp.result { + pub fn add_diagnostic(self: *Self, ctx: Context) Result { var file_path: []const u8 = undefined; var source: []const u8 = undefined; var code: []const u8 = undefined; @@ -3429,14 +3432,14 @@ pub const Editor = struct { tp.extract(&sel.begin.col), tp.extract(&sel.end.row), tp.extract(&sel.end.col), - })) return tp.exit_error(error.InvalidArgument); + })) return error.InvalidArgument; file_path = project_manager.normalize_file_path(file_path); if (!std.mem.eql(u8, file_path, self.file_path orelse return)) return; - (self.diagnostics.addOne() catch |e| return tp.exit_error(e)).* = .{ - .source = self.diagnostics.allocator.dupe(u8, source) catch |e| return tp.exit_error(e), - .code = self.diagnostics.allocator.dupe(u8, code) catch |e| return tp.exit_error(e), - .message = self.diagnostics.allocator.dupe(u8, message) catch |e| return tp.exit_error(e), + (try self.diagnostics.addOne()).* = .{ + .source = try self.diagnostics.allocator.dupe(u8, source), + .code = try self.diagnostics.allocator.dupe(u8, code), + .message = try self.diagnostics.allocator.dupe(u8, message), .severity = severity, .sel = sel, }; @@ -3452,14 +3455,14 @@ pub const Editor = struct { self.need_render(); } - pub fn select(self: *Self, ctx: command.Context) tp.result { + pub fn select(self: *Self, ctx: Context) Result { var sel: Selection = .{}; if (!try ctx.args.match(.{ tp.extract(&sel.begin.row), tp.extract(&sel.begin.col), tp.extract(&sel.end.row), tp.extract(&sel.end.col) })) - return tp.exit_error(error.InvalidArgument); + return error.InvalidArgument; self.get_primary().selection = sel; } - pub fn format(self: *Self, ctx: command.Context) tp.result { + pub fn format(self: *Self, ctx: Context) Result { if (ctx.args.buf.len > 0 and try ctx.args.match(.{ tp.string, tp.more })) { try self.filter_cmd(ctx.args); return; @@ -3467,28 +3470,28 @@ pub const Editor = struct { if (self.syntax) |syn| if (syn.file_type.formatter) |fmtr| if (fmtr.len > 0) { var args = std.ArrayList(u8).init(self.a); const writer = args.writer(); - cbor.writeArrayHeader(writer, fmtr.len) catch |e| return tp.exit_error(e); - for (fmtr) |arg| cbor.writeValue(writer, arg) catch |e| return tp.exit_error(e); + try cbor.writeArrayHeader(writer, fmtr.len); + for (fmtr) |arg| try cbor.writeValue(writer, arg); try self.filter_cmd(.{ .buf = args.items }); return; }; return tp.exit("no formatter"); } - pub fn filter(self: *Self, ctx: command.Context) tp.result { + pub fn filter(self: *Self, ctx: Context) Result { if (!try ctx.args.match(.{ tp.string, tp.more })) - return tp.exit_error(error.InvalidArgument); + return error.InvalidArgument; try self.filter_cmd(ctx.args); } - fn filter_cmd(self: *Self, cmd: tp.message) tp.result { - if (self.filter) |_| return tp.exit_error(error.Stop); + fn filter_cmd(self: *Self, cmd: tp.message) !void { + if (self.filter) |_| return error.Stop; const root = self.buf_root() catch return; - const buf_a_ = self.buf_a() catch |e| return tp.exit_error(e); + const buf_a_ = try self.buf_a(); const primary = self.get_primary(); var sel: Selection = if (primary.selection) |sel_| sel_ else val: { var sel_: Selection = .{}; - expand_selection_to_all(root, &sel_, self.plane) catch |e| tp.exit_error(e); + try expand_selection_to_all(root, &sel_, self.plane); break :val sel_; }; const reversed = sel.begin.right_of(sel.end); @@ -3505,9 +3508,9 @@ pub const Editor = struct { errdefer self.filter_deinit(); const state = &self.filter.?; var buf: [1024]u8 = undefined; - const json = cmd.to_json(&buf) catch |e| return tp.exit_error(e); + const json = try cmd.to_json(&buf); self.logger.print("filter: start {s}", .{json}); - var sp = tp.subprocess.init(self.a, cmd, "filter", .Pipe) catch |e| return tp.exit_error(e); + var sp = try tp.subprocess.init(self.a, cmd, "filter", .Pipe); defer { sp.close() catch {}; sp.deinit(); @@ -3516,39 +3519,39 @@ pub const Editor = struct { try self.write_range(state.before_root, sel, buffer.writer(), tp.exit_error, null, self.plane); try buffer.flush(); self.logger.print("filter: sent", .{}); - state.work_root = state.work_root.delete_range(sel, buf_a_, null, self.plane) catch |e| return tp.exit_error(e); + state.work_root = try state.work_root.delete_range(sel, buf_a_, null, self.plane); } - fn filter_stdout(self: *Self, bytes: []const u8) tp.result { - const state = if (self.filter) |*s| s else return tp.exit_error(error.Stop); + fn filter_stdout(self: *Self, bytes: []const u8) !void { + const state = if (self.filter) |*s| s else return error.Stop; errdefer self.filter_deinit(); - const buf_a_ = self.buf_a() catch |e| return tp.exit_error(e); + const buf_a_ = try self.buf_a(); if (state.whole_file) |*buf| { - buf.appendSlice(bytes) catch |e| return tp.exit_error(e); + try buf.appendSlice(bytes); } else { const cursor = &state.pos.cursor; - cursor.row, cursor.col, state.work_root = state.work_root.insert_chars(cursor.row, cursor.col, bytes, buf_a_, self.plane) catch |e| return tp.exit_error(e); + cursor.row, cursor.col, state.work_root = try state.work_root.insert_chars(cursor.row, cursor.col, bytes, buf_a_, self.plane); state.bytes += bytes.len; state.chunks += 1; } } - fn filter_error(self: *Self, bytes: []const u8) tp.result { + fn filter_error(self: *Self, bytes: []const u8) void { defer self.filter_deinit(); self.logger.print("filter: ERR: {s}", .{bytes}); } - fn filter_done(self: *Self) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); + fn filter_done(self: *Self) !void { + const b = try self.buf_for_update(); const root = self.buf_root() catch return; - const state = if (self.filter) |*s| s else return tp.exit_error(error.Stop); - if (state.before_root != root) return tp.exit_error(error.Stop); + const state = if (self.filter) |*s| s else return error.Stop; + if (state.before_root != root) return error.Stop; defer self.filter_deinit(); const primary = self.get_primary(); self.cancel_all_selections(); self.cancel_all_matches(); if (state.whole_file) |buf| { - state.work_root = b.load_from_string(buf.items) catch |e| return tp.exit_error(e); + state.work_root = try b.load_from_string(buf.items); state.bytes = buf.items.len; state.chunks = 1; primary.cursor = state.old_primary.cursor; @@ -3559,7 +3562,7 @@ pub const Editor = struct { if (state.old_primary_reversed) sel.reverse(); primary.cursor = sel.end; } - self.update_buf(state.work_root) catch |e| return tp.exit_error(e); + try self.update_buf(state.work_root); primary.cursor.clamp_to_buffer(state.work_root, self.plane); self.logger.print("filter: done (bytes:{d} chunks:{d})", .{ state.bytes, state.chunks }); self.reset_syntax(); @@ -3595,10 +3598,10 @@ pub const Editor = struct { return root; } - pub fn to_upper(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, to_upper_cursel, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn to_upper(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, to_upper_cursel, b.a); + try self.update_buf(root); self.clamp(); } @@ -3624,10 +3627,10 @@ pub const Editor = struct { return root; } - pub fn to_lower(self: *Self, _: command.Context) tp.result { - const b = self.buf_for_update() catch |e| return tp.exit_error(e); - const root = self.with_cursels_mut(b.root, to_lower_cursel, b.a) catch |e| return tp.exit_error(e); - self.update_buf(root) catch |e| return tp.exit_error(e); + pub fn to_lower(self: *Self, _: Context) Result { + const b = try self.buf_for_update(); + const root = try self.with_cursels_mut(b.root, to_lower_cursel, b.a); + try self.update_buf(root); self.clamp(); } }; @@ -3694,6 +3697,10 @@ pub const EditorWidget = struct { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { + return self.receive_safe(m) catch |e| return tp.exit_error(e, @errorReturnTrace()); + } + + fn receive_safe(self: *Self, m: tp.message) !bool { var evtype: c_int = undefined; var btn: c_int = undefined; var x: c_int = undefined; @@ -3712,7 +3719,7 @@ pub const EditorWidget = struct { } else if (try m.match(.{ "filter", "stdout", tp.extract(&bytes) })) { self.editor.filter_stdout(bytes) catch {}; } else if (try m.match(.{ "filter", "stderr", tp.extract(&bytes) })) { - self.editor.filter_error(bytes) catch {}; + self.editor.filter_error(bytes); } else if (try m.match(.{ "filter", "term", tp.more })) { self.editor.filter_done() catch {}; } else if (try m.match(.{ "A", tp.more })) { @@ -3730,7 +3737,9 @@ pub const EditorWidget = struct { return true; } - fn mouse_click_event(self: *Self, evtype: c_int, btn: c_int, y: c_int, x: c_int, ypx: c_int, xpx: c_int) tp.result { + const Result = command.Result; + + fn mouse_click_event(self: *Self, evtype: c_int, btn: c_int, y: c_int, x: c_int, ypx: c_int, xpx: c_int) Result { if (evtype != event_type.PRESS) return; const ret = (switch (btn) { key.BUTTON1 => &mouse_click_button1, @@ -3747,7 +3756,7 @@ pub const EditorWidget = struct { return ret; } - fn mouse_drag_event(self: *Self, evtype: c_int, btn: c_int, y: c_int, x: c_int, ypx: c_int, xpx: c_int) tp.result { + fn mouse_drag_event(self: *Self, evtype: c_int, btn: c_int, y: c_int, x: c_int, ypx: c_int, xpx: c_int) Result { if (evtype != event_type.PRESS) return; return (switch (btn) { key.BUTTON1 => &mouse_drag_button1, @@ -3757,7 +3766,7 @@ pub const EditorWidget = struct { })(self, y, x, ypx, xpx); } - fn mouse_click_button1(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) tp.result { + fn mouse_click_button1(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result { const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x); if (self.last_btn == key.BUTTON1) { const click_time_ms = time.milliTimestamp() - self.last_btn_time_ms; @@ -3777,38 +3786,38 @@ pub const EditorWidget = struct { return; } - fn mouse_drag_button1(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) tp.result { + fn mouse_drag_button1(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result { const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x); - try self.editor.primary_drag(y_, x_); + self.editor.primary_drag(y_, x_); } - fn mouse_click_button2(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) tp.result {} + fn mouse_click_button2(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) Result {} - fn mouse_drag_button2(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) tp.result {} + fn mouse_drag_button2(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) Result {} - fn mouse_click_button3(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) tp.result { + fn mouse_click_button3(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result { const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x); try self.editor.secondary_click(y_, x_); } - fn mouse_drag_button3(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) tp.result { + fn mouse_drag_button3(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result { const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x); try self.editor.secondary_drag(y_, x_); } - fn mouse_click_button4(self: *Self, _: c_int, _: c_int, _: c_int, _: c_int) tp.result { + fn mouse_click_button4(self: *Self, _: c_int, _: c_int, _: c_int, _: c_int) Result { try self.editor.scroll_up_pageup(.{}); } - fn mouse_click_button5(self: *Self, _: c_int, _: c_int, _: c_int, _: c_int) tp.result { + fn mouse_click_button5(self: *Self, _: c_int, _: c_int, _: c_int, _: c_int) Result { try self.editor.scroll_down_pagedown(.{}); } - fn mouse_click_button8(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) tp.result { + fn mouse_click_button8(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) Result { try command.executeName("jump_back", .{}); } - fn mouse_click_button9(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) tp.result { + fn mouse_click_button9(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) Result { try command.executeName("jump_forward", .{}); } diff --git a/src/tui/editor_gutter.zig b/src/tui/editor_gutter.zig index 3c8686c..b0f2948 100644 --- a/src/tui/editor_gutter.zig +++ b/src/tui/editor_gutter.zig @@ -76,7 +76,7 @@ fn diff_symbols_clear(self: *Self) void { pub fn handle_event(self: *Self, _: tp.pid_ref, m: tp.message) tp.result { if (try m.match(.{ "E", "update", tp.more })) - return self.diff_update() catch |e| return tp.exit_error(e); + return self.diff_update() catch |e| return tp.exit_error(e, @errorReturnTrace()); if (try m.match(.{ "E", "view", tp.extract(&self.lines), tp.extract(&self.rows), tp.extract(&self.row) })) return self.update_width(); if (try m.match(.{ "E", "pos", tp.extract(&self.lines), tp.extract(&self.line), tp.more })) @@ -382,7 +382,7 @@ fn process_edit(self: *Self, kind: Kind, line: usize, offset: usize, bytes: []co pub fn filter_receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var cb: []const u8 = undefined; if (try m.match(.{ "DIFF", tp.extract_cbor(&cb) })) { - self.process_diff(cb) catch |e| return tp.exit_error(e); + self.process_diff(cb) catch |e| return tp.exit_error(e, @errorReturnTrace()); return true; } return false; diff --git a/src/tui/home.zig b/src/tui/home.zig index 5d193b7..b0e8aed 100644 --- a/src/tui/home.zig +++ b/src/tui/home.zig @@ -189,24 +189,25 @@ const Commands = command.Collection(cmds); const cmds = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn home_menu_down(self: *Self, _: Ctx) tp.result { + pub fn home_menu_down(self: *Self, _: Ctx) Result { self.menu.select_down(); } - pub fn home_menu_up(self: *Self, _: Ctx) tp.result { + pub fn home_menu_up(self: *Self, _: Ctx) Result { self.menu.select_up(); } - pub fn home_menu_activate(self: *Self, _: Ctx) tp.result { + pub fn home_menu_activate(self: *Self, _: Ctx) Result { self.menu.activate_selected(); } - pub fn home_sheeran(self: *Self, _: Ctx) tp.result { + pub fn home_sheeran(self: *Self, _: Ctx) Result { self.fire = if (self.fire) |*fire| ret: { fire.deinit(); break :ret null; - } else Fire.init(self.a, self.plane) catch |e| return tp.exit_error(e); + } else try Fire.init(self.a, self.plane); } }; diff --git a/src/tui/inputview.zig b/src/tui/inputview.zig index 5881b25..1c137f4 100644 --- a/src/tui/inputview.zig +++ b/src/tui/inputview.zig @@ -103,8 +103,8 @@ fn append(self: *Self, json: []const u8) !void { pub fn listen(self: *Self, _: tp.pid_ref, m: tp.message) tp.result { if (try m.match(.{ "M", tp.more })) return; var buf: [4096]u8 = undefined; - const json = m.to_json(&buf) catch |e| return tp.exit_error(e); - self.append(json) catch |e| return tp.exit_error(e); + const json = m.to_json(&buf) catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.append(json) catch |e| return tp.exit_error(e, @errorReturnTrace()); } pub fn receive(_: *Self, _: tp.pid_ref, _: tp.message) error{Exit}!bool { diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index d16fbb3..0f52639 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -108,7 +108,7 @@ pub fn box(self: *const Self) Box { return Box.from(self.plane); } -fn toggle_panel_view(self: *Self, view: anytype, enable_only: bool) error{Exit}!bool { +fn toggle_panel_view(self: *Self, view: anytype, enable_only: bool) !bool { var enabled = true; if (self.panels) |panels| { if (panels.get(@typeName(view))) |w| { @@ -121,12 +121,12 @@ fn toggle_panel_view(self: *Self, view: anytype, enable_only: bool) error{Exit}! enabled = false; } } else { - panels.add(view.create(self.a, self.widgets.plane) catch |e| return tp.exit_error(e)) catch |e| return tp.exit_error(e); + try panels.add(try view.create(self.a, self.widgets.plane)); } } else { - const panels = WidgetList.createH(self.a, self.widgets.widget(), "panel", .{ .static = self.box().h / 5 }) catch |e| return tp.exit_error(e); - self.widgets.add(panels.widget()) catch |e| return tp.exit_error(e); - panels.add(view.create(self.a, self.widgets.plane) catch |e| return tp.exit_error(e)) catch |e| return tp.exit_error(e); + const panels = try WidgetList.createH(self.a, self.widgets.widget(), "panel", .{ .static = self.box().h / 5 }); + try self.widgets.add(panels.widget()); + try panels.add(try view.create(self.a, self.widgets.plane)); self.panels = panels; } tui.current().resize(); @@ -141,11 +141,11 @@ fn close_all_panel_views(self: *Self) void { tui.current().resize(); } -fn toggle_view(self: *Self, view: anytype) tp.result { +fn toggle_view(self: *Self, view: anytype) !void { if (self.widgets.get(@typeName(view))) |w| { self.widgets.remove(w.*); } else { - self.widgets.add(view.create(self.a, self.plane) catch |e| return tp.exit_error(e)) catch |e| return tp.exit_error(e); + try self.widgets.add(try view.create(self.a, self.plane)); } tui.current().resize(); } @@ -153,23 +153,24 @@ fn toggle_view(self: *Self, view: anytype) tp.result { const cmds = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn quit(self: *Self, _: Ctx) tp.result { + pub fn quit(self: *Self, _: Ctx) Result { if (self.editor) |editor| if (editor.is_dirty()) return tp.exit("unsaved changes"); try tp.self_pid().send("quit"); } - pub fn quit_without_saving(_: *Self, _: Ctx) tp.result { + pub fn quit_without_saving(_: *Self, _: Ctx) Result { try tp.self_pid().send("quit"); } - pub fn open_project_cwd(self: *Self, _: Ctx) tp.result { + pub fn open_project_cwd(self: *Self, _: Ctx) Result { try project_manager.open_cwd(); _ = try self.statusbar.msg(.{ "PRJ", "open" }); } - pub fn open_project_dir(self: *Self, ctx: Ctx) tp.result { + pub fn open_project_dir(self: *Self, ctx: Ctx) Result { var project_dir: []const u8 = undefined; if (!try ctx.args.match(.{tp.extract(&project_dir)})) return; @@ -177,7 +178,7 @@ const cmds = struct { _ = try self.statusbar.msg(.{ "PRJ", "open" }); } - pub fn navigate(self: *Self, ctx: Ctx) tp.result { + pub fn navigate(self: *Self, ctx: Ctx) Result { tui.reset_drag_context(); const frame = tracy.initZone(@src(), .{ .name = "navigate" }); defer frame.deinit(); @@ -192,27 +193,27 @@ const cmds = struct { var len = len_; while (len > 0) : (len -= 1) { var field_name: []const u8 = undefined; - if (!(cbor.matchString(&iter, &field_name) catch |e| return tp.exit_error(e))) - return tp.exit_error(error.InvalidArgument); + if (!try cbor.matchString(&iter, &field_name)) + return error.InvalidArgument; if (std.mem.eql(u8, field_name, "line")) { - if (!(cbor.matchValue(&iter, cbor.extract(&line)) catch |e| return tp.exit_error(e))) - return tp.exit_error(error.InvalidArgument); + if (!try cbor.matchValue(&iter, cbor.extract(&line))) + return error.InvalidArgument; } else if (std.mem.eql(u8, field_name, "column")) { - if (!(cbor.matchValue(&iter, cbor.extract(&column)) catch |e| return tp.exit_error(e))) - return tp.exit_error(error.InvalidArgument); + if (!try cbor.matchValue(&iter, cbor.extract(&column))) + return error.InvalidArgument; } else if (std.mem.eql(u8, field_name, "file")) { - if (!(cbor.matchValue(&iter, cbor.extract(&file)) catch |e| return tp.exit_error(e))) - return tp.exit_error(error.InvalidArgument); + if (!try cbor.matchValue(&iter, cbor.extract(&file))) + return error.InvalidArgument; } else if (std.mem.eql(u8, field_name, "goto")) { - if (!(cbor.matchValue(&iter, cbor.extract_cbor(&goto_args)) catch |e| return tp.exit_error(e))) - return tp.exit_error(error.InvalidArgument); + if (!try cbor.matchValue(&iter, cbor.extract_cbor(&goto_args))) + return error.InvalidArgument; } else { - cbor.skipValue(&iter) catch |e| return tp.exit_error(e); + try cbor.skipValue(&iter); } } } else |_| if (ctx.args.match(tp.extract(&file_name)) catch false) { file = file_name; - } else return tp.exit_error(error.InvalidArgument); + } else return error.InvalidArgument; if (tp.env.get().str("project").len == 0) { try open_project_cwd(self, .{}); @@ -247,57 +248,57 @@ const cmds = struct { tui.need_render(); } - pub fn open_help(self: *Self, _: Ctx) tp.result { + pub fn open_help(self: *Self, _: Ctx) Result { tui.reset_drag_context(); try self.create_editor(); try command.executeName("open_scratch_buffer", command.fmt(.{ "help.md", @embedFile("help.md") })); tui.need_render(); } - pub fn open_config(_: *Self, _: Ctx) tp.result { - const file_name = root.get_config_file_name() catch |e| return tp.exit_error(e); + pub fn open_config(_: *Self, _: Ctx) Result { + const file_name = try root.get_config_file_name(); try tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_name } }); } - pub fn restore_session(self: *Self, _: Ctx) tp.result { + pub fn restore_session(self: *Self, _: Ctx) Result { try self.create_editor(); - self.read_restore_info() catch |e| return tp.exit_error(e); + try self.read_restore_info(); tui.need_render(); } - pub fn toggle_logview(self: *Self, _: Ctx) tp.result { + pub fn toggle_logview(self: *Self, _: Ctx) Result { self.logview_enabled = try self.toggle_panel_view(@import("logview.zig"), false); } - pub fn show_logview(self: *Self, _: Ctx) tp.result { + pub fn show_logview(self: *Self, _: Ctx) Result { self.logview_enabled = try self.toggle_panel_view(@import("logview.zig"), true); } - pub fn toggle_inputview(self: *Self, _: Ctx) tp.result { + pub fn toggle_inputview(self: *Self, _: Ctx) Result { _ = try self.toggle_panel_view(@import("inputview.zig"), false); } - pub fn toggle_inspector_view(self: *Self, _: Ctx) tp.result { + pub fn toggle_inspector_view(self: *Self, _: Ctx) Result { _ = try self.toggle_panel_view(@import("inspector_view.zig"), false); } - pub fn show_inspector_view(self: *Self, _: Ctx) tp.result { + pub fn show_inspector_view(self: *Self, _: Ctx) Result { _ = try self.toggle_panel_view(@import("inspector_view.zig"), true); } - pub fn jump_back(self: *Self, _: Ctx) tp.result { + pub fn jump_back(self: *Self, _: Ctx) Result { try self.location_history.back(location_jump); } - pub fn jump_forward(self: *Self, _: Ctx) tp.result { + pub fn jump_forward(self: *Self, _: Ctx) Result { try self.location_history.forward(location_jump); } - pub fn show_home(self: *Self, _: Ctx) tp.result { + pub fn show_home(self: *Self, _: Ctx) Result { return self.create_home(); } - pub fn gutter_mode_next(self: *Self, _: Ctx) tp.result { + pub fn gutter_mode_next(self: *Self, _: Ctx) Result { const tui_ = tui.current(); var ln = tui_.config.gutter_line_numbers; var lnr = tui_.config.gutter_line_numbers_relative; @@ -313,7 +314,7 @@ const cmds = struct { } tui_.config.gutter_line_numbers = ln; tui_.config.gutter_line_numbers_relative = lnr; - tui_.save_config() catch |e| return tp.exit_error(e); + try tui_.save_config(); if (self.widgets.get("editor_gutter")) |gutter_widget| { const gutter = if (gutter_widget.dynamic_cast(@import("editor_gutter.zig"))) |p| p else return; gutter.linenum = ln; @@ -387,8 +388,8 @@ fn location_jump(from: tp.pid_ref, file_path: []const u8, cursor: location_histo } }) catch return; } -fn clear_auto_find(self: *Self, editor: *ed.Editor) !void { - try editor.clear_matches(); +fn clear_auto_find(self: *Self, editor: *ed.Editor) void { + editor.clear_matches(); self.store_last_match_text(null); } @@ -412,11 +413,11 @@ pub fn walk(self: *Self, ctx: *anyopaque, f: Widget.WalkFn, w: *Widget) bool { return self.floating_views.walk(ctx, f) or self.widgets.walk(ctx, f, &self.widgets_widget) or f(ctx, w); } -fn create_editor(self: *Self) tp.result { +fn create_editor(self: *Self) !void { if (self.editor) |editor| if (editor.file_path) |file_path| self.push_file_stack(file_path) catch {}; - self.widgets.replace(0, Widget.empty(self.a, self.plane, .dynamic) catch |e| return tp.exit_error(e)); + self.widgets.replace(0, try Widget.empty(self.a, self.plane, .dynamic)); command.executeName("enter_mode_default", .{}) catch {}; - var editor_widget = ed.create(self.a, Widget.to(self)) catch |e| return tp.exit_error(e); + var editor_widget = try ed.create(self.a, Widget.to(self)); errdefer editor_widget.deinit(self.a); if (editor_widget.get("editor")) |editor| { editor.subscribe(EventHandler.to_unowned(self.statusbar)) catch @panic("subscribe unsupported"); @@ -443,10 +444,10 @@ fn show_home_async(_: *Self) void { tp.self_pid().send(.{ "cmd", "show_home" }) catch return; } -fn create_home(self: *Self) tp.result { +fn create_home(self: *Self) !void { tui.reset_drag_context(); if (self.editor) |_| return; - var home_widget = home.create(self.a, Widget.to(self)) catch |e| return tp.exit_error(e); + var home_widget = try home.create(self.a, Widget.to(self)); errdefer home_widget.deinit(self.a); self.widgets.replace(0, home_widget); tui.current().resize(); diff --git a/src/tui/mode/input/flow.zig b/src/tui/mode/input/flow.zig index 34eebb3..b4a2316 100644 --- a/src/tui/mode/input/flow.zig +++ b/src/tui/mode/input/flow.zig @@ -50,18 +50,18 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var text: []const u8 = undefined; if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { - try self.flush_input(); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.paste_bytes(text); + self.paste_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { return switch (evtype) { event_type.PRESS => self.mapPress(keypress, egc, modifiers), event_type.REPEAT => self.mapPress(keypress, egc, modifiers), @@ -70,7 +70,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); switch (keypress) { @@ -225,7 +225,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) tp.result { +fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { @@ -245,7 +245,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), @@ -253,32 +253,32 @@ fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { }; } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e); - self.input.appendSlice(buf[0..bytes]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + try self.input.appendSlice(buf[0..bytes]); } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { +fn insert_bytes(self: *Self, bytes: []const u8) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); - self.input.appendSlice(bytes) catch |e| return tp.exit_error(e); + try self.input.appendSlice(bytes); } -fn paste_bytes(self: *Self, bytes: []const u8) tp.result { +fn paste_bytes(self: *Self, bytes: []const u8) !void { try self.flush_input(); try command.executeName("paste", command.fmt(.{bytes})); } var insert_chars_id: ?command.ID = null; -fn flush_input(self: *Self) tp.result { +fn flush_input(self: *Self) !void { if (self.input.items.len > 0) { defer self.input.clearRetainingCapacity(); const id = insert_chars_id orelse command.get_id_cache("insert_chars", &insert_chars_id) orelse { - return tp.exit_error(error.InputTargetNotFound); + return tp.exit_error(error.InputTargetNotFound, null); }; try command.execute(id, command.fmt(.{self.input.items})); self.last_cmd = "insert_chars"; diff --git a/src/tui/mode/input/vim/insert.zig b/src/tui/mode/input/vim/insert.zig index c12af88..b8ed540 100644 --- a/src/tui/mode/input/vim/insert.zig +++ b/src/tui/mode/input/vim/insert.zig @@ -53,20 +53,20 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var text: []const u8 = undefined; if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { - try self.flush_input(); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.flush_input(); - try self.insert_bytes(text); - try self.flush_input(); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { return switch (evtype) { event_type.PRESS => self.mapPress(keypress, egc, modifiers), event_type.REPEAT => self.mapPress(keypress, egc, modifiers), @@ -75,7 +75,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); switch (keypress) { @@ -227,7 +227,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) tp.result { +fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { @@ -247,7 +247,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), @@ -255,27 +255,27 @@ fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { }; } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e); - self.input.appendSlice(buf[0..bytes]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + try self.input.appendSlice(buf[0..bytes]); } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { +fn insert_bytes(self: *Self, bytes: []const u8) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); - self.input.appendSlice(bytes) catch |e| return tp.exit_error(e); + try self.input.appendSlice(bytes); } var insert_chars_id: ?command.ID = null; -fn flush_input(self: *Self) tp.result { +fn flush_input(self: *Self) !void { if (self.input.items.len > 0) { defer self.input.clearRetainingCapacity(); const id = insert_chars_id orelse command.get_id_cache("insert_chars", &insert_chars_id) orelse { - return tp.exit_error(error.InputTargetNotFound); + return tp.exit_error(error.InputTargetNotFound, null); }; try command.execute(id, command.fmt(.{self.input.items})); self.last_cmd = "insert_chars"; @@ -306,25 +306,26 @@ const Commands = command.Collection(cmds_); const cmds_ = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn @"w"(self: *Self, _: Ctx) tp.result { + pub fn w(self: *Self, _: Ctx) Result { try self.cmd("save_file", .{}); } - pub fn @"q"(self: *Self, _: Ctx) tp.result { + pub fn q(self: *Self, _: Ctx) Result { try self.cmd("quit", .{}); } - pub fn @"q!"(self: *Self, _: Ctx) tp.result { + pub fn @"q!"(self: *Self, _: Ctx) Result { try self.cmd("quit_without_saving", .{}); } - pub fn @"wq"(self: *Self, _: Ctx) tp.result { + pub fn wq(self: *Self, _: Ctx) Result { try self.cmd("save_file", .{}); try self.cmd("quit", .{}); } - pub fn @"wq!"(self: *Self, _: Ctx) tp.result { + pub fn @"wq!"(self: *Self, _: Ctx) Result { self.cmd("save_file", .{}) catch {}; try self.cmd("quit_without_saving", .{}); } diff --git a/src/tui/mode/input/vim/normal.zig b/src/tui/mode/input/vim/normal.zig index 1b6193d..e4377b5 100644 --- a/src/tui/mode/input/vim/normal.zig +++ b/src/tui/mode/input/vim/normal.zig @@ -55,20 +55,20 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var text: []const u8 = undefined; if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { - try self.flush_input(); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.flush_input(); - try self.insert_bytes(text); - try self.flush_input(); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { return switch (evtype) { event_type.PRESS => self.mapPress(keypress, egc, modifiers), event_type.REPEAT => self.mapPress(keypress, egc, modifiers), @@ -77,7 +77,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { if (self.count > 0 and modifiers == 0 and '0' <= keypress and keypress <= '9') return self.add_count(keypress - '0'); const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); @@ -290,7 +290,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { if (keypress == key.LCTRL or keypress == key.RCTRL or keypress == key.LALT or @@ -403,7 +403,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), @@ -416,27 +416,27 @@ fn add_count(self: *Self, value: usize) void { self.count += value; } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e); - self.input.appendSlice(buf[0..bytes]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + try self.input.appendSlice(buf[0..bytes]); } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { +fn insert_bytes(self: *Self, bytes: []const u8) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); - self.input.appendSlice(bytes) catch |e| return tp.exit_error(e); + try self.input.appendSlice(bytes); } var insert_chars_id: ?command.ID = null; -fn flush_input(self: *Self) tp.result { +fn flush_input(self: *Self) !void { if (self.input.items.len > 0) { defer self.input.clearRetainingCapacity(); const id = insert_chars_id orelse command.get_id_cache("insert_chars", &insert_chars_id) orelse { - return tp.exit_error(error.InputTargetNotFound); + return tp.exit_error(error.InputTargetNotFound, null); }; try command.execute(id, command.fmt(.{self.input.items})); self.last_cmd = "insert_chars"; @@ -610,25 +610,26 @@ const Commands = command.Collection(cmds_); const cmds_ = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn @"w"(self: *Self, _: Ctx) tp.result { + pub fn w(self: *Self, _: Ctx) Result { try self.cmd("save_file", .{}); } - pub fn @"q"(self: *Self, _: Ctx) tp.result { + pub fn q(self: *Self, _: Ctx) Result { try self.cmd("quit", .{}); } - pub fn @"q!"(self: *Self, _: Ctx) tp.result { + pub fn @"q!"(self: *Self, _: Ctx) Result { try self.cmd("quit_without_saving", .{}); } - pub fn @"wq"(self: *Self, _: Ctx) tp.result { + pub fn wq(self: *Self, _: Ctx) Result { try self.cmd("save_file", .{}); try self.cmd("quit", .{}); } - pub fn @"wq!"(self: *Self, _: Ctx) tp.result { + pub fn @"wq!"(self: *Self, _: Ctx) Result { self.cmd("save_file", .{}) catch {}; try self.cmd("quit_without_saving", .{}); } diff --git a/src/tui/mode/input/vim/visual.zig b/src/tui/mode/input/vim/visual.zig index 85e279f..b5a0667 100644 --- a/src/tui/mode/input/vim/visual.zig +++ b/src/tui/mode/input/vim/visual.zig @@ -55,20 +55,20 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var text: []const u8 = undefined; if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { - try self.flush_input(); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.flush_input(); - try self.insert_bytes(text); - try self.flush_input(); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { return switch (evtype) { event_type.PRESS => self.mapPress(keypress, egc, modifiers), event_type.REPEAT => self.mapPress(keypress, egc, modifiers), @@ -77,7 +77,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { if (self.count > 0 and modifiers == 0 and '0' <= keypress and keypress <= '9') return self.add_count(keypress - '0'); const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); @@ -288,7 +288,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { if (keypress == key.LCTRL or keypress == key.RCTRL or keypress == key.LALT or @@ -363,7 +363,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), @@ -376,27 +376,27 @@ fn add_count(self: *Self, value: usize) void { self.count += value; } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e); - self.input.appendSlice(buf[0..bytes]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + try self.input.appendSlice(buf[0..bytes]); } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { +fn insert_bytes(self: *Self, bytes: []const u8) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); - self.input.appendSlice(bytes) catch |e| return tp.exit_error(e); + try self.input.appendSlice(bytes); } var insert_chars_id: ?command.ID = null; -fn flush_input(self: *Self) tp.result { +fn flush_input(self: *Self) !void { if (self.input.items.len > 0) { defer self.input.clearRetainingCapacity(); const id = insert_chars_id orelse command.get_id_cache("insert_chars", &insert_chars_id) orelse { - return tp.exit_error(error.InputTargetNotFound); + return tp.exit_error(error.InputTargetNotFound, null); }; try command.execute(id, command.fmt(.{self.input.items})); self.last_cmd = "insert_chars"; @@ -570,25 +570,26 @@ const Commands = command.Collection(cmds_); const cmds_ = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn @"w"(self: *Self, _: Ctx) tp.result { + pub fn @"w"(self: *Self, _: Ctx) Result { try self.cmd("save_file", .{}); } - pub fn @"q"(self: *Self, _: Ctx) tp.result { + pub fn @"q"(self: *Self, _: Ctx) Result { try self.cmd("quit", .{}); } - pub fn @"q!"(self: *Self, _: Ctx) tp.result { + pub fn @"q!"(self: *Self, _: Ctx) Result { try self.cmd("quit_without_saving", .{}); } - pub fn @"wq"(self: *Self, _: Ctx) tp.result { + pub fn @"wq"(self: *Self, _: Ctx) Result { try self.cmd("save_file", .{}); try self.cmd("quit", .{}); } - pub fn @"wq!"(self: *Self, _: Ctx) tp.result { + pub fn @"wq!"(self: *Self, _: Ctx) Result { self.cmd("save_file", .{}) catch {}; try self.cmd("quit_without_saving", .{}); } diff --git a/src/tui/mode/mini/find.zig b/src/tui/mode/mini/find.zig index 3af41f9..b71e699 100644 --- a/src/tui/mode/mini/find.zig +++ b/src/tui/mode/mini/find.zig @@ -74,16 +74,16 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { } if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { - self.flush_input() catch |e| return e; + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.insert_bytes(text); + self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { switch (evtype) { event_type.PRESS => try self.mapPress(keypress, egc, modifiers), event_type.REPEAT => try self.mapPress(keypress, egc, modifiers), @@ -92,7 +92,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t } } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { mod.CTRL => switch (keynormal) { @@ -150,7 +150,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), key.LALT, key.RALT => self.cmd("disable_fast_scroll", .{}), @@ -158,14 +158,14 @@ fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { }; } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { if (self.input.len + 16 > self.buf.len) try self.flush_input(); - const bytes = ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]) catch |e| return tp.exit_error(e); + const bytes = ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]) catch |e| return tp.exit_error(e, @errorReturnTrace()); self.input = self.buf[0 .. self.input.len + bytes]; } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { +fn insert_bytes(self: *Self, bytes: []const u8) !void { if (self.input.len + 16 > self.buf.len) try self.flush_input(); const newlen = self.input.len + bytes.len; @@ -175,7 +175,7 @@ fn insert_bytes(self: *Self, bytes: []const u8) tp.result { var find_cmd_id: ?command.ID = null; -fn flush_input(self: *Self) tp.result { +fn flush_input(self: *Self) !void { if (self.input.len > 0) { if (eql(u8, self.input, self.last_input)) return; diff --git a/src/tui/mode/mini/find_in_files.zig b/src/tui/mode/mini/find_in_files.zig index 5b64df2..09d41d8 100644 --- a/src/tui/mode/mini/find_in_files.zig +++ b/src/tui/mode/mini/find_in_files.zig @@ -73,16 +73,16 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { } if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { - self.flush_input() catch |e| return e; + self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.insert_bytes(text); + self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { switch (evtype) { event_type.PRESS => try self.mapPress(keypress, egc, modifiers), event_type.REPEAT => try self.mapPress(keypress, egc, modifiers), @@ -91,7 +91,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t } } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { mod.CTRL => switch (keynormal) { @@ -147,7 +147,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), key.LALT, key.RALT => self.cmd("disable_fast_scroll", .{}), @@ -155,14 +155,14 @@ fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) tp.result { }; } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { if (self.input.len + 16 > self.buf.len) try self.flush_input(); - const bytes = ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]); self.input = self.buf[0 .. self.input.len + bytes]; } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { +fn insert_bytes(self: *Self, bytes: []const u8) !void { if (self.input.len + 16 > self.buf.len) try self.flush_input(); const newlen = self.input.len + bytes.len; @@ -172,7 +172,7 @@ fn insert_bytes(self: *Self, bytes: []const u8) tp.result { var find_cmd_id: ?command.ID = null; -fn flush_input(self: *Self) tp.result { +fn flush_input(self: *Self) !void { if (self.input.len > 0) { if (eql(u8, self.input, self.last_input)) return; diff --git a/src/tui/mode/mini/open_file.zig b/src/tui/mode/mini/open_file.zig index 74086a8..7097c18 100644 --- a/src/tui/mode/mini/open_file.zig +++ b/src/tui/mode/mini/open_file.zig @@ -65,12 +65,12 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { } if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { switch (evtype) { event_type.PRESS => try self.mapPress(keypress, egc, modifiers), event_type.REPEAT => try self.mapPress(keypress, egc, modifiers), @@ -79,7 +79,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t } } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { mod.CTRL => switch (keynormal) { @@ -121,16 +121,16 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapRelease(_: *Self, _: u32, _: u32, _: u32) tp.result {} +fn mapRelease(_: *Self, _: u32, _: u32, _: u32) !void {} -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { var buf: [32]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e); - self.file_path.appendSlice(buf[0..bytes]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + try self.file_path.appendSlice(buf[0..bytes]); } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { - self.file_path.appendSlice(bytes) catch |e| return tp.exit_error(e); +fn insert_bytes(self: *Self, bytes: []const u8) !void { + try self.file_path.appendSlice(bytes); } fn cmd(_: *Self, name_: []const u8, ctx: command.Context) tp.result { diff --git a/src/tui/mode/overlay/command_palette.zig b/src/tui/mode/overlay/command_palette.zig index b94d24b..71fee7a 100644 --- a/src/tui/mode/overlay/command_palette.zig +++ b/src/tui/mode/overlay/command_palette.zig @@ -170,7 +170,7 @@ fn menu_action_execute_command(menu: **Menu.State(*Self), button: *Button.State( fn on_scroll(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!void { if (try m.match(.{ "scroll_to", tp.extract(&self.view_pos) })) { - try self.start_query(); + self.start_query() catch |e| return tp.exit_error(e, @errorReturnTrace()); } } @@ -186,14 +186,14 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var text: []const u8 = undefined; if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.insert_bytes(text); + self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { return switch (evtype) { event_type.PRESS => self.mapPress(keypress, egc, modifiers), event_type.REPEAT => self.mapPress(keypress, egc, modifiers), @@ -202,7 +202,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { mod.CTRL => switch (keynormal) { @@ -267,14 +267,14 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => if (self.menu.selected orelse 0 > 0) return self.cmd("command_palette_menu_activate", .{}), else => {}, }; } -fn start_query(self: *Self) tp.result { +fn start_query(self: *Self) !void { self.items = 0; self.menu.reset_items(); self.menu.selected = null; @@ -289,10 +289,10 @@ fn start_query(self: *Self) tp.result { defer pos += 1; if (pos < self.view_pos) continue; if (self.items < self.view_rows) - self.add_item(cmd_.name, cmd_.id, null) catch |e| return tp.exit_error(e); + try self.add_item(cmd_.name, cmd_.id, null); } } else { - _ = self.query_commands(self.inputbox.text.items) catch |e| return tp.exit_error(e); + _ = try self.query_commands(self.inputbox.text.items); } self.menu.select_down(); self.do_resize(); @@ -360,7 +360,7 @@ fn add_item(self: *Self, name: []const u8, id: command.ID, matches: ?[]const usi self.items += 1; } -fn delete_word(self: *Self) tp.result { +fn delete_word(self: *Self) !void { if (std.mem.lastIndexOfAny(u8, self.inputbox.text.items, "/\\. -_")) |pos| { self.inputbox.text.shrinkRetainingCapacity(pos); } else { @@ -371,7 +371,7 @@ fn delete_word(self: *Self) tp.result { return self.start_query(); } -fn delete_code_point(self: *Self) tp.result { +fn delete_code_point(self: *Self) !void { if (self.inputbox.text.items.len > 0) { self.inputbox.text.shrinkRetainingCapacity(self.inputbox.text.items.len - 1); self.inputbox.cursor = self.inputbox.text.items.len; @@ -380,17 +380,17 @@ fn delete_code_point(self: *Self) tp.result { return self.start_query(); } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { var buf: [6]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e); - self.inputbox.text.appendSlice(buf[0..bytes]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + try self.inputbox.text.appendSlice(buf[0..bytes]); self.inputbox.cursor = self.inputbox.text.items.len; self.view_pos = 0; return self.start_query(); } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { - self.inputbox.text.appendSlice(bytes) catch |e| return tp.exit_error(e); +fn insert_bytes(self: *Self, bytes: []const u8) !void { + try self.inputbox.text.appendSlice(bytes); self.inputbox.cursor = self.inputbox.text.items.len; self.view_pos = 0; return self.start_query(); @@ -476,8 +476,9 @@ fn restore_state(self: *Self) !void { const cmds = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn command_palette_menu_down(self: *Self, _: Ctx) tp.result { + pub fn command_palette_menu_down(self: *Self, _: Ctx) Result { if (self.menu.selected) |selected| { if (selected == self.view_rows - 1) { self.view_pos += 1; @@ -489,7 +490,7 @@ const cmds = struct { self.menu.select_down(); } - pub fn command_palette_menu_up(self: *Self, _: Ctx) tp.result { + pub fn command_palette_menu_up(self: *Self, _: Ctx) Result { if (self.menu.selected) |selected| { if (selected == 0 and self.view_pos > 0) { self.view_pos -= 1; @@ -501,7 +502,7 @@ const cmds = struct { self.menu.select_up(); } - pub fn command_palette_menu_pagedown(self: *Self, _: Ctx) tp.result { + pub fn command_palette_menu_pagedown(self: *Self, _: Ctx) Result { if (self.total_items > self.view_rows) { self.view_pos += self.view_rows; if (self.view_pos > self.total_items - self.view_rows) @@ -511,14 +512,14 @@ const cmds = struct { self.menu.select_last(); } - pub fn command_palette_menu_pageup(self: *Self, _: Ctx) tp.result { + pub fn command_palette_menu_pageup(self: *Self, _: Ctx) Result { if (self.view_pos > self.view_rows) self.view_pos -= self.view_rows; try self.start_query(); self.menu.select_first(); } - pub fn command_palette_menu_activate(self: *Self, _: Ctx) tp.result { + pub fn command_palette_menu_activate(self: *Self, _: Ctx) Result { self.menu.activate_selected(); } }; diff --git a/src/tui/mode/overlay/open_recent.zig b/src/tui/mode/overlay/open_recent.zig index 273e2e3..871ff9f 100644 --- a/src/tui/mode/overlay/open_recent.zig +++ b/src/tui/mode/overlay/open_recent.zig @@ -150,20 +150,20 @@ fn add_item(self: *Self, file_name: []const u8, matches: ?[]const u8) !void { fn receive_project_manager(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { if (try m.match(.{ "PRJ", tp.more })) { - try self.process_project_manager(m); + self.process_project_manager(m) catch |e| return tp.exit_error(e, @errorReturnTrace()); return true; } return false; } -fn process_project_manager(self: *Self, m: tp.message) tp.result { +fn process_project_manager(self: *Self, m: tp.message) !void { var file_name: []const u8 = undefined; var matches: []const u8 = undefined; var query: []const u8 = undefined; if (try m.match(.{ "PRJ", "recent", tp.extract(&file_name), tp.extract_cbor(&matches) })) { if (self.need_reset) self.reset_results(); self.longest = @max(self.longest, file_name.len); - self.add_item(file_name, matches) catch |e| return tp.exit_error(e); + try self.add_item(file_name, matches); self.menu.resize(.{ .y = 0, .x = 25, .w = @min(self.longest, max_menu_width) + 2 }); if (self.need_select_first) { self.menu.select_down(); @@ -173,7 +173,7 @@ fn process_project_manager(self: *Self, m: tp.message) tp.result { } else if (try m.match(.{ "PRJ", "recent", tp.extract(&file_name) })) { if (self.need_reset) self.reset_results(); self.longest = @max(self.longest, file_name.len); - self.add_item(file_name, null) catch |e| return tp.exit_error(e); + try self.add_item(file_name, null); self.menu.resize(.{ .y = 0, .x = 25, .w = @min(self.longest, max_menu_width) + 2 }); if (self.need_select_first) { self.menu.select_down(); @@ -198,14 +198,14 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var text: []const u8 = undefined; if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, egc, modifiers); + self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { - try self.insert_bytes(text); + self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { return switch (evtype) { event_type.PRESS => self.mapPress(keypress, egc, modifiers), event_type.REPEAT => self.mapPress(keypress, egc, modifiers), @@ -214,7 +214,7 @@ fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) t }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { +fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { mod.CTRL => switch (keynormal) { @@ -271,7 +271,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32) tp.result { +fn mapRelease(self: *Self, keypress: u32, _: u32) !void { return switch (keypress) { key.LCTRL, key.RCTRL => if (self.menu.selected orelse 0 > 0) return self.cmd("open_recent_menu_activate", .{}), else => {}, @@ -285,13 +285,13 @@ fn reset_results(self: *Self) void { self.need_select_first = true; } -fn start_query(self: *Self) tp.result { +fn start_query(self: *Self) !void { if (self.query_pending) return; self.query_pending = true; try project_manager.query_recent_files(max_recent_files, self.inputbox.text.items); } -fn delete_word(self: *Self) tp.result { +fn delete_word(self: *Self) !void { if (std.mem.lastIndexOfAny(u8, self.inputbox.text.items, "/\\. -_")) |pos| { self.inputbox.text.shrinkRetainingCapacity(pos); } else { @@ -301,7 +301,7 @@ fn delete_word(self: *Self) tp.result { return self.start_query(); } -fn delete_code_point(self: *Self) tp.result { +fn delete_code_point(self: *Self) !void { if (self.inputbox.text.items.len > 0) { self.inputbox.text.shrinkRetainingCapacity(self.inputbox.text.items.len - 1); self.inputbox.cursor = self.inputbox.text.items.len; @@ -309,16 +309,16 @@ fn delete_code_point(self: *Self) tp.result { return self.start_query(); } -fn insert_code_point(self: *Self, c: u32) tp.result { +fn insert_code_point(self: *Self, c: u32) !void { var buf: [6]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e); - self.inputbox.text.appendSlice(buf[0..bytes]) catch |e| return tp.exit_error(e); + const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + try self.inputbox.text.appendSlice(buf[0..bytes]); self.inputbox.cursor = self.inputbox.text.items.len; return self.start_query(); } -fn insert_bytes(self: *Self, bytes: []const u8) tp.result { - self.inputbox.text.appendSlice(bytes) catch |e| return tp.exit_error(e); +fn insert_bytes(self: *Self, bytes: []const u8) !void { + try self.inputbox.text.appendSlice(bytes); self.inputbox.cursor = self.inputbox.text.items.len; return self.start_query(); } @@ -339,16 +339,17 @@ const Commands = command.Collection(cmds); const cmds = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn open_recent_menu_down(self: *Self, _: Ctx) tp.result { + pub fn open_recent_menu_down(self: *Self, _: Ctx) Result { self.menu.select_down(); } - pub fn open_recent_menu_up(self: *Self, _: Ctx) tp.result { + pub fn open_recent_menu_up(self: *Self, _: Ctx) Result { self.menu.select_up(); } - pub fn open_recent_menu_activate(self: *Self, _: Ctx) tp.result { + pub fn open_recent_menu_activate(self: *Self, _: Ctx) Result { self.menu.activate_selected(); } }; diff --git a/src/tui/status/minilog.zig b/src/tui/status/minilog.zig index 2d416af..7689f90 100644 --- a/src/tui/status/minilog.zig +++ b/src/tui/status/minilog.zig @@ -71,8 +71,8 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { fn receive_log(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var clear_msg_num: usize = 0; if (try m.match(.{ "log", tp.more })) { - logview.process_log(m) catch |e| return tp.exit_error(e); - self.process_log(m) catch |e| return tp.exit_error(e); + logview.process_log(m) catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.process_log(m) catch |e| return tp.exit_error(e, @errorReturnTrace()); return true; } else if (try m.match(.{ "MINILOG", tp.extract(&clear_msg_num) })) { if (clear_msg_num == self.msg_counter) diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 1a805bd..1e2481f 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -72,7 +72,7 @@ pub fn spawn(a: Allocator, ctx: *tp.context, eh: anytype, env: ?*const tp.env) ! fn start(args: StartArgs) tp.result { _ = tp.set_trap(true); - var self = init(args.a) catch |e| return tp.exit_error(e); + var self = init(args.a) catch |e| return tp.exit_error(e, @errorReturnTrace()); errdefer self.deinit(); tp.receive(&self.receiver); } @@ -144,7 +144,7 @@ fn init(a: Allocator) !*Self { return self; } -fn init_delayed(self: *Self) tp.result { +fn init_delayed(self: *Self) !void { if (self.input_mode) |_| {} else return cmds.enter_mode(self, command.Context.fmt(.{self.config.input_mode})); } @@ -171,7 +171,7 @@ fn deinit(self: *Self) void { fn listen_sigwinch(self: *Self) tp.result { if (self.sigwinch_signal) |old| old.deinit(); - self.sigwinch_signal = tp.signal.init(std.posix.SIG.WINCH, tp.message.fmt(.{"sigwinch"})) catch |e| return tp.exit_error(e); + self.sigwinch_signal = tp.signal.init(std.posix.SIG.WINCH, tp.message.fmt(.{"sigwinch"})) catch |e| return tp.exit_error(e, @errorReturnTrace()); } fn receive(self: *Self, from: tp.pid_ref, m: tp.message) tp.result { @@ -183,18 +183,18 @@ fn receive(self: *Self, from: tp.pid_ref, m: tp.message) tp.result { self.receive_safe(from, m) catch |e| { if (std.mem.eql(u8, "normal", tp.error_text())) - return e; + return error.Exit; if (std.mem.eql(u8, "restart", tp.error_text())) - return e; - self.logger.err("UI", e); + return error.Exit; + self.logger.err("UI", tp.exit_error(e, @errorReturnTrace())); }; } -fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) tp.result { +fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void { var input: []const u8 = undefined; var text: []const u8 = undefined; if (try m.match(.{ "VXS", tp.extract(&input), tp.extract(&text) })) { - self.rdr.process_input_event(input, if (text.len > 0) text else null) catch |e| return tp.exit_error(e); + try self.rdr.process_input_event(input, if (text.len > 0) text else null); try self.dispatch_flush_input_event(); if (self.unrendered_input_events_count > 0 and !self.frame_clock_running) need_render(); @@ -355,10 +355,10 @@ fn render(self: *Self) void { } } -fn dispatch_flush_input_event(self: *Self) tp.result { +fn dispatch_flush_input_event(self: *Self) !void { var buf: [32]u8 = undefined; if (self.input_mode) |mode| - try mode.handler.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{"F"}) catch |e| return tp.exit_error(e)); + try mode.handler.send(tp.self_pid(), try tp.message.fmtbuf(&buf, .{"F"})); } fn dispatch_input(ctx: *anyopaque, cbor_msg: []const u8) void { @@ -383,10 +383,8 @@ fn dispatch_mouse(ctx: *anyopaque, y: c_int, x: c_int, cbor_msg: []const u8) voi const m: tp.message = .{ .buf = cbor_msg }; const from = tp.self_pid(); self.unrendered_input_events_count += 1; - if (self.drag_source) |_| - self.send_mouse_drag(y, x, from, m) catch |e| self.logger.err("dispatch mouse", e) - else - self.send_mouse(y, x, from, m) catch |e| self.logger.err("dispatch mouse", e); + const send_func = if (self.drag_source) |_| &send_mouse_drag else &send_mouse; + send_func(self, y, x, from, m) catch |e| self.logger.err("dispatch mouse", e); self.drag_source = null; } @@ -462,16 +460,16 @@ fn send_mouse(self: *Self, y: c_int, x: c_int, from: tp.pid_ref, m: tp.message) var buf: [256]u8 = undefined; if (self.hover_focus) |h| { if (self.is_live_widget_ptr(h)) - _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e)); + _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e, @errorReturnTrace())); } self.hover_focus = w; - _ = try w.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", true }) catch |e| return tp.exit_error(e)); + _ = try w.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", true }) catch |e| return tp.exit_error(e, @errorReturnTrace())); } _ = try w.send(from, m); } else { if (self.hover_focus) |h| { var buf: [256]u8 = undefined; - _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e)); + _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e, @errorReturnTrace())); } self.hover_focus = null; } @@ -488,15 +486,15 @@ fn send_mouse_drag(self: *Self, y: c_int, x: c_int, from: tp.pid_ref, m: tp.mess var buf: [256]u8 = undefined; if (self.hover_focus) |h| { if (self.is_live_widget_ptr(h)) - _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e)); + _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e, @errorReturnTrace())); } self.hover_focus = w; - _ = try w.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", true }) catch |e| return tp.exit_error(e)); + _ = try w.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", true }) catch |e| return tp.exit_error(e, @errorReturnTrace())); } } else { if (self.hover_focus) |h| { var buf: [256]u8 = undefined; - _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e)); + _ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e, @errorReturnTrace())); } self.hover_focus = null; } @@ -510,83 +508,84 @@ pub fn save_config(self: *const Self) !void { const cmds = struct { pub const Target = Self; const Ctx = command.Context; + const Result = command.Result; - pub fn restart(_: *Self, _: Ctx) tp.result { + pub fn restart(_: *Self, _: Ctx) Result { try tp.self_pid().send("restart"); } - pub fn theme_next(self: *Self, _: Ctx) tp.result { + pub fn theme_next(self: *Self, _: Ctx) Result { self.theme = get_next_theme_by_name(self.theme.name); self.config.theme = self.theme.name; self.logger.print("theme: {s}", .{self.theme.description}); - self.save_config() catch |e| return tp.exit_error(e); + try self.save_config(); } - pub fn theme_prev(self: *Self, _: Ctx) tp.result { + pub fn theme_prev(self: *Self, _: Ctx) Result { self.theme = get_prev_theme_by_name(self.theme.name); self.config.theme = self.theme.name; self.logger.print("theme: {s}", .{self.theme.description}); - self.save_config() catch |e| return tp.exit_error(e); + try self.save_config(); } - pub fn toggle_whitespace(self: *Self, _: Ctx) tp.result { + pub fn toggle_whitespace(self: *Self, _: Ctx) Result { self.config.show_whitespace = !self.config.show_whitespace; self.logger.print("show_whitspace {s}", .{if (self.config.show_whitespace) "enabled" else "disabled"}); - self.save_config() catch |e| return tp.exit_error(e); + try self.save_config(); var buf: [32]u8 = undefined; - const m = tp.message.fmtbuf(&buf, .{ "show_whitespace", self.config.show_whitespace }) catch |e| return tp.exit_error(e); + const m = try tp.message.fmtbuf(&buf, .{ "show_whitespace", self.config.show_whitespace }); _ = try self.send_widgets(tp.self_pid(), m); } - pub fn toggle_input_mode(self: *Self, _: Ctx) tp.result { + pub fn toggle_input_mode(self: *Self, _: Ctx) Result { self.config.input_mode = if (std.mem.eql(u8, self.config.input_mode, "flow")) "vim/normal" else "flow"; - self.save_config() catch |e| return tp.exit_error(e); + try self.save_config(); return enter_mode(self, Ctx.fmt(.{self.config.input_mode})); } - pub fn enter_mode(self: *Self, ctx: Ctx) tp.result { + pub fn enter_mode(self: *Self, ctx: Ctx) Result { var mode: []const u8 = undefined; if (!try ctx.args.match(.{tp.extract(&mode)})) - return tp.exit_error(error.InvalidArgument); + return tp.exit_error(error.InvalidArgument, null); if (self.mini_mode) |_| try exit_mini_mode(self, .{}); if (self.input_mode_outer) |_| try exit_overlay_mode(self, .{}); if (self.input_mode) |*m| m.deinit(); self.input_mode = if (std.mem.eql(u8, mode, "vim/normal")) - @import("mode/input/vim/normal.zig").create(self.a) catch |e| return tp.exit_error(e) + try @import("mode/input/vim/normal.zig").create(self.a) else if (std.mem.eql(u8, mode, "vim/insert")) - @import("mode/input/vim/insert.zig").create(self.a) catch |e| return tp.exit_error(e) + try @import("mode/input/vim/insert.zig").create(self.a) else if (std.mem.eql(u8, mode, "vim/visual")) - @import("mode/input/vim/visual.zig").create(self.a) catch |e| return tp.exit_error(e) + try @import("mode/input/vim/visual.zig").create(self.a) else if (std.mem.eql(u8, mode, "flow")) - @import("mode/input/flow.zig").create(self.a) catch |e| return tp.exit_error(e) + try @import("mode/input/flow.zig").create(self.a) else if (std.mem.eql(u8, mode, "home")) - @import("mode/input/home.zig").create(self.a) catch |e| return tp.exit_error(e) + try @import("mode/input/home.zig").create(self.a) else ret: { self.logger.print("unknown mode {s}", .{mode}); - break :ret @import("mode/input/flow.zig").create(self.a) catch |e| return tp.exit_error(e); + break :ret try @import("mode/input/flow.zig").create(self.a); }; // self.logger.print("input mode: {s}", .{(self.input_mode orelse return).description}); } - pub fn enter_mode_default(self: *Self, _: Ctx) tp.result { + pub fn enter_mode_default(self: *Self, _: Ctx) Result { return enter_mode(self, Ctx.fmt(.{self.config.input_mode})); } - pub fn open_command_palette(self: *Self, _: Ctx) tp.result { + pub fn open_command_palette(self: *Self, _: Ctx) Result { if (self.mini_mode) |_| try exit_mini_mode(self, .{}); if (self.input_mode_outer) |_| try exit_overlay_mode(self, .{}); self.input_mode_outer = self.input_mode; - self.input_mode = @import("mode/overlay/command_palette.zig").create(self.a) catch |e| return tp.exit_error(e); + self.input_mode = try @import("mode/overlay/command_palette.zig").create(self.a); } - pub fn open_recent(self: *Self, _: Ctx) tp.result { + pub fn open_recent(self: *Self, _: Ctx) Result { if (self.mini_mode) |_| try exit_mini_mode(self, .{}); if (self.input_mode_outer) |_| try exit_overlay_mode(self, .{}); self.input_mode_outer = self.input_mode; - self.input_mode = @import("mode/overlay/open_recent.zig").create(self.a) catch |e| return tp.exit_error(e); + self.input_mode = try @import("mode/overlay/open_recent.zig").create(self.a); } - pub fn exit_overlay_mode(self: *Self, _: Ctx) tp.result { + pub fn exit_overlay_mode(self: *Self, _: Ctx) Result { if (self.input_mode_outer == null) return; defer { self.input_mode = self.input_mode_outer; @@ -595,29 +594,29 @@ const cmds = struct { if (self.input_mode) |*mode| mode.deinit(); } - pub fn enter_find_mode(self: *Self, ctx: Ctx) tp.result { + pub fn enter_find_mode(self: *Self, ctx: Ctx) Result { return enter_mini_mode(self, @import("mode/mini/find.zig"), ctx); } - pub fn enter_find_in_files_mode(self: *Self, ctx: Ctx) tp.result { + pub fn enter_find_in_files_mode(self: *Self, ctx: Ctx) Result { return enter_mini_mode(self, @import("mode/mini/find_in_files.zig"), ctx); } - pub fn enter_goto_mode(self: *Self, ctx: Ctx) tp.result { + pub fn enter_goto_mode(self: *Self, ctx: Ctx) Result { return enter_mini_mode(self, @import("mode/mini/goto.zig"), ctx); } - pub fn enter_move_to_char_mode(self: *Self, ctx: Ctx) tp.result { + pub fn enter_move_to_char_mode(self: *Self, ctx: Ctx) Result { return enter_mini_mode(self, @import("mode/mini/move_to_char.zig"), ctx); } - pub fn enter_open_file_mode(self: *Self, ctx: Ctx) tp.result { + pub fn enter_open_file_mode(self: *Self, ctx: Ctx) Result { return enter_mini_mode(self, @import("mode/mini/open_file.zig"), ctx); } const MiniModeFactory = fn (Allocator, Ctx) error{ NotFound, OutOfMemory }!EventHandler; - fn enter_mini_mode(self: *Self, comptime mode: anytype, ctx: Ctx) tp.result { + fn enter_mini_mode(self: *Self, comptime mode: anytype, ctx: Ctx) Result { if (self.mini_mode) |_| try exit_mini_mode(self, .{}); if (self.input_mode_outer) |_| try exit_overlay_mode(self, .{}); self.input_mode_outer = self.input_mode; @@ -626,7 +625,7 @@ const cmds = struct { self.input_mode_outer = null; self.mini_mode = null; } - const mode_instance = mode.create(self.a, ctx) catch |e| return tp.exit_error(e); + const mode_instance = try mode.create(self.a, ctx); self.input_mode = .{ .handler = mode_instance.handler(), .name = mode_instance.name(), @@ -635,7 +634,7 @@ const cmds = struct { self.mini_mode = .{}; } - pub fn exit_mini_mode(self: *Self, _: Ctx) tp.result { + pub fn exit_mini_mode(self: *Self, _: Ctx) Result { if (self.mini_mode) |_| {} else return; defer { self.input_mode = self.input_mode_outer;