libghostty
Loading...
Searching...
No Matches
Grid Reference

Detailed Description

A grid reference is a reference to a specific cell position in the terminal. Obtain a grid reference from ghostty_terminal_grid_ref for untracked or ghostty_terminal_grid_ref_track for tracked. Untracked vs tracked is explained next.

Important: The grid reference APIs are not meant to be used as the core of a render loop. They are not built to sustain the framerates needed for rendering large screens. Use the render state API for that.

Untracked vs Tracked References

Untracked Reference

An untracked grid reference is a value type that snapshots a specific cell. It is only valid until the next update to the terminal instance. There is no guarantee that it will remain valid after any operation, even if a seemingly unrelated part of the grid is changed. These are meant to be read and have their values cached immediately after obtaining it.

An untracked grid reference has a performance cost in its initial lookup, but doesn't affect the ongoing performance of the terminal in any way, since it is a one-time snapshot.

Tracked Reference

A tracked grid reference follows its cell across normal screen operations. For example scrolling, scrollback pruning, resize/reflow, and other terminal mutations update the tracked reference automatically.

A tracked reference can still lose its original semantic location. This can happen when the underlying grid is reset, pruned, or otherwise discarded in a way that cannot be mapped to a meaningful new cell. In that state, ghostty_tracked_grid_ref_has_value() returns false and ghostty_tracked_grid_ref_snapshot() / ghostty_tracked_grid_ref_point() return GHOSTTY_NO_VALUE. The handle remains valid, and callers may move it to a new point with ghostty_tracked_grid_ref_set().

To read cell data from a tracked reference, first snapshot it with ghostty_tracked_grid_ref_snapshot(). The returned GhosttyGridRef is again an untracked reference and follows the same short lifetime rules as any other untracked grid reference.

A tracked reference belongs to the terminal screen/page-list that was active when it was created or last set. Converting it to a point uses that owning screen/page-list, even if the terminal has since switched between primary and alternate screens. Calling ghostty_tracked_grid_ref_set() resolves the new point against the terminal's currently active screen/page-list and may move the tracked reference between screens.

Tracked references are owned by the caller and must be freed with ghostty_tracked_grid_ref_free(). If the terminal that created a tracked reference is freed first, the handle remains valid only for tracked-grid-ref APIs: it reports no value and can still be freed.

Each tracked reference adds bookkeeping to terminal mutations. Use them sparingly for long-lived anchors such as selections, search state, marks, or application-side bookmarks.

Lifetime

An untracked reference is a snapshot. It doesn't need to be freed. The safety of accessing the value is documented explicitly above: it is only safe to access any data until the next terminal mutating operation (including free).

A tracked reference is allocated and must be freed when it is no longer needed. A tracked reference may outlive the terminal that created it; after terminal free, it reports no value and can still be freed.

Examples

int main() {
// Create a small terminal
GhosttyTerminal terminal;
.cols = 10,
.rows = 3,
.max_scrollback = 0,
};
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
assert(result == GHOSTTY_SUCCESS);
// Write some content so the grid has interesting data
const char *text = "Hello!\r\n" // Row 0: H e l l o !
"World\r\n" // Row 1: W o r l d
"\033[1mBold"; // Row 2: B o l d (bold style)
terminal, (const uint8_t *)text, strlen(text));
// Get terminal dimensions
uint16_t cols, rows;
// Traverse the entire grid using grid refs
for (uint16_t row = 0; row < rows; row++) {
printf("Row %u: ", row);
for (uint16_t col = 0; col < cols; col++) {
// Resolve the point to a grid reference
GhosttyPoint pt = {
.value = { .coordinate = { .x = col, .y = row } },
};
result = ghostty_terminal_grid_ref(terminal, pt, &ref);
assert(result == GHOSTTY_SUCCESS);
// Read the cell from the grid ref
result = ghostty_grid_ref_cell(&ref, &cell);
assert(result == GHOSTTY_SUCCESS);
// Check if the cell has text
bool has_text = false;
if (has_text) {
uint32_t codepoint = 0;
printf("%c", (char)codepoint);
} else {
printf(".");
}
}
// Also inspect the row for wrap state
GhosttyPoint pt = {
.value = { .coordinate = { .x = 0, .y = row } },
};
ghostty_terminal_grid_ref(terminal, pt, &ref);
GhosttyRow grid_row;
ghostty_grid_ref_row(&ref, &grid_row);
bool wrap = false;
printf(" (wrap=%s", wrap ? "true" : "false");
// Check the style of the first cell with text
ghostty_grid_ref_style(&ref, &style);
printf(", bold=%s)\n", style.bold ? "true" : "false");
}
return 0;
}
static uint32_t codepoint_at_tracked_ref(GhosttyTrackedGridRef tracked) {
GhosttyResult result = ghostty_tracked_grid_ref_snapshot(tracked, &snapshot);
assert(result == GHOSTTY_SUCCESS);
result = ghostty_grid_ref_cell(&snapshot, &cell);
assert(result == GHOSTTY_SUCCESS);
bool has_text = false;
assert(has_text);
uint32_t codepoint = 0;
return codepoint;
}
int main() {
GhosttyTerminal terminal;
.cols = 8,
.rows = 3,
.max_scrollback = 100,
};
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
assert(result == GHOSTTY_SUCCESS);
const char *text = "alpha\r\n"
"bravo\r\n"
"charlie";
terminal, (const uint8_t *)text, strlen(text));
GhosttyTrackedGridRef tracked = NULL;
GhosttyPoint alpha = {
.value = { .coordinate = { .x = 0, .y = 0 } },
};
result = ghostty_terminal_grid_ref_track(terminal, alpha, &tracked);
assert(result == GHOSTTY_SUCCESS);
// Writing another line scrolls the original "alpha" row into scrollback.
// The tracked ref still follows the same cell.
const char *more = "\r\ndelta";
terminal, (const uint8_t *)more, strlen(more));
printf("tracked codepoint after scroll: %c\n",
(char)codepoint_at_tracked_ref(tracked));
GhosttyPointCoordinate screen = {0};
tracked, GHOSTTY_POINT_TAG_SCREEN, &screen);
assert(result == GHOSTTY_SUCCESS);
printf("tracked screen point: %u,%u\n", screen.x, screen.y);
// Resetting the terminal discards the old grid contents. The tracked
// handle remains valid, but no longer has a meaningful location.
result = ghostty_tracked_grid_ref_snapshot(tracked, &discarded);
assert(result == GHOSTTY_NO_VALUE);
// The same handle can be moved to a new point after it loses its value.
const char *replacement = "echo";
terminal, (const uint8_t *)replacement, strlen(replacement));
GhosttyPoint echo = {
.value = { .coordinate = { .x = 0, .y = 0 } },
};
result = ghostty_tracked_grid_ref_set(tracked, terminal, echo);
assert(result == GHOSTTY_SUCCESS);
printf("tracked codepoint after reset/set: %c\n",
(char)codepoint_at_tracked_ref(tracked));
return 0;
}

Typedefs

typedef struct GhosttyTrackedGridRefImpl * GhosttyTrackedGridRef

Functions

GHOSTTY_API GhosttyResult ghostty_grid_ref_cell (const GhosttyGridRef *ref, GhosttyCell *out_cell)
GHOSTTY_API GhosttyResult ghostty_grid_ref_row (const GhosttyGridRef *ref, GhosttyRow *out_row)
GHOSTTY_API GhosttyResult ghostty_grid_ref_graphemes (const GhosttyGridRef *ref, uint32_t *buf, size_t buf_len, size_t *out_len)
GHOSTTY_API GhosttyResult ghostty_grid_ref_hyperlink_uri (const GhosttyGridRef *ref, uint8_t *buf, size_t buf_len, size_t *out_len)
GHOSTTY_API GhosttyResult ghostty_grid_ref_style (const GhosttyGridRef *ref, GhosttyStyle *out_style)
GHOSTTY_API void ghostty_tracked_grid_ref_free (GhosttyTrackedGridRef ref)
GHOSTTY_API bool ghostty_tracked_grid_ref_has_value (GhosttyTrackedGridRef ref)
GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_point (GhosttyTrackedGridRef ref, GhosttyPointTag tag, GhosttyPointCoordinate *out_point)
GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_set (GhosttyTrackedGridRef ref, GhosttyTerminal terminal, GhosttyPoint point)
GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_snapshot (GhosttyTrackedGridRef ref, GhosttyGridRef *out_ref)

