diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-04 19:22:04 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 01:23:06 +0300 |
| commit | 41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch) | |
| tree | 3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/unicode/props_uucode.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/unicode/props_uucode.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/unicode/props_uucode.zig | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/unicode/props_uucode.zig b/vendor/libghostty-vt/src/unicode/props_uucode.zig new file mode 100644 index 00000000..527a757e --- /dev/null +++ b/vendor/libghostty-vt/src/unicode/props_uucode.zig @@ -0,0 +1,85 @@ +const props = @This(); +const std = @import("std"); +const assert = std.debug.assert; +const uucode = @import("uucode"); +const lut = @import("lut.zig"); +const Properties = @import("props.zig").Properties; + +pub fn get(cp: u21) Properties { + if (cp > uucode.config.max_code_point) return .{ + .width = 1, + .width_zero_in_grapheme = true, + .grapheme_break = .other, + .emoji_vs_base = false, + }; + + return .{ + .width = uucode.get(.width, cp), + .width_zero_in_grapheme = uucode.get(.wcwidth_zero_in_grapheme, cp), + .grapheme_break = uucode.get(.grapheme_break_no_control, cp), + .emoji_vs_base = uucode.get(.is_emoji_vs_base, cp), + }; +} + +/// Runnable binary to generate the lookup tables and output to stdout. +pub fn main() !void { + var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena_state.deinit(); + const alloc = arena_state.allocator(); + + const gen: lut.Generator( + Properties, + struct { + pub fn get(ctx: @This(), cp: u21) !Properties { + _ = ctx; + return props.get(cp); + } + + pub fn eql(ctx: @This(), a: Properties, b: Properties) bool { + _ = ctx; + return a.eql(b); + } + }, + ) = .{}; + + const t = try gen.generate(alloc); + defer alloc.free(t.stage1); + defer alloc.free(t.stage2); + defer alloc.free(t.stage3); + + var buf: [4096]u8 = undefined; + var stdout = std.fs.File.stdout().writer(&buf); + try t.writeZig(&stdout.interface); + // Use flush instead of end because stdout is a pipe when captured by + // the build system, and pipes cannot be truncated (Windows returns + // INVALID_PARAMETER, Linux returns EINVAL). + try stdout.interface.flush(); + + // Uncomment when manually debugging to see our table sizes. + // std.log.warn("stage1={} stage2={} stage3={}", .{ + // t.stage1.len, + // t.stage2.len, + // t.stage3.len, + // }); +} + +test "unicode props: tables match uucode" { + if (std.valgrind.runningOnValgrind() > 0) return error.SkipZigTest; + + const testing = std.testing; + const table = @import("props_table.zig").table; + + const min = 0xFF + 1; // start outside ascii + const max = std.math.maxInt(u21) + 1; + for (min..max) |cp| { + const t = table.get(@intCast(cp)); + const uu = if (cp > uucode.config.max_code_point) + 1 + else + uucode.get(.width, @intCast(cp)); + if (t.width != uu) { + std.log.warn("mismatch cp=U+{x} t={} uu={}", .{ cp, t.width, uu }); + try testing.expect(false); + } + } +} |
