example: add grid reference traversal example
Add a c-vt-grid-ref example that demonstrates the terminal and grid reference APIs end-to-end. The example creates a small 10x3 terminal, writes text with mixed styles via VT sequences, then iterates over every cell in the active area using ghostty_terminal_grid_ref. For each cell it extracts the codepoint, and for each row it inspects the wrap flag and the style bold attribute. The grid_ref.h defgroup gains a @snippet reference to the new example, and vt.h gets the corresponding @example entry and @ref listing.pull/11676/head
parent
549824842d
commit
93c597ce6b
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Example: `ghostty-vt` Grid Traversal
|
||||||
|
|
||||||
|
This contains a simple example of how to use the `ghostty-vt` terminal and
|
||||||
|
grid reference APIs to create a terminal, write content into it, and then
|
||||||
|
traverse the entire grid cell-by-cell using grid refs to inspect codepoints,
|
||||||
|
row state, and styles.
|
||||||
|
|
||||||
|
This uses a `build.zig` and `Zig` to build the C program so that we
|
||||||
|
can reuse a lot of our build logic and depend directly on our source
|
||||||
|
tree, but Ghostty emits a standard C library that can be used with any
|
||||||
|
C tooling.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Run the program:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
zig build run
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
|
||||||
|
const exe_mod = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
exe_mod.addCSourceFiles(.{
|
||||||
|
.root = b.path("src"),
|
||||||
|
.files = &.{"main.c"},
|
||||||
|
});
|
||||||
|
|
||||||
|
// You'll want to use a lazy dependency here so that ghostty is only
|
||||||
|
// downloaded if you actually need it.
|
||||||
|
if (b.lazyDependency("ghostty", .{
|
||||||
|
// Setting simd to false will force a pure static build that
|
||||||
|
// doesn't even require libc, but it has a significant performance
|
||||||
|
// penalty. If your embedding app requires libc anyway, you should
|
||||||
|
// always keep simd enabled.
|
||||||
|
// .simd = false,
|
||||||
|
})) |dep| {
|
||||||
|
exe_mod.linkLibrary(dep.artifact("ghostty-vt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exe
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "c_vt_grid_traverse",
|
||||||
|
.root_module = exe_mod,
|
||||||
|
});
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
// Run
|
||||||
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| run_cmd.addArgs(args);
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
.{
|
||||||
|
.name = .c_vt_grid_traverse,
|
||||||
|
.version = "0.0.0",
|
||||||
|
.fingerprint = 0xf694dd12db9be040,
|
||||||
|
.minimum_zig_version = "0.15.1",
|
||||||
|
.dependencies = .{
|
||||||
|
// Ghostty dependency. In reality, you'd probably use a URL-based
|
||||||
|
// dependency like the one showed (and commented out) below this one.
|
||||||
|
// We use a path dependency here for simplicity and to ensure our
|
||||||
|
// examples always test against the source they're bundled with.
|
||||||
|
.ghostty = .{ .path = "../../" },
|
||||||
|
|
||||||
|
// Example of what a URL-based dependency looks like:
|
||||||
|
// .ghostty = .{
|
||||||
|
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
|
||||||
|
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
.paths = .{
|
||||||
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"src",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ghostty/vt.h>
|
||||||
|
|
||||||
|
//! [grid-ref-traverse]
|
||||||
|
int main() {
|
||||||
|
// Create a small terminal
|
||||||
|
GhosttyTerminal terminal;
|
||||||
|
GhosttyTerminalOptions opts = {
|
||||||
|
.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)
|
||||||
|
ghostty_terminal_vt_write(
|
||||||
|
terminal, (const uint8_t *)text, strlen(text));
|
||||||
|
|
||||||
|
// Get terminal dimensions
|
||||||
|
uint16_t cols, rows;
|
||||||
|
ghostty_terminal_get(terminal, GHOSTTY_TERMINAL_DATA_COLS, &cols);
|
||||||
|
ghostty_terminal_get(terminal, GHOSTTY_TERMINAL_DATA_ROWS, &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
|
||||||
|
GhosttyGridRef ref = GHOSTTY_INIT_SIZED(GhosttyGridRef);
|
||||||
|
GhosttyPoint pt = {
|
||||||
|
.tag = GHOSTTY_POINT_TAG_ACTIVE,
|
||||||
|
.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
|
||||||
|
GhosttyCell cell;
|
||||||
|
result = ghostty_grid_ref_cell(&ref, &cell);
|
||||||
|
assert(result == GHOSTTY_SUCCESS);
|
||||||
|
|
||||||
|
// Check if the cell has text
|
||||||
|
bool has_text = false;
|
||||||
|
ghostty_cell_get(cell, GHOSTTY_CELL_DATA_HAS_TEXT, &has_text);
|
||||||
|
|
||||||
|
if (has_text) {
|
||||||
|
uint32_t codepoint = 0;
|
||||||
|
ghostty_cell_get(cell, GHOSTTY_CELL_DATA_CODEPOINT, &codepoint);
|
||||||
|
printf("%c", (char)codepoint);
|
||||||
|
} else {
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also inspect the row for wrap state
|
||||||
|
GhosttyGridRef ref = GHOSTTY_INIT_SIZED(GhosttyGridRef);
|
||||||
|
GhosttyPoint pt = {
|
||||||
|
.tag = GHOSTTY_POINT_TAG_ACTIVE,
|
||||||
|
.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;
|
||||||
|
ghostty_row_get(grid_row, GHOSTTY_ROW_DATA_WRAP, &wrap);
|
||||||
|
printf(" (wrap=%s", wrap ? "true" : "false");
|
||||||
|
|
||||||
|
// Check the style of the first cell with text
|
||||||
|
GhosttyStyle style = GHOSTTY_INIT_SIZED(GhosttyStyle);
|
||||||
|
ghostty_grid_ref_style(&ref, &style);
|
||||||
|
printf(", bold=%s)\n", style.bold ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
ghostty_terminal_free(terminal);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//! [grid-ref-traverse]
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
* - @ref c-vt-paste/src/main.c - Paste safety check example
|
* - @ref c-vt-paste/src/main.c - Paste safety check example
|
||||||
* - @ref c-vt-sgr/src/main.c - SGR parser example
|
* - @ref c-vt-sgr/src/main.c - SGR parser example
|
||||||
* - @ref c-vt-formatter/src/main.c - Terminal formatter example
|
* - @ref c-vt-formatter/src/main.c - Terminal formatter example
|
||||||
|
* - @ref c-vt-grid-traverse/src/main.c - Grid traversal example using grid refs
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -84,6 +85,11 @@
|
||||||
* contents as plain text.
|
* contents as plain text.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** @example c-vt-grid-traverse/src/main.c
|
||||||
|
* This example demonstrates how to traverse the entire terminal grid using
|
||||||
|
* grid refs to inspect cell codepoints, row wrap state, and cell styles.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef GHOSTTY_VT_H
|
#ifndef GHOSTTY_VT_H
|
||||||
#define GHOSTTY_VT_H
|
#define GHOSTTY_VT_H
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ extern "C" {
|
||||||
* built to sustain the framerates needed for rendering large screens.
|
* built to sustain the framerates needed for rendering large screens.
|
||||||
* Use the render state API for that.
|
* Use the render state API for that.
|
||||||
*
|
*
|
||||||
|
* ## Example
|
||||||
|
*
|
||||||
|
* @snippet c-vt-grid-traverse/src/main.c grid-ref-traverse
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue