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/pkg/macos/foundation/array.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/pkg/macos/foundation/array.zig')
| -rw-r--r-- | vendor/libghostty-vt/pkg/macos/foundation/array.zig | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/pkg/macos/foundation/array.zig b/vendor/libghostty-vt/pkg/macos/foundation/array.zig new file mode 100644 index 00000000..7b580eb0 --- /dev/null +++ b/vendor/libghostty-vt/pkg/macos/foundation/array.zig @@ -0,0 +1,176 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const base = @import("base.zig"); +const c = @import("c.zig").c; +const cftype = @import("type.zig"); +const ComparisonResult = base.ComparisonResult; +const Range = base.Range; + +pub const Array = opaque { + pub fn create(comptime T: type, values: []*const T) Allocator.Error!*Array { + return CFArrayCreate( + null, + @ptrCast(values.ptr), + @intCast(values.len), + null, + ) orelse error.OutOfMemory; + } + + pub fn release(self: *Array) void { + cftype.CFRelease(self); + } + + pub fn getCount(self: *Array) usize { + return CFArrayGetCount(self); + } + + /// Note the return type is actually a `*const T` but we strip the + /// constness so that further API calls work correctly. The Foundation + /// API doesn't properly mark things const/non-const. + pub fn getValueAtIndex(self: *Array, comptime T: type, idx: usize) *T { + return @ptrCast(@alignCast(CFArrayGetValueAtIndex(self, idx))); + } + + pub extern "c" fn CFArrayCreate( + allocator: ?*anyopaque, + values: [*]*const anyopaque, + num_values: usize, + callbacks: ?*const anyopaque, + ) ?*Array; + pub extern "c" fn CFArrayGetCount(*Array) usize; + pub extern "c" fn CFArrayGetValueAtIndex(*Array, usize) *anyopaque; + extern "c" var kCFTypeArrayCallBacks: anyopaque; +}; + +pub const MutableArray = opaque { + pub fn create() Allocator.Error!*MutableArray { + return CFArrayCreateMutable( + null, + 0, + &c.kCFTypeArrayCallBacks, + ) orelse error.OutOfMemory; + } + + pub fn createCopy(array: *Array) Allocator.Error!*MutableArray { + return CFArrayCreateMutableCopy( + null, + 0, + array, + ) orelse error.OutOfMemory; + } + + pub fn release(self: *MutableArray) void { + cftype.CFRelease(self); + } + + pub fn appendValue( + self: *MutableArray, + comptime Elem: type, + value: *const Elem, + ) void { + CFArrayAppendValue(self, @ptrCast(@constCast(value))); + } + + pub fn removeValue(self: *MutableArray, idx: usize) void { + CFArrayRemoveValueAtIndex(self, idx); + } + + pub fn sortValues( + self: *MutableArray, + comptime Elem: type, + comptime Context: type, + context: ?*Context, + comptime comparator: ?*const fn ( + a: *const Elem, + b: *const Elem, + context: ?*Context, + ) callconv(.c) ComparisonResult, + ) void { + CFArraySortValues( + self, + Range.init(0, Array.CFArrayGetCount(@ptrCast(self))), + comparator, + context, + ); + } + + extern "c" fn CFArrayCreateMutable( + allocator: ?*anyopaque, + capacity: usize, + callbacks: ?*const anyopaque, + ) ?*MutableArray; + extern "c" fn CFArrayCreateMutableCopy( + allocator: ?*anyopaque, + capacity: usize, + array: *Array, + ) ?*MutableArray; + extern "c" fn CFArrayAppendValue( + *MutableArray, + *anyopaque, + ) void; + extern "c" fn CFArrayRemoveValueAtIndex( + *MutableArray, + usize, + ) void; + extern "c" fn CFArraySortValues( + array: *MutableArray, + range: Range, + comparator: ?*const anyopaque, + context: ?*anyopaque, + ) void; +}; + +test "array" { + const testing = std.testing; + + const str = "hello"; + var values = [_]*const u8{ &str[0], &str[1] }; + const arr = try Array.create(u8, &values); + defer arr.release(); + + try testing.expectEqual(@as(usize, 2), arr.getCount()); + + { + const ch = arr.getValueAtIndex(u8, 0); + try testing.expectEqual(@as(u8, 'h'), ch.*); + } + + // Can make it mutable + var mut = try MutableArray.createCopy(arr); + defer mut.release(); +} + +test "array sorting" { + const testing = std.testing; + + const str = "hello"; + var values = [_]*const u8{ &str[0], &str[1] }; + const arr = try Array.create(u8, &values); + defer arr.release(); + const mut = try MutableArray.createCopy(arr); + defer mut.release(); + + mut.sortValues( + u8, + void, + null, + struct { + fn compare(a: *const u8, b: *const u8, _: ?*void) callconv(.c) ComparisonResult { + if (a.* > b.*) return .greater; + if (a.* == b.*) return .equal; + return .less; + } + }.compare, + ); + + { + const mutarr: *Array = @ptrCast(mut); + const ch = mutarr.getValueAtIndex(u8, 0); + try testing.expectEqual(@as(u8, 'e'), ch.*); + } + { + const mutarr: *Array = @ptrCast(mut); + const ch = mutarr.getValueAtIndex(u8, 1); + try testing.expectEqual(@as(u8, 'h'), ch.*); + } +} |
