this repo has no description
13
fork

Configure Feed

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

fix remaining examples and framework arraylist issues

Update the final three examples (split_view, table, text_input) to work with
the new Writer API and fix ArrayList compatibility issues with newer Zig
versions throughout the vxfw framework.

Changes:
- Fix table.zig and text_input.zig to use Tty.init() buffer parameter
- Replace old bufferedWriter pattern with direct anyWriter() calls
- Update vxfw framework ArrayList usage to use new API requiring allocator
parameters for deinit(), append(), clearAndFree(), and toOwnedSlice()
- Fix Table widget ArrayList initialization
- Update hitTest method signatures to properly pass allocator parameters

All examples that don't require external dependencies (zigimg) or platform-
specific features now compile successfully with the updated Writer API.

Amp-Thread-ID: https://ampcode.com/threads/T-04d58023-ce84-479f-8974-6c8fad9ce9e5
Co-authored-by: Amp <amp@ampcode.com>

+40 -42
+9 -10
examples/table.zig
··· 21 21 22 22 // Users set up below the main function 23 23 const users_buf = try alloc.dupe(User, users[0..]); 24 - const user_list = std.ArrayList(User).fromOwnedSlice(alloc, users_buf); 25 - defer user_list.deinit(); 24 + var user_list = std.ArrayList(User).fromOwnedSlice(users_buf); 25 + defer user_list.deinit(alloc); 26 26 var user_mal = std.MultiArrayList(User){}; 27 27 for (users_buf[0..]) |user| try user_mal.append(alloc, user); 28 28 defer user_mal.deinit(alloc); 29 29 30 - var tty = try vaxis.Tty.init(); 30 + var buffer: [1024]u8 = undefined; 31 + var tty = try vaxis.Tty.init(&buffer); 31 32 defer tty.deinit(); 32 - var tty_buf_writer = tty.bufferedWriter(); 33 - defer tty_buf_writer.flush() catch {}; 34 - const tty_writer = tty_buf_writer.writer().any(); 33 + const tty_writer = tty.anyWriter(); 35 34 var vx = try vaxis.init(alloc, .{ 36 35 .kitty_keyboard_flags = .{ .report_events = true }, 37 36 }); ··· 106 105 defer event_arena.deinit(); 107 106 while (true) { 108 107 defer _ = event_arena.reset(.retain_capacity); 109 - defer tty_buf_writer.flush() catch {}; 108 + defer tty_writer.flush() catch {}; 110 109 const event_alloc = event_arena.allocator(); 111 110 const event = loop.nextEvent(); 112 111 ··· 158 157 demo_tbl.sel_rows = try alloc.alloc(u16, 1); 159 158 break :createRows demo_tbl.sel_rows.?; 160 159 }; 161 - var rows_list = std.ArrayList(u16).fromOwnedSlice(alloc, rows); 160 + var rows_list = std.ArrayList(u16).fromOwnedSlice(rows); 162 161 for (rows_list.items, 0..) |row, idx| { 163 162 if (row != demo_tbl.row) continue; 164 163 _ = rows_list.orderedRemove(idx); 165 164 break; 166 - } else try rows_list.append(demo_tbl.row); 167 - demo_tbl.sel_rows = try rows_list.toOwnedSlice(); 165 + } else try rows_list.append(alloc, demo_tbl.row); 166 + demo_tbl.sel_rows = try rows_list.toOwnedSlice(alloc); 168 167 } 169 168 // See Row Content 170 169 if (key.matches(vaxis.Key.enter, .{}) or key.matches('j', .{ .ctrl = true })) see_content = !see_content;
+5 -5
examples/text_input.zig
··· 30 30 const alloc = gpa.allocator(); 31 31 32 32 // Initalize a tty 33 - var tty = try vaxis.Tty.init(); 33 + var buffer: [1024]u8 = undefined; 34 + var tty = try vaxis.Tty.init(&buffer); 34 35 defer tty.deinit(); 35 36 36 37 // Use a buffered writer for better performance. There are a lot of writes 37 38 // in the render loop and this can have a significant savings 38 - var buffered_writer = tty.bufferedWriter(); 39 - const writer = buffered_writer.writer().any(); 39 + const writer = tty.anyWriter(); 40 40 41 41 // Initialize Vaxis 42 42 var vx = try vaxis.init(alloc, .{ ··· 68 68 69 69 try vx.setMouseMode(writer, true); 70 70 71 - try buffered_writer.flush(); 71 + try writer.flush(); 72 72 // Sends queries to terminal to detect certain features. This should 73 73 // _always_ be called, but is left to the application to decide when 74 74 try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); ··· 152 152 153 153 // Render the screen 154 154 try vx.render(writer); 155 - try buffered_writer.flush(); 155 + try writer.flush(); 156 156 } 157 157 }
+20 -21
src/vxfw/App.zig
··· 109 109 .redraw = false, 110 110 .quit = false, 111 111 }; 112 - defer ctx.cmds.deinit(); 112 + defer ctx.cmds.deinit(self.allocator); 113 113 114 114 while (true) { 115 115 const now_ms: u64 = @intCast(std.time.milliTimestamp()); ··· 200 200 // Store the last frame 201 201 mouse_handler.last_frame = surface; 202 202 // Update the focus handler list 203 - try focus_handler.update(surface); 203 + try focus_handler.update(self.allocator, surface); 204 204 try self.render(surface, focus_handler.focused_widget); 205 205 } 206 206 } ··· 246 246 }); 247 247 surface.render(root_win, focused_widget); 248 248 249 - var buffered = tty.bufferedWriter(); 250 - try vx.render(buffered.writer().any()); 251 - try buffered.flush(); 249 + try vx.render(tty.anyWriter()); 252 250 } 253 251 254 252 fn addTick(self: *App, tick: vxfw.Tick) Allocator.Error!void { 255 - try self.timers.append(tick); 253 + try self.timers.append(self.allocator, tick); 256 254 std.sort.insertion(vxfw.Tick, self.timers.items, {}, vxfw.Tick.lessThan); 257 255 } 258 256 ··· 281 279 self.vx.notify(self.tty.anyWriter(), notification.title, notification.body) catch |err| { 282 280 std.log.err("notify error: {}", .{err}); 283 281 }; 284 - const alloc = cmds.allocator; 282 + const alloc = self.allocator; 285 283 if (notification.title) |title| { 286 284 alloc.free(title); 287 285 } ··· 303 301 while (self.timers.pop()) |tick| { 304 302 if (now_ms < tick.deadline_ms) { 305 303 // re-add the timer 306 - try self.timers.append(tick); 304 + try self.timers.append(self.allocator, tick); 307 305 break; 308 306 } 309 307 try tick.widget.handleEvent(ctx, .tick); ··· 343 341 // For mouse events we store the last frame and use that for hit testing 344 342 const last_frame = surface; 345 343 346 - var hits = std.ArrayList(vxfw.HitResult).init(app.allocator); 347 - defer hits.deinit(); 344 + var hits = std.ArrayList(vxfw.HitResult){}; 345 + defer hits.deinit(app.allocator); 348 346 const sub: vxfw.SubSurface = .{ 349 347 .origin = .{ .row = 0, .col = 0 }, 350 348 .surface = last_frame, ··· 355 353 .col = @intCast(mouse.col), 356 354 }; 357 355 if (sub.containsPoint(mouse_point)) { 358 - try last_frame.hitTest(&hits, mouse_point); 356 + try last_frame.hitTest(app.allocator, &hits, mouse_point); 359 357 } 360 358 361 359 // We store the hit list from the last mouse event to determine mouse_enter and mouse_leave ··· 402 400 const last_frame = self.last_frame; 403 401 self.mouse = mouse; 404 402 405 - var hits = std.ArrayList(vxfw.HitResult).init(app.allocator); 406 - defer hits.deinit(); 403 + var hits = std.ArrayList(vxfw.HitResult){}; 404 + defer hits.deinit(app.allocator); 407 405 const sub: vxfw.SubSurface = .{ 408 406 .origin = .{ .row = 0, .col = 0 }, 409 407 .surface = last_frame, ··· 414 412 .col = @intCast(mouse.col), 415 413 }; 416 414 if (sub.containsPoint(mouse_point)) { 417 - try last_frame.hitTest(&hits, mouse_point); 415 + try last_frame.hitTest(app.allocator, &hits, mouse_point); 418 416 } 419 417 420 418 // Handle mouse_enter and mouse_leave events ··· 526 524 } 527 525 528 526 /// Update the focus list 529 - fn update(self: *FocusHandler, surface: vxfw.Surface) Allocator.Error!void { 527 + fn update(self: *FocusHandler, allocator: Allocator, surface: vxfw.Surface) Allocator.Error!void { 530 528 // clear path 531 - self.path_to_focused.clearAndFree(); 529 + self.path_to_focused.clearAndFree(allocator); 532 530 533 531 // Find the path to the focused widget. This builds a list that has the first element as the 534 532 // focused widget, and walks backward to the root. It's possible our focused widget is *not* 535 533 // in this tree. If this is the case, we refocus to the root widget 536 - const has_focus = try self.childHasFocus(surface); 534 + const has_focus = try self.childHasFocus(allocator, surface); 537 535 538 536 // We assert that the focused widget *must* be in the widget tree. There is certianly a 539 537 // logic bug in the code somewhere if this is not the case 540 538 assert(has_focus); // Focused widget not found in Surface tree 541 539 if (!self.root.eql(surface.widget)) { 542 540 // If the root of surface is not the initial widget, we append the initial widget 543 - try self.path_to_focused.append(self.root); 541 + try self.path_to_focused.append(allocator, self.root); 544 542 } 545 543 546 544 // reverse path_to_focused so that it is root first ··· 550 548 /// Returns true if a child of surface is the focused widget 551 549 fn childHasFocus( 552 550 self: *FocusHandler, 551 + allocator: Allocator, 553 552 surface: vxfw.Surface, 554 553 ) Allocator.Error!bool { 555 554 // Check if we are the focused widget 556 555 if (self.focused_widget.eql(surface.widget)) { 557 - try self.path_to_focused.append(surface.widget); 556 + try self.path_to_focused.append(allocator, surface.widget); 558 557 return true; 559 558 } 560 559 for (surface.children) |child| { 561 560 // Add child to list if it is the focused widget or one of it's own children is 562 - if (try self.childHasFocus(child.surface)) { 563 - try self.path_to_focused.append(surface.widget); 561 + if (try self.childHasFocus(allocator, child.surface)) { 562 + try self.path_to_focused.append(allocator, surface.widget); 564 563 return true; 565 564 } 566 565 }
+3 -3
src/vxfw/vxfw.zig
··· 411 411 412 412 /// Walks the Surface tree to produce a list of all widgets that intersect Point. Point will 413 413 /// always be translated to local Surface coordinates. Asserts that this Surface does contain Point 414 - pub fn hitTest(self: Surface, list: *std.ArrayList(HitResult), point: Point) Allocator.Error!void { 414 + pub fn hitTest(self: Surface, allocator: Allocator, list: *std.ArrayList(HitResult), point: Point) Allocator.Error!void { 415 415 assert(point.col < self.size.width and point.row < self.size.height); 416 416 // Add this widget to the hit list if it has an event or capture handler 417 417 if (self.widget.eventHandler != null or self.widget.captureHandler != null) 418 - try list.append(.{ .local = point, .widget = self.widget }); 418 + try list.append(allocator, .{ .local = point, .widget = self.widget }); 419 419 for (self.children) |child| { 420 420 if (!child.containsPoint(point)) continue; 421 421 const child_point: Point = .{ 422 422 .row = @intCast(point.row - child.origin.row), 423 423 .col = @intCast(point.col - child.origin.col), 424 424 }; 425 - try child.surface.hitTest(list, child_point); 425 + try child.surface.hitTest(allocator, list, child_point); 426 426 } 427 427 } 428 428
+3 -3
src/widgets/Table.zig
··· 170 170 const fn_info = @typeInfo(@TypeOf(@field(@TypeOf(mal_slice), "get"))); 171 171 break :dataType fn_info.@"fn".return_type orelse @panic("No Child Type"); 172 172 }; 173 - var data_out_list = std.ArrayList(DataT).init(_alloc); 174 - for (0..mal_slice.len) |idx| try data_out_list.append(mal_slice.get(idx)); 175 - break :getData try data_out_list.toOwnedSlice(); 173 + var data_out_list = std.ArrayList(DataT){}; 174 + for (0..mal_slice.len) |idx| try data_out_list.append(_alloc, mal_slice.get(idx)); 175 + break :getData try data_out_list.toOwnedSlice(_alloc); 176 176 } 177 177 return error.UnsupportedTableDataType; 178 178 },