this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

add readme

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>

+170
+170
README.md
··· 1 + # libvaxis 2 + 3 + ``` 4 + It begins with them, but ends with me. Their son, Vaxis 5 + ``` 6 + 7 + libvaxis is a zig port of the go TUI library 8 + [Vaxis](https://git.sr.ht/~rockorager/vaxis). The goal is to have the same 9 + feature set, only written in zig. 10 + 11 + Like it's sibling library, libvaxis _does not use terminfo_. Support for vt 12 + features is detected through terminal queries. 13 + 14 + Contributions are welcome. 15 + 16 + ## Feature comparison 17 + 18 + | Feature | Vaxis | libvaxis | notcurses | 19 + | ------------------------------ | :---: | :------: | :-------: | 20 + | RGB | ✅ | ✅ | ✅ | 21 + | Hyperlinks | ✅ | planned | ❌ | 22 + | Bracketed Paste | ✅ | planned | ❌ | 23 + | Kitty Keyboard | ✅ | ✅ | ✅ | 24 + | Styled Underlines | ✅ | ✅ | ✅ | 25 + | Mouse Shapes (OSC 22) | ✅ | planned | ❌ | 26 + | System Clipboard (OSC 52) | ✅ | planned | ❌ | 27 + | System Notifications (OSC 9) | ✅ | planned | ❌ | 28 + | System Notifications (OSC 777) | ✅ | planned | ❌ | 29 + | Synchronized Output (DEC 2026) | ✅ | ✅ | ✅ | 30 + | Unicode Core (DEC 2027) | ✅ | ✅ | ❌ | 31 + | Color Mode Updates (DEC 2031) | ✅ | planned | ❌ | 32 + | Images (full/space) | ✅ | planned | ✅ | 33 + | Images (half block) | ✅ | planned | ✅ | 34 + | Images (quadrant) | ✅ | planned | ✅ | 35 + | Images (sextant) | ❌ | ❌ | ✅ | 36 + | Images (sixel) | ✅ | planned | ✅ | 37 + | Images (kitty) | ✅ | planned | ✅ | 38 + | Images (iterm2) | ❌ | ❌ | ✅ | 39 + | Video | ❌ | ❌ | ✅ | 40 + | Dank | 🆗 | 🆗 | ✅ | 41 + 42 + ## Usage 43 + 44 + The below example can be run using `zig build run 2>log`. stderr must be 45 + redirected in order to not print to the same screen. 46 + 47 + ```zig 48 + const std = @import("std"); 49 + const vaxis = @import("vaxis"); 50 + const Cell = vaxis.Cell; 51 + const TextInput = vaxis.widgets.TextInput; 52 + const border = vaxis.widgets.border; 53 + 54 + const log = std.log.scoped(.main); 55 + 56 + // Our EventType. This can contain internal events as well as Vaxis events. 57 + // Internal events can be posted into the same queue as vaxis events to allow 58 + // for a single event loop with exhaustive switching. Booya 59 + const Event = union(enum) { 60 + key_press: vaxis.Key, 61 + winsize: vaxis.Winsize, 62 + focus_in, 63 + foo: u8, 64 + }; 65 + 66 + pub fn main() !void { 67 + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 68 + defer { 69 + const deinit_status = gpa.deinit(); 70 + //fail test; can't try in defer as defer is executed after we return 71 + if (deinit_status == .leak) { 72 + log.err("memory leak", .{}); 73 + } 74 + } 75 + const alloc = gpa.allocator(); 76 + 77 + // Initialize Vaxis with our event type 78 + var vx = try vaxis.init(Event, .{}); 79 + // deinit takes an optional allocator. If your program is exiting, you can 80 + // choose to pass a null allocator to save some exit time. 81 + defer vx.deinit(alloc); 82 + 83 + // Start the read loop. This puts the terminal in raw mode and begins 84 + // reading user input 85 + try vx.startReadThread(); 86 + defer vx.stopReadThread(); 87 + 88 + // Optionally enter the alternate screen 89 + try vx.enterAltScreen(); 90 + 91 + // We'll adjust the color index every keypress for the border 92 + var color_idx: u8 = 0; 93 + 94 + // init our text input widget. The text input widget needs an allocator to 95 + // store the contents of the input 96 + var text_input = TextInput.init(alloc); 97 + defer text_input.deinit(); 98 + 99 + // Sends queries to terminal to detect certain features. This should 100 + // _always_ be called, but is left to the application to decide when 101 + try vx.queryTerminal(); 102 + 103 + // The main event loop. Vaxis provides a thread safe, blocking, buffered 104 + // queue which can serve as the primary event queue for an application 105 + outer: while (true) { 106 + // nextEvent blocks until an event is in the queue 107 + const event = vx.nextEvent(); 108 + log.debug("event: {}\r\n", .{event}); 109 + // exhaustive switching ftw. Vaxis will send events if your EventType 110 + // enum has the fields for those events (ie "key_press", "winsize") 111 + switch (event) { 112 + .key_press => |key| { 113 + color_idx = switch (color_idx) { 114 + 255 => 0, 115 + else => color_idx + 1, 116 + }; 117 + if (key.matches('c', .{ .ctrl = true })) { 118 + break :outer; 119 + } else if (key.matches('l', .{ .ctrl = true })) { 120 + vx.queueRefresh(); 121 + } else { 122 + try text_input.update(.{ .key_press = key }); 123 + } 124 + }, 125 + 126 + // winsize events are sent to the application to ensure that all 127 + // resizes occur in the main thread. This lets us avoid expensive 128 + // locks on the screen. All applications must handle this event 129 + // unless they aren't using a screen (IE only detecting features) 130 + // 131 + // This is the only call that the core of Vaxis needs an allocator 132 + // for. The allocations are because we keep a copy of each cell to 133 + // optimize renders. When resize is called, we allocated two slices: 134 + // one for the screen, and one for our buffered screen. Each cell in 135 + // the buffered screen contains an ArrayList(u8) to be able to store 136 + // the grapheme for that cell Each cell is initialized with a size 137 + // of 1, which is sufficient for all of ASCII. Anything requiring 138 + // more than one byte will incur an allocation on the first render 139 + // after it is drawn. Thereafter, it will not allocate unless the 140 + // screen is resized 141 + .winsize => |ws| try vx.resize(alloc, ws), 142 + else => {}, 143 + } 144 + 145 + // vx.window() returns the root window. This window is the size of the 146 + // terminal and can spawn child windows as logical areas. Child windows 147 + // cannot draw outside of their bounds 148 + const win = vx.window(); 149 + 150 + // Clear the entire space because we are drawing in immediate mode. 151 + // vaxis double buffers the screen. This new frame will be compared to 152 + // the old and only updated cells will be drawn 153 + win.clear(); 154 + const child = win.initChild( 155 + win.width / 2 - 20, 156 + win.height / 2 - 3, 157 + .{ .limit = 40 }, 158 + .{ .limit = 3 }, 159 + ); 160 + // draw the text_input using a bordered window 161 + const style: vaxis.Style = .{ 162 + .fg = .{ .index = color_idx }, 163 + }; 164 + text_input.draw(border.all(child, style)); 165 + 166 + // Render the screen 167 + try vx.render(); 168 + } 169 + } 170 + ```