Data Structures

struct  GhosttyGridRef

Typedef Documentation

◆ GhosttyTrackedGridRef

typedef struct GhosttyTrackedGridRefImpl* GhosttyTrackedGridRef

Opaque handle to a tracked grid reference.

A tracked grid reference is owned by the caller and must be freed with ghostty_tracked_grid_ref_free(). If the terminal that created it is freed first, the handle remains valid only for tracked-grid-ref APIs: it reports no value and can still be freed.

Examples
c-vt-grid-ref-tracked/src/main.c.

Definition at line 107 of file types.h.

Function Documentation

◆ ghostty_grid_ref_cell()

GHOSTTY_API GhosttyResult ghostty_grid_ref_cell ( const GhosttyGridRef * ref,
GhosttyCell * out_cell )

Get the cell from a grid reference.

Parameters
refPointer to the grid reference
[out]out_cellOn success, set to the cell at the ref's position (may be NULL)
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's node is NULL
Examples
c-vt-grid-ref-tracked/src/main.c, and c-vt-grid-traverse/src/main.c.

◆ ghostty_grid_ref_graphemes()

GHOSTTY_API GhosttyResult ghostty_grid_ref_graphemes ( const GhosttyGridRef * ref,
uint32_t * buf,
size_t buf_len,
size_t * out_len )

Get the grapheme cluster codepoints for the cell at the grid reference's position.

