aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/unicode
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/unicode
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/unicode')
-rw-r--r--vendor/libghostty-vt/src/unicode/grapheme.zig24
-rw-r--r--vendor/libghostty-vt/src/unicode/props.zig14
-rw-r--r--vendor/libghostty-vt/src/unicode/props_uucode.zig8
-rw-r--r--vendor/libghostty-vt/src/unicode/symbols_uucode.zig8
4 files changed, 33 insertions, 21 deletions
diff --git a/vendor/libghostty-vt/src/unicode/grapheme.zig b/vendor/libghostty-vt/src/unicode/grapheme.zig
index 73782dd6..79968935 100644
--- a/vendor/libghostty-vt/src/unicode/grapheme.zig
+++ b/vendor/libghostty-vt/src/unicode/grapheme.zig
@@ -141,22 +141,28 @@ inline fn invalidCodepoint(cp: anytype) bool {
/// This is all the structures and data for the precomputed lookup table
/// for all possible permutations of state and grapheme break properties.
-/// Precomputation requires 2^13 keys of 4 bit values so the whole table is
-/// 8KB.
+/// Precomputation requires 2^13 keys of byte-sized values so the whole
+/// table is 8KB.
const Precompute = struct {
const Key = packed struct(u13) {
state: uucode.grapheme.BreakState,
- gb1: uucode.x.types.GraphemeBreakNoControl,
- gb2: uucode.x.types.GraphemeBreakNoControl,
+ gb1: uucode.types.GraphemeBreakNoControl,
+ gb2: uucode.types.GraphemeBreakNoControl,
fn index(self: Key) usize {
return @intCast(@as(u13, @bitCast(self)));
}
};
- const Value = packed struct(u4) {
+ const Value = packed struct(u8) {
result: bool,
state: uucode.grapheme.BreakState,
+
+ /// Explicit padding to give the struct a power-of-two backing
+ /// integer, for the same reason as `Properties._padding` (avoids
+ /// exotic-width LLVM integer accesses that defeat register
+ /// promotion). @sizeOf was already 1, so the table stays 8KB.
+ _padding: u4 = 0,
};
const data = precompute: {
@@ -171,18 +177,18 @@ const Precompute = struct {
};
@setEvalBranchQuota(10_000);
- const info = @typeInfo(uucode.x.types.GraphemeBreakNoControl).@"enum";
+ const info = @typeInfo(uucode.types.GraphemeBreakNoControl).@"enum";
for (0..max_state_int + 1) |state_int| {
for (info.fields) |field1| {
for (info.fields) |field2| {
var state: uucode.grapheme.BreakState = @enumFromInt(state_int);
const key: Key = .{
- .gb1 = @field(uucode.x.types.GraphemeBreakNoControl, field1.name),
- .gb2 = @field(uucode.x.types.GraphemeBreakNoControl, field2.name),
+ .gb1 = @field(uucode.types.GraphemeBreakNoControl, field1.name),
+ .gb2 = @field(uucode.types.GraphemeBreakNoControl, field2.name),
.state = state,
};
- const v = uucode.x.grapheme.computeGraphemeBreakNoControl(
+ const v = uucode.grapheme.computeGraphemeBreakNoControl(
key.gb1,
key.gb2,
&state,
diff --git a/vendor/libghostty-vt/src/unicode/props.zig b/vendor/libghostty-vt/src/unicode/props.zig
index 2653f0cc..dd6a4dbb 100644
--- a/vendor/libghostty-vt/src/unicode/props.zig
+++ b/vendor/libghostty-vt/src/unicode/props.zig
@@ -7,7 +7,7 @@
const std = @import("std");
const uucode = @import("uucode");
-pub const Properties = packed struct {
+pub const Properties = packed struct(u16) {
/// Codepoint width. We clamp to [0, 2] since Ghostty handles control
/// characters and we max out at 2 for wide characters (i.e. 3-em dash
/// becomes a 2-em dash).
@@ -18,11 +18,21 @@ pub const Properties = packed struct {
width_zero_in_grapheme: bool = false,
/// Grapheme break property.
- grapheme_break: uucode.x.types.GraphemeBreakNoControl = .other,
+ grapheme_break: uucode.types.GraphemeBreakNoControl = .other,
/// Emoji VS compatibility
emoji_vs_base: bool = false,
+ /// Explicit padding to give the struct a power-of-two backing integer.
+ /// This is a performance workaround: with a non-power-of-two backing
+ /// integer (u9), Zig 0.16 lowers loads/stores of this struct through
+ /// mismatched exotic-width LLVM integer types (store i9 / load i16),
+ /// which blocks LLVM from promoting temporaries to registers and forces
+ /// stack round-trips in hot paths like `graphemeBreak`. See
+ /// https://github.com/ziglang/zig/issues/21891 for the upstream issue.
+ /// The size of the lookup table is unchanged (@sizeOf was already 2).
+ _padding: u7 = 0,
+
// Needed for lut.Generator
pub fn eql(a: Properties, b: Properties) bool {
return a.width == b.width and
diff --git a/vendor/libghostty-vt/src/unicode/props_uucode.zig b/vendor/libghostty-vt/src/unicode/props_uucode.zig
index 527a757e..211d1ac3 100644
--- a/vendor/libghostty-vt/src/unicode/props_uucode.zig
+++ b/vendor/libghostty-vt/src/unicode/props_uucode.zig
@@ -22,10 +22,8 @@ pub fn get(cp: u21) Properties {
}
/// 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();
+pub fn main(init: std.process.Init) !void {
+ const alloc = init.arena.allocator();
const gen: lut.Generator(
Properties,
@@ -48,7 +46,7 @@ pub fn main() !void {
defer alloc.free(t.stage3);
var buf: [4096]u8 = undefined;
- var stdout = std.fs.File.stdout().writer(&buf);
+ var stdout = std.Io.File.stdout().writer(init.io, &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
diff --git a/vendor/libghostty-vt/src/unicode/symbols_uucode.zig b/vendor/libghostty-vt/src/unicode/symbols_uucode.zig
index 794ca5ba..94344388 100644
--- a/vendor/libghostty-vt/src/unicode/symbols_uucode.zig
+++ b/vendor/libghostty-vt/src/unicode/symbols_uucode.zig
@@ -3,10 +3,8 @@ const uucode = @import("uucode");
const lut = @import("lut.zig");
/// 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();
+pub fn main(init: std.process.Init) !void {
+ const alloc = init.arena.allocator();
const gen: lut.Generator(
bool,
@@ -32,7 +30,7 @@ pub fn main() !void {
defer alloc.free(t.stage3);
var buf: [4096]u8 = undefined;
- var stdout = std.fs.File.stdout().writer(&buf);
+ var stdout = std.Io.File.stdout().writer(init.io, &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