a modern tui library written in zig

render: advance by width of grapheme

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

+18 -8
+18 -8
src/vaxis.zig
··· 10 10 const Window = @import("Window.zig"); 11 11 const Options = @import("Options.zig"); 12 12 const Style = @import("cell.zig").Style; 13 + const strWidth = @import("ziglyph").display_width.strWidth; 13 14 14 15 /// Vaxis is the entrypoint for a Vaxis application. The provided type T should 15 16 /// be a tagged union which contains all of the events the application will ··· 73 74 pub fn deinit(self: *Self, alloc: ?std.mem.Allocator) void { 74 75 if (self.tty) |_| { 75 76 var tty = &self.tty.?; 77 + if (self.kitty_keyboard) { 78 + _ = tty.write(ctlseqs.csi_u_pop) catch {}; 79 + } 76 80 if (self.alt_screen) { 77 81 _ = tty.write(ctlseqs.rmcup) catch {}; 78 - tty.flush() catch {}; 79 82 } 80 - if (self.kitty_keyboard) { 81 - _ = tty.write(ctlseqs.csi_u_pop) catch {}; 82 - tty.flush() catch {}; 83 - } 83 + tty.flush() catch {}; 84 84 tty.deinit(); 85 85 } 86 86 if (alloc) |a| { ··· 242 242 var cursor: Style = .{}; 243 243 244 244 var i: usize = 0; 245 - while (i < self.screen.buf.len) : (i += 1) { 245 + while (i < self.screen.buf.len) { 246 246 const cell = self.screen.buf[i]; 247 - defer col += 1; 248 - if (col == self.screen.width) { 247 + defer { 248 + // advance by the width of this char mod 1 249 + const width = blk: { 250 + if (cell.char.width > 0) break :blk cell.char.width; 251 + break :blk strWidth(cell.char.grapheme, .half) catch 1; 252 + }; 253 + col += width; 254 + i += width; 255 + } 256 + if (col >= self.screen.width) { 249 257 row += 1; 250 258 col = 0; 251 259 } ··· 422 430 } 423 431 424 432 pub fn enableKittyKeyboard(self: *Self, flags: Key.KittyFlags) !void { 433 + self.kitty_keyboard = true; 425 434 const flag_int: u5 = @bitCast(flags); 426 435 try std.fmt.format( 427 436 self.tty.?.buffered_writer.writer(), ··· 430 439 flag_int, 431 440 }, 432 441 ); 442 + try self.tty.?.flush(); 433 443 } 434 444 }; 435 445 }