From 0fa082033eb559fbc67c8b4eca355d262414c000 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Fri, 24 May 2024 11:00:35 -0500 Subject: [PATCH] examples: add readline example --- build.zig | 1 + examples/readline.zig | 75 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 examples/readline.zig diff --git a/build.zig b/build.zig index 001281d..1abd0c5 100644 --- a/build.zig +++ b/build.zig @@ -43,6 +43,7 @@ pub fn build(b: *std.Build) void { main, nvim, pathological, + readline, shell, table, text_input, diff --git a/examples/readline.zig b/examples/readline.zig new file mode 100644 index 0000000..4c75970 --- /dev/null +++ b/examples/readline.zig @@ -0,0 +1,75 @@ +const std = @import("std"); +const vaxis = @import("vaxis"); +const Cell = vaxis.Cell; +const TextInput = vaxis.widgets.TextInput; +const border = vaxis.widgets.border; + +const log = std.log.scoped(.main); + +const Event = union(enum) { + key_press: vaxis.Key, + winsize: vaxis.Winsize, +}; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer { + const deinit_status = gpa.deinit(); + //fail test; can't try in defer as defer is executed after we return + if (deinit_status == .leak) { + log.err("memory leak", .{}); + } + } + const alloc = gpa.allocator(); + + var line: ?[]const u8 = null; + defer { + // do this in defer so that vaxis cleans up terminal state before we + // print to stdout + if (line) |_| { + const stdout = std.io.getStdOut().writer(); + stdout.print("\n{s}\n", .{line.?}) catch {}; + alloc.free(line.?); + } + } + var vx = try vaxis.init(alloc, .{}); + defer vx.deinit(alloc); + + var loop: vaxis.Loop(Event) = .{ .vaxis = &vx }; + try loop.run(); + defer loop.stop(); + + var text_input = TextInput.init(alloc, &vx.unicode); + defer text_input.deinit(); + + try vx.queryTerminal(); + + const prompt: vaxis.Segment = .{ .text = "$ " }; + + while (true) { + const event = loop.nextEvent(); + switch (event) { + .key_press => |key| { + if (key.matches('c', .{ .ctrl = true })) { + break; + } else if (key.matches(vaxis.Key.enter, .{})) { + line = try text_input.toOwnedSlice(); + text_input.clearAndFree(); + break; + } else { + try text_input.update(.{ .key_press = key }); + } + }, + .winsize => |ws| try vx.resize(alloc, ws), + } + + const win = vx.window(); + + win.clear(); + _ = try win.printSegment(prompt, .{}); + + const input_win = win.child(.{ .x_off = 2 }); + text_input.draw(input_win); + try vx.render(); + } +}