Writes the full grapheme cluster (the cell's primary codepoint followed by any combining codepoints) into the provided buffer. If the cell has no text, out_len is set to 0 and GHOSTTY_SUCCESS is returned.

If the buffer is too small (or NULL), the function returns GHOSTTY_OUT_OF_SPACE and writes the required number of codepoints to out_len. The caller can then retry with a sufficiently sized buffer.

Parameters
refPointer to the grid reference
bufOutput buffer of uint32_t codepoints (may be NULL)
buf_lenNumber of uint32_t elements in the buffer
[out]out_lenOn success, the number of codepoints written. On GHOSTTY_OUT_OF_SPACE, the required buffer size in codepoints.
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's node is NULL, GHOSTTY_OUT_OF_SPACE if the buffer is too small

◆ ghostty_grid_ref_hyperlink_uri()

GHOSTTY_API GhosttyResult ghostty_grid_ref_hyperlink_uri ( const GhosttyGridRef * ref,
uint8_t * buf,
size_t buf_len,
size_t * out_len )

Get the hyperlink URI for the cell at the grid reference's position.

Writes the URI bytes into the provided buffer. If the cell has no hyperlink, out_len is set to 0 and GHOSTTY_SUCCESS is returned.

If the buffer is too small (or NULL), the function returns GHOSTTY_OUT_OF_SPACE and writes the required number of bytes to out_len. The caller can then retry with a sufficiently sized buffer.

Parameters
refPointer to the grid reference
bufOutput buffer for the URI bytes (may be NULL)
buf_lenSize of the output buffer in bytes
[out]out_lenOn success, the number of bytes written. On GHOSTTY_OUT_OF_SPACE, the required buffer size in bytes.
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's node is NULL, GHOSTTY_OUT_OF_SPACE if the buffer is too small

◆ ghostty_grid_ref_row()

GHOSTTY_API GhosttyResult ghostty_grid_ref_row ( const GhosttyGridRef * ref,
GhosttyRow * out_row )

Get the row from a grid reference.

Parameters
refPointer to the grid reference
[out]out_rowOn success, set to the row at the ref's position (may be NULL)
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's node is NULL
Examples
c-vt-grid-traverse/src/main.c.

◆ ghostty_grid_ref_style()

GHOSTTY_API GhosttyResult ghostty_grid_ref_style ( const GhosttyGridRef * ref,
GhosttyStyle * out_style )

Get the style of the cell at the grid reference's position.

Parameters
refPointer to the grid reference
[out]out_styleOn success, set to the cell's style (may be NULL)
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's node is NULL
Examples
c-vt-grid-traverse/src/main.c.

◆ ghostty_tracked_grid_ref_free()

GHOSTTY_API void ghostty_tracked_grid_ref_free ( GhosttyTrackedGridRef ref)

Tracked grid references are owned grid references that move with the terminal. See Grid Reference for the full overview of tracked and untracked grid reference behavior. Free a tracked grid reference.

Passing NULL is allowed and has no effect. A tracked reference may be freed after the terminal that created it is freed.

Parameters
refTracked grid reference to free.
Examples
c-vt-grid-ref-tracked/src/main.c.

◆ ghostty_tracked_grid_ref_has_value()

GHOSTTY_API bool ghostty_tracked_grid_ref_has_value ( GhosttyTrackedGridRef ref)

Return whether a tracked grid reference currently has a meaningful value.

If the terminal that created the tracked reference has been freed, this returns false.

Parameters
refTracked grid reference.
Returns
true if the reference currently has a meaningful value.
Examples
c-vt-grid-ref-tracked/src/main.c.

◆ ghostty_tracked_grid_ref_point()

GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_point ( GhosttyTrackedGridRef ref,
GhosttyPointTag tag,
GhosttyPointCoordinate * out_point )

Convert a tracked grid reference to a point in the requested coordinate space.

This is the tracked equivalent of ghostty_terminal_point_from_grid_ref(). Unlike snapshotting, this does not expose an intermediate untracked GhosttyGridRef.

A tracked reference is resolved against the terminal screen/page-list that currently owns the reference. If the terminal has switched between primary and alternate screens since the reference was created or last set, this may be different from the terminal's currently active screen.

If the tracked reference no longer has a meaningful value, this returns GHOSTTY_NO_VALUE. GHOSTTY_NO_VALUE is also returned when the reference cannot be represented in the requested coordinate space, including after the terminal that created the tracked reference has been freed.

Parameters
refTracked grid reference.
tagCoordinate space to convert into.
[out]out_pointOn success, receives the coordinate. May be NULL.
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if ref is invalid, or GHOSTTY_NO_VALUE if there is no representable value.
Examples
c-vt-grid-ref-tracked/src/main.c.

◆ ghostty_tracked_grid_ref_set()

GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_set ( GhosttyTrackedGridRef ref,
GhosttyTerminal terminal,
GhosttyPoint point )

Move an existing tracked grid reference to a new terminal point.

On success, the tracked reference begins tracking the new point and any prior "no value" state is cleared. On GHOSTTY_OUT_OF_MEMORY, the original tracked reference is left unchanged.

The terminal must be the same terminal that created the tracked reference. The point is resolved against the terminal screen/page-list that is active at the time this function is called. If the terminal has switched between primary and alternate screens, this may move the tracked reference from one screen/page-list to the other.

Parameters
refTracked grid reference.
TerminalTerminal instance that owns the reference.
PointNew point to track.
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if ref, terminal, or point is invalid, or GHOSTTY_OUT_OF_MEMORY if allocation fails.
Examples
c-vt-grid-ref-tracked/src/main.c.

◆ ghostty_tracked_grid_ref_snapshot()

GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_snapshot ( GhosttyTrackedGridRef ref,
GhosttyGridRef * out_ref )

Snapshot a tracked grid reference into a regular GhosttyGridRef.

The returned GhosttyGridRef is an untracked snapshot and has the same lifetime rules as ghostty_terminal_grid_ref(): it is only valid until the next terminal update. Snapshot immediately before calling ghostty_grid_ref_cell(), ghostty_grid_ref_row(), ghostty_grid_ref_graphemes(), ghostty_grid_ref_hyperlink_uri(), or ghostty_grid_ref_style().

If the tracked reference no longer has a meaningful value, this returns GHOSTTY_NO_VALUE. This includes references whose owning terminal has been freed.

Parameters
refTracked grid reference.
[out]out_refOn success, receives an untracked snapshot. May be NULL.
Returns
GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if ref is invalid, or GHOSTTY_NO_VALUE if the tracked location was discarded.
Examples
c-vt-grid-ref-tracked/src/main.c.