Compare commits

..

2 commits

13 changed files with 119 additions and 53 deletions

View file

@ -167,7 +167,7 @@ fn get_mode_binding_set(mode_name: []const u8, insert_command: []const u8) LoadE
return binding_set; return binding_set;
} }
const LoadError = (error{ NotFound, NotAnObject } || std.json.ParseError(std.json.Scanner) || parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError); pub const LoadError = (error{ NotFound, NotAnObject } || std.json.ParseError(std.json.Scanner) || parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError);
///A collection of modes that represent a switchable editor emulation ///A collection of modes that represent a switchable editor emulation
const Namespace = struct { const Namespace = struct {

View file

@ -16,7 +16,7 @@ pub const Selection = struct {
end: Cursor = Cursor{}, end: Cursor = Cursor{},
}; };
pub fn create() !Self { pub fn create() error{ OutOfMemory, ThespianSpawnFailed }!Self {
return .{ .pid = try Process.create() }; return .{ .pid = try Process.create() };
} }
@ -45,7 +45,7 @@ const Process = struct {
selection: ?Selection = null, selection: ?Selection = null,
}; };
pub fn create() !tp.pid { pub fn create() error{ OutOfMemory, ThespianSpawnFailed }!tp.pid {
const self = try outer_a.create(Process); const self = try outer_a.create(Process);
self.* = .{ self.* = .{
.arena = std.heap.ArenaAllocator.init(outer_a), .arena = std.heap.ArenaAllocator.init(outer_a),

View file

@ -551,7 +551,9 @@ fn read_nested_include_files(T: type, allocator: std.mem.Allocator, conf: *T, bu
}; };
} }
pub fn write_config(conf: anytype, allocator: std.mem.Allocator) !void { pub const ConfigWriteError = error{ CreateConfigFileFailed, WriteConfigFileFailed };
pub fn write_config(conf: anytype, allocator: std.mem.Allocator) (ConfigDirError || ConfigWriteError)!void {
config_mutex.lock(); config_mutex.lock();
defer config_mutex.unlock(); defer config_mutex.unlock();
_ = allocator; _ = allocator;
@ -560,14 +562,20 @@ pub fn write_config(conf: anytype, allocator: std.mem.Allocator) !void {
// return write_json_file(@TypeOf(conf), conf, allocator, try get_app_config_file_name(application_name, @typeName(@TypeOf(conf)))); // return write_json_file(@TypeOf(conf), conf, allocator, try get_app_config_file_name(application_name, @typeName(@TypeOf(conf))));
} }
fn write_text_config_file(comptime T: type, data: T, file_name: []const u8) !void { fn write_text_config_file(comptime T: type, data: T, file_name: []const u8) ConfigWriteError!void {
var file = try std.fs.createFileAbsolute(file_name, .{ .truncate = true }); var file = std.fs.createFileAbsolute(file_name, .{ .truncate = true }) catch |e| {
std.log.err("createFileAbsolute failed with {any} for: {s}", .{ e, file_name });
return error.CreateConfigFileFailed;
};
defer file.close(); defer file.close();
const writer = file.writer(); const writer = file.writer();
return write_config_to_writer(T, data, writer); write_config_to_writer(T, data, writer) catch |e| {
std.log.err("write file failed with {any} for: {s}", .{ e, file_name });
return error.WriteConfigFileFailed;
};
} }
pub fn write_config_to_writer(comptime T: type, data: T, writer: anytype) !void { pub fn write_config_to_writer(comptime T: type, data: T, writer: anytype) @TypeOf(writer).Error!void {
const default: T = .{}; const default: T = .{};
inline for (@typeInfo(T).@"struct".fields) |field_info| { inline for (@typeInfo(T).@"struct".fields) |field_info| {
if (config_eql( if (config_eql(
@ -650,7 +658,15 @@ pub fn get_config_dir() ![]const u8 {
return get_app_config_dir(application_name); return get_app_config_dir(application_name);
} }
fn get_app_config_dir(appname: []const u8) ![]const u8 { pub const ConfigDirError = error{
NoSpaceLeft,
MakeConfigDirFailed,
MakeHomeConfigDirFailed,
MakeAppConfigDirFailed,
AppConfigDirUnavailable,
};
fn get_app_config_dir(appname: []const u8) ConfigDirError![]const u8 {
const a = std.heap.c_allocator; const a = std.heap.c_allocator;
const local = struct { const local = struct {
var config_dir_buffer: [std.posix.PATH_MAX]u8 = undefined; var config_dir_buffer: [std.posix.PATH_MAX]u8 = undefined;
@ -666,7 +682,7 @@ fn get_app_config_dir(appname: []const u8) ![]const u8 {
const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config", .{home}); const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config", .{home});
std.fs.makeDirAbsolute(dir) catch |e| switch (e) { std.fs.makeDirAbsolute(dir) catch |e| switch (e) {
error.PathAlreadyExists => {}, error.PathAlreadyExists => {},
else => return e, else => return error.MakeHomeConfigDirFailed,
}; };
break :ret try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config/{s}", .{ home, appname }); break :ret try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config/{s}", .{ home, appname });
} else if (builtin.os.tag == .windows) ret: { } else if (builtin.os.tag == .windows) ret: {
@ -675,7 +691,7 @@ fn get_app_config_dir(appname: []const u8) ![]const u8 {
const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ appdata, appname }); const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ appdata, appname });
std.fs.makeDirAbsolute(dir) catch |e| switch (e) { std.fs.makeDirAbsolute(dir) catch |e| switch (e) {
error.PathAlreadyExists => {}, error.PathAlreadyExists => {},
else => return e, else => return error.MakeAppConfigDirFailed,
}; };
break :ret dir; break :ret dir;
} else return error.AppConfigDirUnavailable; } else return error.AppConfigDirUnavailable;
@ -684,7 +700,7 @@ fn get_app_config_dir(appname: []const u8) ![]const u8 {
local.config_dir = config_dir; local.config_dir = config_dir;
std.fs.makeDirAbsolute(config_dir) catch |e| switch (e) { std.fs.makeDirAbsolute(config_dir) catch |e| switch (e) {
error.PathAlreadyExists => {}, error.PathAlreadyExists => {},
else => return e, else => return error.MakeConfigDirFailed,
}; };
var keybind_dir_buffer: [std.posix.PATH_MAX]u8 = undefined; var keybind_dir_buffer: [std.posix.PATH_MAX]u8 = undefined;
@ -784,11 +800,11 @@ fn get_app_state_dir(appname: []const u8) ![]const u8 {
return state_dir; return state_dir;
} }
fn get_app_config_file_name(appname: []const u8, comptime base_name: []const u8) ![]const u8 { fn get_app_config_file_name(appname: []const u8, comptime base_name: []const u8) ConfigDirError![]const u8 {
return get_app_config_dir_file_name(appname, base_name ++ ".json"); return get_app_config_dir_file_name(appname, base_name ++ ".json");
} }
fn get_app_config_dir_file_name(appname: []const u8, comptime config_file_name: []const u8) ![]const u8 { fn get_app_config_dir_file_name(appname: []const u8, comptime config_file_name: []const u8) ConfigDirError![]const u8 {
const local = struct { const local = struct {
var config_file_buffer: [std.posix.PATH_MAX]u8 = undefined; var config_file_buffer: [std.posix.PATH_MAX]u8 = undefined;
}; };

View file

@ -41,7 +41,20 @@ logger: log.Logger,
loop: Loop, loop: Loop,
pub fn init(allocator: std.mem.Allocator, handler_ctx: *anyopaque, no_alternate: bool, _: *const fn (ctx: *anyopaque) void) !Self { pub const Error = error{
UnexpectedRendererEvent,
OutOfMemory,
IntegerTooLarge,
IntegerTooSmall,
InvalidType,
TooShort,
Utf8CannotEncodeSurrogateHalf,
CodepointTooLarge,
TtyInitError,
TtyWriteError,
} || std.Thread.SpawnError;
pub fn init(allocator: std.mem.Allocator, handler_ctx: *anyopaque, no_alternate: bool, _: *const fn (ctx: *anyopaque) void) Error!Self {
const opts: vaxis.Vaxis.Options = .{ const opts: vaxis.Vaxis.Options = .{
.kitty_keyboard_flags = .{ .kitty_keyboard_flags = .{
.disambiguate = true, .disambiguate = true,
@ -54,7 +67,7 @@ pub fn init(allocator: std.mem.Allocator, handler_ctx: *anyopaque, no_alternate:
}; };
return .{ return .{
.allocator = allocator, .allocator = allocator,
.tty = try vaxis.Tty.init(), .tty = vaxis.Tty.init() catch return error.TtyInitError,
.vx = try vaxis.init(allocator, opts), .vx = try vaxis.init(allocator, opts),
.no_alternate = no_alternate, .no_alternate = no_alternate,
.event_buffer = std.ArrayList(u8).init(allocator), .event_buffer = std.ArrayList(u8).init(allocator),
@ -93,19 +106,19 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_
return std.debug.defaultPanic(msg, ret_addr orelse @returnAddress()); return std.debug.defaultPanic(msg, ret_addr orelse @returnAddress());
} }
pub fn run(self: *Self) !void { pub fn run(self: *Self) Error!void {
self.vx.sgr = .legacy; self.vx.sgr = .legacy;
self.vx.conpty_hacks = true; self.vx.conpty_hacks = true;
panic_cleanup = .{ .allocator = self.allocator, .tty = &self.tty, .vx = &self.vx }; panic_cleanup = .{ .allocator = self.allocator, .tty = &self.tty, .vx = &self.vx };
if (!self.no_alternate) try self.vx.enterAltScreen(self.tty.anyWriter()); if (!self.no_alternate) self.vx.enterAltScreen(self.tty.anyWriter()) catch return error.TtyWriteError;
if (builtin.os.tag == .windows) { if (builtin.os.tag == .windows) {
try self.resize(.{ .rows = 25, .cols = 80, .x_pixel = 0, .y_pixel = 0 }); // dummy resize to fully init vaxis try self.resize(.{ .rows = 25, .cols = 80, .x_pixel = 0, .y_pixel = 0 }); // dummy resize to fully init vaxis
} else { } else {
try self.sigwinch(); self.sigwinch() catch return error.TtyWriteError;
} }
try self.vx.setBracketedPaste(self.tty.anyWriter(), true); self.vx.setBracketedPaste(self.tty.anyWriter(), true) catch return error.TtyWriteError;
try self.vx.queryTerminalSend(self.tty.anyWriter()); self.vx.queryTerminalSend(self.tty.anyWriter()) catch return error.TtyWriteError;
self.loop = Loop.init(&self.tty, &self.vx); self.loop = Loop.init(&self.tty, &self.vx);
try self.loop.start(); try self.loop.start();
@ -122,8 +135,8 @@ pub fn sigwinch(self: *Self) !void {
try self.resize(try vaxis.Tty.getWinsize(self.input_fd_blocking())); try self.resize(try vaxis.Tty.getWinsize(self.input_fd_blocking()));
} }
fn resize(self: *Self, ws: vaxis.Winsize) !void { fn resize(self: *Self, ws: vaxis.Winsize) error{ TtyWriteError, OutOfMemory }!void {
try self.vx.resize(self.allocator, self.tty.anyWriter(), ws); self.vx.resize(self.allocator, self.tty.anyWriter(), ws) catch return error.TtyWriteError;
self.vx.queueRefresh(); self.vx.queueRefresh();
if (self.dispatch_event) |f| f(self.handler_ctx, try self.fmtmsg(.{"resize"})); if (self.dispatch_event) |f| f(self.handler_ctx, try self.fmtmsg(.{"resize"}));
} }
@ -147,7 +160,7 @@ pub fn input_fd_blocking(self: Self) i32 {
return self.tty.fd; return self.tty.fd;
} }
pub fn process_renderer_event(self: *Self, msg: []const u8) !void { pub fn process_renderer_event(self: *Self, msg: []const u8) Error!void {
var input_: []const u8 = undefined; var input_: []const u8 = undefined;
var text_: []const u8 = undefined; var text_: []const u8 = undefined;
if (!try cbor.match(msg, .{ "RDR", cbor.extract(&input_), cbor.extract(&text_) })) if (!try cbor.match(msg, .{ "RDR", cbor.extract(&input_), cbor.extract(&text_) }))
@ -268,7 +281,7 @@ pub fn process_renderer_event(self: *Self, msg: []const u8) !void {
.cap_da1 => { .cap_da1 => {
self.queries_done = true; self.queries_done = true;
self.vx.enableDetectedFeatures(self.tty.anyWriter()) catch |e| self.logger.err("enable features", e); self.vx.enableDetectedFeatures(self.tty.anyWriter()) catch |e| self.logger.err("enable features", e);
try self.vx.setMouseMode(self.tty.anyWriter(), true); self.vx.setMouseMode(self.tty.anyWriter(), true) catch return error.TtyWriteError;
}, },
.cap_kitty_keyboard => { .cap_kitty_keyboard => {
self.logger.print("kitty keyboard capability detected", .{}); self.logger.print("kitty keyboard capability detected", .{});
@ -287,7 +300,7 @@ pub fn process_renderer_event(self: *Self, msg: []const u8) !void {
} }
} }
fn fmtmsg(self: *Self, value: anytype) ![]const u8 { fn fmtmsg(self: *Self, value: anytype) std.ArrayList(u8).Writer.Error![]const u8 {
self.event_buffer.clearRetainingCapacity(); self.event_buffer.clearRetainingCapacity();
try cbor.writeValue(self.event_buffer.writer(), value); try cbor.writeValue(self.event_buffer.writer(), value);
return self.event_buffer.items; return self.event_buffer.items;
@ -329,7 +342,7 @@ fn handle_bracketed_paste_end(self: *Self) !void {
if (self.dispatch_event) |f| f(self.handler_ctx, try self.fmtmsg(.{ "system_clipboard", self.bracketed_paste_buffer.items })); if (self.dispatch_event) |f| f(self.handler_ctx, try self.fmtmsg(.{ "system_clipboard", self.bracketed_paste_buffer.items }));
} }
fn handle_bracketed_paste_error(self: *Self, e: anytype) !void { fn handle_bracketed_paste_error(self: *Self, e: Error) !void {
self.logger.err("bracketed paste", e); self.logger.err("bracketed paste", e);
self.bracketed_paste_buffer.clearAndFree(); self.bracketed_paste_buffer.clearAndFree();
self.bracketed_paste = false; self.bracketed_paste = false;
@ -508,7 +521,7 @@ const Loop = struct {
} }
/// spawns the input thread to read input from the tty /// spawns the input thread to read input from the tty
pub fn start(self: *Loop) !void { pub fn start(self: *Loop) std.Thread.SpawnError!void {
if (self.thread) |_| return; if (self.thread) |_| return;
self.thread = try std.Thread.spawn(.{}, Loop.ttyRun, .{self}); self.thread = try std.Thread.spawn(.{}, Loop.ttyRun, .{self});
} }

View file

@ -20,6 +20,18 @@ const DropWriter = gui.DropWriter;
pub const style = StyleBits; pub const style = StyleBits;
pub const styles = @import("tuirenderer").styles; pub const styles = @import("tuirenderer").styles;
pub const Error = error{
UnexpectedRendererEvent,
OutOfMemory,
IntegerTooLarge,
IntegerTooSmall,
InvalidType,
TooShort,
Utf8CannotEncodeSurrogateHalf,
CodepointTooLarge,
VaxisResizeError,
} || std.Thread.SpawnError;
pub const panic = messageBoxThenPanic(.{ .title = "Flow Panic" }); pub const panic = messageBoxThenPanic(.{ .title = "Flow Panic" });
threadlocal var thread_is_panicing = false; threadlocal var thread_is_panicing = false;
@ -80,7 +92,7 @@ pub fn init(
handler_ctx: *anyopaque, handler_ctx: *anyopaque,
no_alternate: bool, no_alternate: bool,
dispatch_initialized: *const fn (ctx: *anyopaque) void, dispatch_initialized: *const fn (ctx: *anyopaque) void,
) !Self { ) Error!Self {
std.debug.assert(!global.init_called); std.debug.assert(!global.init_called);
global.init_called = true; global.init_called = true;
@ -116,16 +128,16 @@ pub fn deinit(self: *Self) void {
self.title_buf.deinit(); self.title_buf.deinit();
} }
pub fn run(self: *Self) !void { pub fn run(self: *Self) Error!void {
if (self.thread) |_| return; if (self.thread) |_| return;
// dummy resize to fully init vaxis // dummy resize to fully init vaxis
const drop_writer = DropWriter{}; const drop_writer = DropWriter{};
try self.vx.resize( self.vx.resize(
self.allocator, self.allocator,
drop_writer.writer().any(), drop_writer.writer().any(),
.{ .rows = 25, .cols = 80, .x_pixel = 0, .y_pixel = 0 }, .{ .rows = 25, .cols = 80, .x_pixel = 0, .y_pixel = 0 },
); ) catch return error.VaxisResizeError;
self.thread = try gui.start(); self.thread = try gui.start();
} }
@ -164,7 +176,7 @@ pub fn stdplane(self: *Self) Plane {
return plane; return plane;
} }
pub fn process_renderer_event(self: *Self, msg: []const u8) !void { pub fn process_renderer_event(self: *Self, msg: []const u8) Error!void {
const Input = struct { const Input = struct {
kind: u8, kind: u8,
codepoint: u21, codepoint: u21,

View file

@ -43,7 +43,7 @@ pub fn main() anyerror!void {
try cbor.writeValue(writer, "highlights"); try cbor.writeValue(writer, "highlights");
try cbor.writeValue(writer, highlights_cb); try cbor.writeValue(writer, highlights_cb);
std.log.info("file_type {s} highlights {d} bytes", .{ file_type.name, highlights_cb.len }); // std.log.info("file_type {s} highlights {d} bytes", .{ file_type.name, highlights_cb.len });
if (file_type.injections) |injections| { if (file_type.injections) |injections| {
const injections_in = try treez.Query.create(lang, injections); const injections_in = try treez.Query.create(lang, injections);
@ -54,12 +54,12 @@ pub fn main() anyerror!void {
try cbor.writeValue(writer, "injections"); try cbor.writeValue(writer, "injections");
try cbor.writeValue(writer, injections_cb); try cbor.writeValue(writer, injections_cb);
std.log.info("file_type {s} injections {d} bytes", .{ file_type.name, injections_cb.len }); // std.log.info("file_type {s} injections {d} bytes", .{ file_type.name, injections_cb.len });
} }
} }
try output_file.writeAll(output.items); try output_file.writeAll(output.items);
std.log.info("file_types total {d} bytes", .{output.items.len}); // std.log.info("file_types total {d} bytes", .{output.items.len});
} }
fn fatal(comptime format: []const u8, args: anytype) noreturn { fn fatal(comptime format: []const u8, args: anytype) noreturn {

View file

@ -31,7 +31,7 @@ on_render: *const fn (ctx: ?*anyopaque, theme: *const Widget.Theme) void = on_re
after_render: *const fn (ctx: ?*anyopaque, theme: *const Widget.Theme) void = on_render_default, after_render: *const fn (ctx: ?*anyopaque, theme: *const Widget.Theme) void = on_render_default,
on_resize: *const fn (ctx: ?*anyopaque, self: *Self, pos_: Widget.Box) void = on_resize_default, on_resize: *const fn (ctx: ?*anyopaque, self: *Self, pos_: Widget.Box) void = on_resize_default,
pub fn createH(allocator: Allocator, parent: Plane, name: [:0]const u8, layout_: Layout) !*Self { pub fn createH(allocator: Allocator, parent: Plane, name: [:0]const u8, layout_: Layout) error{OutOfMemory}!*Self {
const self: *Self = try allocator.create(Self); const self: *Self = try allocator.create(Self);
self.* = try init(allocator, parent, name, .horizontal, layout_, Box{}); self.* = try init(allocator, parent, name, .horizontal, layout_, Box{});
self.plane.hide(); self.plane.hide();

View file

@ -60,7 +60,9 @@ const FileListType = enum {
find_in_files, find_in_files,
}; };
pub fn create(allocator: std.mem.Allocator) !Widget { pub const CreateError = error{ OutOfMemory, ThespianSpawnFailed };
pub fn create(allocator: std.mem.Allocator) CreateError!Widget {
const self = try allocator.create(Self); const self = try allocator.create(Self);
self.* = .{ self.* = .{
.allocator = allocator, .allocator = allocator,

View file

@ -8,13 +8,17 @@ const Plane = @import("renderer").Plane;
pub const Style = enum { none, grip }; pub const Style = enum { none, grip };
pub fn create(allocator: std.mem.Allocator, parent: Plane, config: []const u8, style: Style, event_handler: ?EventHandler) !Widget { pub fn create(allocator: std.mem.Allocator, parent: Plane, config: []const u8, style: Style, event_handler: ?EventHandler) error{OutOfMemory}!Widget {
var w = try WidgetList.createH(allocator, parent, "statusbar", .{ .static = 1 }); var w = try WidgetList.createH(allocator, parent, "statusbar", .{ .static = 1 });
if (style == .grip) w.after_render = render_grip; if (style == .grip) w.after_render = render_grip;
w.ctx = w; w.ctx = w;
var it = std.mem.splitScalar(u8, config, ' '); var it = std.mem.splitScalar(u8, config, ' ');
while (it.next()) |widget_name| while (it.next()) |widget_name| {
try w.add(try status_widget.create(widget_name, allocator, w.plane, event_handler) orelse continue); try w.add(status_widget.create(widget_name, allocator, w.plane, event_handler) catch |e| switch (e) {
error.OutOfMemory => return error.OutOfMemory,
error.WidgetInitFailed => null,
} orelse continue);
}
return w.widget(); return w.widget();
} }

View file

@ -19,14 +19,20 @@ tz: zeit.timezone.TimeZone,
const Self = @This(); const Self = @This();
pub fn create(allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) @import("widget.zig").CreateError!Widget { pub fn create(allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) @import("widget.zig").CreateError!Widget {
var env = std.process.getEnvMap(allocator) catch |e| return tp.exit_error(e, @errorReturnTrace()); var env = std.process.getEnvMap(allocator) catch |e| {
std.log.err("clock: std.process.getEnvMap failed with {any}", .{e});
return error.WidgetInitFailed;
};
defer env.deinit(); defer env.deinit();
const self: *Self = try allocator.create(Self); const self: *Self = try allocator.create(Self);
self.* = .{ self.* = .{
.allocator = allocator, .allocator = allocator,
.plane = try Plane.init(&(Widget.Box{}).opts(@typeName(Self)), parent), .plane = try Plane.init(&(Widget.Box{}).opts(@typeName(Self)), parent),
.on_event = event_handler, .on_event = event_handler,
.tz = zeit.local(allocator, &env) catch |e| return tp.exit_error(e, @errorReturnTrace()), .tz = zeit.local(allocator, &env) catch |e| {
std.log.err("clock: zeit.local failed with {any}", .{e});
return error.WidgetInitFailed;
},
}; };
try tui.message_filters().add(MessageFilter.bind(self, receive_tick)); try tui.message_filters().add(MessageFilter.bind(self, receive_tick));
self.update_tick_timer(.init); self.update_tick_timer(.init);

View file

@ -35,7 +35,7 @@ pub fn create(allocator: std.mem.Allocator, parent: Plane, event_handler: ?Event
}; };
logview.init(allocator); logview.init(allocator);
try tui.message_filters().add(MessageFilter.bind(self, receive_log)); try tui.message_filters().add(MessageFilter.bind(self, receive_log));
try log.subscribe(); log.subscribe() catch return error.WidgetInitFailed;
return Widget.to(self); return Widget.to(self);
} }

View file

@ -20,7 +20,7 @@ const widgets = std.static_string_map.StaticStringMap(CreateFunction).initCompti
.{ "keybind", @import("keybindstate.zig").create }, .{ "keybind", @import("keybindstate.zig").create },
.{ "tabs", @import("tabs.zig").create }, .{ "tabs", @import("tabs.zig").create },
}); });
pub const CreateError = error{ OutOfMemory, Exit }; pub const CreateError = error{ OutOfMemory, WidgetInitFailed };
pub const CreateFunction = *const fn (allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) CreateError!Widget; pub const CreateFunction = *const fn (allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) CreateError!Widget;
pub fn create(name: []const u8, allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) CreateError!?Widget { pub fn create(name: []const u8, allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) CreateError!?Widget {

View file

@ -84,11 +84,24 @@ fn start(args: StartArgs) tp.result {
tp.receive(&self.receiver); tp.receive(&self.receiver);
} }
fn init(allocator: Allocator) !*Self { const InitError = error{
OutOfMemory,
UnknownTheme,
ThespianMetronomeInitFailed,
ThespianMetronomeStartFailed,
ThespianTimeoutInitFailed,
ThespianSignalInitFailed,
ThespianSpawnFailed,
} || renderer.Error ||
root.ConfigDirError ||
root.ConfigWriteError ||
keybind.LoadError;
fn init(allocator: Allocator) InitError!*Self {
var conf, const conf_bufs = root.read_config(@import("config"), allocator); var conf, const conf_bufs = root.read_config(@import("config"), allocator);
defer root.free_config(allocator, conf_bufs); defer root.free_config(allocator, conf_bufs);
const theme_ = get_theme_by_name(conf.theme) orelse get_theme_by_name("dark_modern") orelse return tp.exit("unknown theme"); const theme_ = get_theme_by_name(conf.theme) orelse get_theme_by_name("dark_modern") orelse return error.UnknownTheme;
conf.theme = theme_.name; conf.theme = theme_.name;
conf.whitespace_mode = try allocator.dupe(u8, conf.whitespace_mode); conf.whitespace_mode = try allocator.dupe(u8, conf.whitespace_mode);
conf.input_mode = try allocator.dupe(u8, conf.input_mode); conf.input_mode = try allocator.dupe(u8, conf.input_mode);
@ -161,7 +174,7 @@ fn init(allocator: Allocator) !*Self {
return self; return self;
} }
fn init_input_namespace(self: *Self) !void { fn init_input_namespace(self: *Self) InitError!void {
var mode_parts = std.mem.splitScalar(u8, self.config_.input_mode, '/'); var mode_parts = std.mem.splitScalar(u8, self.config_.input_mode, '/');
const namespace_name = mode_parts.first(); const namespace_name = mode_parts.first();
keybind.set_namespace(namespace_name) catch { keybind.set_namespace(namespace_name) catch {
@ -172,7 +185,7 @@ fn init_input_namespace(self: *Self) !void {
}; };
} }
fn init_delayed(self: *Self) !void { fn init_delayed(self: *Self) command.Result {
self.delayed_init_done = true; self.delayed_init_done = true;
if (self.input_mode_) |_| {} else { if (self.input_mode_) |_| {} else {
if (self.delayed_init_input_mode) |delayed_init_input_mode| { if (self.delayed_init_input_mode) |delayed_init_input_mode| {
@ -218,9 +231,9 @@ fn deinit(self: *Self) void {
self.allocator.destroy(self); self.allocator.destroy(self);
} }
fn listen_sigwinch(self: *Self) tp.result { fn listen_sigwinch(self: *Self) error{ThespianSignalInitFailed}!void {
if (self.sigwinch_signal) |old| old.deinit(); 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, @errorReturnTrace()); self.sigwinch_signal = try tp.signal.init(std.posix.SIG.WINCH, tp.message.fmt(.{"sigwinch"}));
} }
fn update_mouse_idle_timer(self: *Self) void { fn update_mouse_idle_timer(self: *Self) void {
@ -465,7 +478,7 @@ fn active_event_handler(self: *Self) ?EventHandler {
return mode.event_handler orelse mode.input_handler; return mode.event_handler orelse mode.input_handler;
} }
fn dispatch_flush_input_event(self: *Self) !void { fn dispatch_flush_input_event(self: *Self) error{ Exit, NoSpaceLeft }!void {
var buf: [32]u8 = undefined; var buf: [32]u8 = undefined;
const mode = self.input_mode_ orelse return; const mode = self.input_mode_ orelse return;
try mode.input_handler.send(tp.self_pid(), try tp.message.fmtbuf(&buf, .{"F"})); try mode.input_handler.send(tp.self_pid(), try tp.message.fmtbuf(&buf, .{"F"}));
@ -627,7 +640,7 @@ pub fn refresh_hover() void {
_ = self.update_hover(self.last_hover_y, self.last_hover_x) catch {}; _ = self.update_hover(self.last_hover_y, self.last_hover_x) catch {};
} }
pub fn save_config() !void { pub fn save_config() (root.ConfigDirError || root.ConfigWriteError)!void {
const self = current(); const self = current();
try root.write_config(self.config_, self.allocator); try root.write_config(self.config_, self.allocator);
} }