this repo has no description
1const std = @import("std");
2const vaxis = @import("vaxis");
3const Cell = vaxis.Cell;
4const TextInput = vaxis.widgets.TextInput;
5
6const log = std.log.scoped(.main);
7pub fn main(init: std.process.Init) !void {
8 const io = init.io;
9 const alloc = init.gpa;
10
11 var buffer: [1024]u8 = undefined;
12 var tty = try vaxis.Tty.init(io, &buffer);
13 defer tty.deinit();
14
15 var vx = try vaxis.init(io, alloc, init.environ_map, .{});
16 defer vx.deinit(alloc, tty.writer());
17
18 var loop: vaxis.Loop(Event) = .init(io, &tty, &vx);
19
20 try loop.start();
21 defer loop.stop();
22
23 try vx.queryTerminal(tty.writer(), .fromSeconds(1));
24
25 var text_input = TextInput.init(alloc);
26 defer text_input.deinit();
27
28 var selected_option: ?usize = null;
29
30 const options = [_][]const u8{
31 "option 1",
32 "option 2",
33 "option 3",
34 };
35
36 // The main event loop. Vaxis provides a thread safe, blocking, buffered
37 // queue which can serve as the primary event queue for an application
38 while (true) {
39 // nextEvent blocks until an event is in the queue
40 const event = try loop.nextEvent();
41 // exhaustive switching ftw. Vaxis will send events if your Event
42 // enum has the fields for those events (ie "key_press", "winsize")
43 switch (event) {
44 .key_press => |key| {
45 if (key.codepoint == 'c' and key.mods.ctrl) {
46 break;
47 } else if (key.matches(vaxis.Key.tab, .{})) {
48 if (selected_option == null) {
49 selected_option = 0;
50 } else {
51 selected_option.? = @min(options.len - 1, selected_option.? + 1);
52 }
53 } else if (key.matches(vaxis.Key.tab, .{ .shift = true })) {
54 if (selected_option == null) {
55 selected_option = 0;
56 } else {
57 selected_option.? = selected_option.? -| 1;
58 }
59 } else if (key.matches(vaxis.Key.enter, .{}) or key.matches('j', .{ .ctrl = true })) {
60 if (selected_option) |i| {
61 log.err("enter", .{});
62 try text_input.insertSliceAtCursor(options[i]);
63 selected_option = null;
64 }
65 } else {
66 if (selected_option == null)
67 try text_input.update(.{ .key_press = key });
68 }
69 },
70 .winsize => |ws| {
71 try vx.resize(alloc, tty.writer(), ws);
72 },
73 else => {},
74 }
75
76 const win = vx.window();
77 win.clear();
78
79 text_input.draw(win);
80
81 if (selected_option) |i| {
82 win.hideCursor();
83 for (options, 0..) |opt, j| {
84 log.err("i = {d}, j = {d}, opt = {s}", .{ i, j, opt });
85 var seg = [_]vaxis.Segment{.{
86 .text = opt,
87 .style = if (j == i) .{ .reverse = true } else .{},
88 }};
89 _ = win.print(&seg, .{ .row_offset = @intCast(j + 1) });
90 }
91 }
92 try vx.render(tty.writer());
93 }
94}
95
96// Our Event. This can contain internal events as well as Vaxis events.
97// Internal events can be posted into the same queue as vaxis events to allow
98// for a single event loop with exhaustive switching. Booya
99const Event = union(enum) {
100 key_press: vaxis.Key,
101 winsize: vaxis.Winsize,
102 focus_in,
103 foo: u8,
104};
105
106test {
107 std.testing.refAllDecls(@This());
108}