Files
tui-diff/src/main.zig
Yves Biener 5dba0d4408
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 1m41s
Intial project structure with zterm dependency and basic tui render/event loop
2025-11-26 17:55:46 +01:00

104 lines
2.9 KiB
Zig

// TODO planned features:
// FIX known issues:
pub fn main() !void {
// argument handling
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
defer if (gpa.deinit() == .leak) std.log.err("memory leak", .{});
var area: std.heap.ArenaAllocator = .init(gpa.allocator());
defer area.deinit();
// NOTE current setup
// - in debug builds use the gpa (to identify leaks!)
// - in other builds use the area to free all memory!
const allocator = switch (builtin.mode) {
.Debug => gpa.allocator(),
else => area.allocator(),
};
// argument handling
{
var arg_it = try std.process.argsWithAllocator(allocator);
defer arg_it.deinit();
// TODO may there be other options?
// usage: tui-diff
// skip own executable name
_ = arg_it.skip();
}
var threaded_io: std.Io.Threaded = .init(allocator);
errdefer threaded_io.deinit();
const io = threaded_io.io();
errdefer |err| log.err("Application Error: {any}", .{err});
var renderer = zterm.Renderer.Buffered.init(allocator);
defer renderer.deinit();
var app: App = .init(io, .init);
var root = try tui_diff.Container(App, allocator);
defer root.deinit(); // also de-initializes the children
try app.start();
defer app.stop() catch |err| log.err("Failed to stop application: {any}", .{err});
// event loop
loop: while (true) {
// batch events since last iteration
const len = blk: {
app.queue.poll();
app.queue.lock();
defer app.queue.unlock();
break :blk app.queue.len();
};
// handle events
for (0..len) |_| {
const event = app.queue.pop();
// pre event handling
switch (event) {
.key => |key| if (key.eql(.{ .cp = 'q' })) app.quit(),
else => {},
}
// NOTE returned errors should be propagated back to the application
root.handle(&app.model, event) catch |err| app.postEvent(.{
.err = .{
.err = err,
.msg = "Container Event handling failed",
},
});
// post event handling
switch (event) {
.quit => break :loop,
else => {},
}
}
root.resize(&app.model, try renderer.resize());
root.reposition(&app.model, .{});
try renderer.render(@TypeOf(root), &root, App.Model, &app.model);
try renderer.flush();
}
threaded_io.deinit();
}
const log = std.log.scoped(.default);
const App = zterm.App(Model, Event);
pub const panic = App.panic_handler;
const std = @import("std");
const builtin = @import("builtin");
const tui_diff = @import("tui-diff");
const zterm = @import("zterm");
const Event = tui_diff.Event;
const Model = tui_diff.Model;