aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/terminal/point.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/terminal/point.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/terminal/point.zig')
-rw-r--r--vendor/libghostty-vt/src/terminal/point.zig94
1 files changed, 94 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/terminal/point.zig b/vendor/libghostty-vt/src/terminal/point.zig
new file mode 100644
index 00000000..4297bf5b
--- /dev/null
+++ b/vendor/libghostty-vt/src/terminal/point.zig
@@ -0,0 +1,94 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const lib = @import("lib.zig");
+const size = @import("size.zig");
+
+/// The possible reference locations for a point. When someone says "(42, 80)"
+/// in the context of a terminal, that could mean multiple things: it is in the
+/// current visible viewport? the current active area of the screen where the
+/// cursor is? the entire scrollback history? etc.
+///
+/// This tag is used to differentiate those cases.
+pub const Tag = lib.Enum(lib.target, &.{
+ // Top-left is part of the active area where a running program can
+ // jump the cursor and make changes. The active area is the "editable"
+ // part of the screen.
+ //
+ // The bottom-right of the active tag differs from all other tags
+ // because it includes the full height (rows) of the screen, including
+ // rows that may not be written yet. This is required because the active
+ // area is fully "addressable" by the running program (see below) whereas
+ // the other tags are used primarily for reading/modifying past-written
+ // data so they can't address unwritten rows.
+ //
+ // Note for those less familiar with terminal functionality: there
+ // are escape sequences to move the cursor to any position on
+ // the screen, but it is limited to the size of the viewport and
+ // the bottommost part of the screen. Terminal programs can't --
+ // with sequences at the time of writing this comment -- modify
+ // anything in the scrollback, visible viewport (if it differs
+ // from the active area), etc.
+ "active",
+
+ // Top-left is the visible viewport. This means that if the user
+ // has scrolled in any direction, top-left changes. The bottom-right
+ // is the last written row from the top-left.
+ "viewport",
+
+ // Top-left is the furthest back in the scrollback history
+ // supported by the screen and the bottom-right is the bottom-right
+ // of the last written row. Note this last point is important: the
+ // bottom right is NOT necessarily the same as "active" because
+ // "active" always allows referencing the full rows tall of the
+ // screen whereas "screen" only contains written rows.
+ "screen",
+
+ // The top-left is the same as "screen" but the bottom-right is
+ // the line just before the top of "active". This contains only
+ // the scrollback history.
+ "history",
+});
+
+/// An x/y point in the terminal for some definition of location (tag).
+pub const Point = union(Tag) {
+ active: Coordinate,
+ viewport: Coordinate,
+ screen: Coordinate,
+ history: Coordinate,
+
+ pub inline fn coord(self: Point) Coordinate {
+ return switch (self) {
+ .active,
+ .viewport,
+ .screen,
+ .history,
+ => |v| v,
+ };
+ }
+
+ const c_union = lib.TaggedUnion(
+ lib.target,
+ @This(),
+ // Padding: largest variant is Coordinate (u16 + u32 = 6 bytes).
+ // Use [2]u64 (16 bytes) for future expansion.
+ [2]u64,
+ );
+ pub const C = c_union.C;
+ pub const CValue = c_union.CValue;
+ pub const cval = c_union.cval;
+};
+
+pub const Coordinate = extern struct {
+ /// x can use size.CellCountInt because the number of columns
+ /// can't ever be more than a valid number of columns in a Page.
+ x: size.CellCountInt = 0,
+
+ /// y does not use size.CellCountInt because certain coordinate
+ /// usage such as screen/history can have more rows than are possible
+ /// in a single page.
+ y: u32 = 0,
+
+ pub fn eql(self: Coordinate, other: Coordinate) bool {
+ return self.x == other.x and self.y == other.y;
+ }
+};