aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/apprt/gtk/ext/slice.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/apprt/gtk/ext/slice.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/apprt/gtk/ext/slice.zig')
-rw-r--r--vendor/libghostty-vt/src/apprt/gtk/ext/slice.zig111
1 files changed, 111 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/apprt/gtk/ext/slice.zig b/vendor/libghostty-vt/src/apprt/gtk/ext/slice.zig
new file mode 100644
index 00000000..49ad63d8
--- /dev/null
+++ b/vendor/libghostty-vt/src/apprt/gtk/ext/slice.zig
@@ -0,0 +1,111 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const ArenaAllocator = std.heap.ArenaAllocator;
+const glib = @import("glib");
+const gobject = @import("gobject");
+
+/// A boxed type that holds a list of string slices.
+pub const StringList = struct {
+ arena: ArenaAllocator,
+ strings: []const [:0]const u8,
+
+ pub fn create(
+ alloc: Allocator,
+ strings: []const [:0]const u8,
+ ) Allocator.Error!*StringList {
+ var arena: ArenaAllocator = .init(alloc);
+ errdefer arena.deinit();
+ const arena_alloc = arena.allocator();
+ var stored = try arena_alloc.alloc([:0]const u8, strings.len);
+ for (strings, 0..) |s, i| stored[i] = try arena_alloc.dupeZ(u8, s);
+
+ const ptr = try alloc.create(StringList);
+ errdefer alloc.destroy(ptr);
+ ptr.* = .{ .arena = arena, .strings = stored };
+
+ return ptr;
+ }
+
+ pub fn deinit(self: *StringList) void {
+ self.arena.deinit();
+ }
+
+ pub fn destroy(self: *StringList) void {
+ const alloc = self.arena.child_allocator;
+ self.deinit();
+ alloc.destroy(self);
+ }
+
+ /// Returns the general-purpose allocator used by this StringList.
+ pub fn allocator(self: *const StringList) Allocator {
+ return self.arena.child_allocator;
+ }
+
+ pub const getGObjectType = gobject.ext.defineBoxed(
+ StringList,
+ .{
+ .name = "GhosttyStringList",
+ .funcs = .{
+ .copy = &struct {
+ fn copy(self: *StringList) callconv(.c) *StringList {
+ return StringList.create(
+ self.arena.child_allocator,
+ self.strings,
+ ) catch @panic("OOM");
+ }
+ }.copy,
+ .free = &struct {
+ fn free(self: *StringList) callconv(.c) void {
+ self.destroy();
+ }
+ }.free,
+ },
+ },
+ );
+};
+
+test "StringList create and destroy" {
+ const testing = std.testing;
+ const alloc = testing.allocator;
+
+ const input: []const [:0]const u8 = &.{ "hello", "world" };
+ const list = try StringList.create(alloc, input);
+ defer list.destroy();
+
+ try testing.expectEqual(@as(usize, 2), list.strings.len);
+ try testing.expectEqualStrings("hello", list.strings[0]);
+ try testing.expectEqualStrings("world", list.strings[1]);
+}
+
+test "StringList create empty list" {
+ const testing = std.testing;
+ const alloc = testing.allocator;
+
+ const input: []const [:0]const u8 = &.{};
+ const list = try StringList.create(alloc, input);
+ defer list.destroy();
+
+ try testing.expectEqual(@as(usize, 0), list.strings.len);
+}
+
+test "StringList boxedCopy and boxedFree" {
+ const testing = std.testing;
+ const alloc = testing.allocator;
+
+ const input: []const [:0]const u8 = &.{ "foo", "bar", "baz" };
+ const original = try StringList.create(alloc, input);
+ defer original.destroy();
+
+ const copied: *StringList = @ptrCast(@alignCast(gobject.boxedCopy(
+ StringList.getGObjectType(),
+ original,
+ )));
+ defer gobject.boxedFree(StringList.getGObjectType(), copied);
+
+ try testing.expectEqual(@as(usize, 3), copied.strings.len);
+ try testing.expectEqualStrings("foo", copied.strings[0]);
+ try testing.expectEqualStrings("bar", copied.strings[1]);
+ try testing.expectEqualStrings("baz", copied.strings[2]);
+
+ try testing.expect(original.strings.ptr != copied.strings.ptr);
+}