aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/terminal/c/grid_ref.zig
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-07 18:29:21 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-07 18:29:21 +0300
commitdcfe11a7588fcd42471159453810abc9b7720a57 (patch)
treec32a77266028e73ca2382b96c96f8438a5fcd621 /vendor/libghostty-vt/src/terminal/c/grid_ref.zig
parent2dfed860103c4e4505ac7f25def9fe37da1e1e6a (diff)
build: update libghostty-vt vendor
vendor ghostty 063ac3e and remove the musl libc++ link workaround. expose the new selection formatter and hyperlink uri apis for follow-up rendering work. add manual artifact validation for static linux builds.
Diffstat (limited to 'vendor/libghostty-vt/src/terminal/c/grid_ref.zig')
-rw-r--r--vendor/libghostty-vt/src/terminal/c/grid_ref.zig96
1 files changed, 95 insertions, 1 deletions
diff --git a/vendor/libghostty-vt/src/terminal/c/grid_ref.zig b/vendor/libghostty-vt/src/terminal/c/grid_ref.zig
index d029c595..db7ff2e8 100644
--- a/vendor/libghostty-vt/src/terminal/c/grid_ref.zig
+++ b/vendor/libghostty-vt/src/terminal/c/grid_ref.zig
@@ -3,11 +3,13 @@ const testing = std.testing;
const lib = @import("../lib.zig");
const page = @import("../page.zig");
const PageList = @import("../PageList.zig");
+const point = @import("../point.zig");
const size = @import("../size.zig");
const stylepkg = @import("../style.zig");
const cell_c = @import("cell.zig");
const row_c = @import("row.zig");
const style_c = @import("style.zig");
+const terminal_c = @import("terminal.zig");
const Result = @import("result.zig").Result;
/// C: GhosttyGridRef
@@ -29,7 +31,7 @@ pub const CGridRef = extern struct {
};
}
- fn toPin(self: CGridRef) ?PageList.Pin {
+ pub fn toPin(self: CGridRef) ?PageList.Pin {
return .{
.node = self.node orelse return null,
.x = self.x,
@@ -89,6 +91,38 @@ pub fn grid_ref_graphemes(
return .success;
}
+pub fn grid_ref_hyperlink_uri(
+ ref: *const CGridRef,
+ out_buf: ?[*]u8,
+ buf_len: usize,
+ out_len: *usize,
+) callconv(lib.calling_conv) Result {
+ const p = ref.toPin() orelse return .invalid_value;
+ const rac = p.node.data.getRowAndCell(p.x, p.y);
+ const cell = rac.cell;
+
+ if (!cell.hyperlink) {
+ out_len.* = 0;
+ return .success;
+ }
+
+ const link_id = p.node.data.lookupHyperlink(cell) orelse {
+ out_len.* = 0;
+ return .success;
+ };
+ const entry = p.node.data.hyperlink_set.get(p.node.data.memory, link_id);
+ const uri = entry.uri.slice(p.node.data.memory);
+
+ if (out_buf == null or buf_len < uri.len) {
+ out_len.* = uri.len;
+ return .out_of_space;
+ }
+
+ @memcpy(out_buf.?[0..uri.len], uri);
+ out_len.* = uri.len;
+ return .success;
+}
+
pub fn grid_ref_style(
ref: *const CGridRef,
out: ?*style_c.Style,
@@ -154,3 +188,63 @@ test "grid_ref_style null out" {
const ref = CGridRef{};
try testing.expectEqual(Result.invalid_value, grid_ref_style(&ref, null));
}
+
+test "grid_ref_hyperlink_uri null node" {
+ const ref = CGridRef{};
+ var len: usize = undefined;
+ try testing.expectEqual(Result.invalid_value, grid_ref_hyperlink_uri(&ref, null, 0, &len));
+}
+
+test "grid_ref_hyperlink_uri no hyperlink" {
+ var terminal: terminal_c.Terminal = null;
+ try testing.expectEqual(Result.success, terminal_c.new(
+ &lib.alloc.test_allocator,
+ &terminal,
+ .{ .cols = 80, .rows = 24, .max_scrollback = 10_000 },
+ ));
+ defer terminal_c.free(terminal);
+
+ terminal_c.vt_write(terminal, "hello", 5);
+
+ var ref: CGridRef = undefined;
+ try testing.expectEqual(Result.success, terminal_c.grid_ref(
+ terminal,
+ point.Point.cval(.{ .active = .{ .x = 0, .y = 0 } }),
+ &ref,
+ ));
+
+ var len: usize = undefined;
+ try testing.expectEqual(Result.success, grid_ref_hyperlink_uri(&ref, null, 0, &len));
+ try testing.expectEqual(@as(usize, 0), len);
+}
+
+test "grid_ref_hyperlink_uri with hyperlink" {
+ var terminal: terminal_c.Terminal = null;
+ try testing.expectEqual(Result.success, terminal_c.new(
+ &lib.alloc.test_allocator,
+ &terminal,
+ .{ .cols = 80, .rows = 24, .max_scrollback = 10_000 },
+ ));
+ defer terminal_c.free(terminal);
+
+ // Write OSC 8 hyperlink: \e]8;;uri\e\\text\e]8;;\e\\
+ const seq = "\x1b]8;;https://example.com\x1b\\link\x1b]8;;\x1b\\";
+ terminal_c.vt_write(terminal, seq, seq.len);
+
+ var ref: CGridRef = undefined;
+ try testing.expectEqual(Result.success, terminal_c.grid_ref(
+ terminal,
+ point.Point.cval(.{ .active = .{ .x = 0, .y = 0 } }),
+ &ref,
+ ));
+
+ // First query length with null buf
+ var len: usize = undefined;
+ try testing.expectEqual(Result.out_of_space, grid_ref_hyperlink_uri(&ref, null, 0, &len));
+ try testing.expectEqual(@as(usize, 19), len); // "https://example.com"
+
+ // Now read with a properly sized buffer
+ var buf: [256]u8 = undefined;
+ try testing.expectEqual(Result.success, grid_ref_hyperlink_uri(&ref, &buf, buf.len, &len));
+ try testing.expectEqualStrings("https://example.com", buf[0..len]);
+}