libghostty-vt 0.0.0
Loading...
Searching...
No Matches
c-vt-stream/src/main.c

Feed VT sequences into a terminal, read the final screen back as plain text, and draw it with a render state. Start here for read-only tools like replay viewers and CI log viewers.

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>
int main(void) {
// Create a terminal
GhosttyTerminal terminal;
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, 80, 24);
assert(result == GHOSTTY_SUCCESS);
// Feed VT data into the terminal
const char *text = "Hello, World!\r\n";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
// ANSI color codes: ESC[1;32m = bold green, ESC[0m = reset
text = "\x1b[1;32mGreen Text\x1b[0m\r\n";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
// Cursor positioning: ESC[1;1H = move to row 1, column 1
text = "\x1b[1;1HTop-left corner\r\n";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
// Cursor movement: ESC[5B = move down 5 lines
text = "\x1b[5B";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
text = "Moved down!\r\n";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
// Erase line: ESC[2K = clear entire line
text = "\x1b[2K";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
text = "New content\r\n";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
// Multiple lines
text = "Line A\r\nLine B\r\nLine C\r\n";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
// Get the final terminal state as a plain string using the formatter
GhosttyFormatter formatter;
result = ghostty_formatter_terminal_new(NULL, &formatter, terminal);
assert(result == GHOSTTY_SUCCESS);
assert(result == GHOSTTY_SUCCESS);
bool trim = true;
assert(result == GHOSTTY_SUCCESS);
uint8_t *buf = NULL;
size_t len = 0;
result = ghostty_formatter_format_alloc(formatter, NULL, &buf, &len);
assert(result == GHOSTTY_SUCCESS);
fwrite(buf, 1, len, stdout);
printf("\n");
ghostty_free(NULL, buf, len);
// Create these once and reuse them for every frame.
GhosttyRenderState render_state = NULL;
result = ghostty_render_state_new(NULL, &render_state);
assert(result == GHOSTTY_SUCCESS);
result = ghostty_render_state_row_iterator_new(NULL, &row_iter);
assert(result == GHOSTTY_SUCCESS);
result = ghostty_render_state_row_cells_new(NULL, &cells);
assert(result == GHOSTTY_SUCCESS);
// Capture the frame. This is the only step that reads the terminal.
result = ghostty_render_state_update(render_state, terminal);
assert(result == GHOSTTY_SUCCESS);
// Visit only the rows that changed. In the first frame, that's all of them.
render_state, GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR, &row_iter);
assert(result == GHOSTTY_SUCCESS);
uint16_t y = 0;
assert(result == GHOSTTY_SUCCESS);
GhosttyStyle style;
assert(result == GHOSTTY_SUCCESS);
uint8_t bytes[64];
GhosttyBuffer grapheme = {.ptr = bytes, .cap = sizeof(bytes)};
assert(result == GHOSTTY_SUCCESS);
// A real renderer draws the cell here. We print it, with its bold
// style, which the plain text from the formatter didn't have.
if (grapheme.len == 0) {
putchar(' ');
continue;
}
bool bold = style.flags & GHOSTTY_STYLE_FLAG_BOLD;
if (bold) printf("\x1b[1m");
fwrite(bytes, 1, grapheme.len, stdout);
if (bold) printf("\x1b[0m");
}
putchar('\n');
}
// The frame is drawn, so the next one only reports new changes.
result = ghostty_render_state_clean(render_state);
assert(result == GHOSTTY_SUCCESS);
return 0;
}
GHOSTTY_API void ghostty_free(const GhosttyAllocator *allocator, uint8_t *ptr, size_t len)
GhosttyResult
Definition types.h:143
@ GHOSTTY_SUCCESS
Definition types.h:145
GHOSTTY_API GhosttyResult ghostty_formatter_format_alloc(GhosttyFormatter formatter, const GhosttyAllocator *allocator, uint8_t **out_ptr, size_t *out_len)
GHOSTTY_API GhosttyResult ghostty_formatter_terminal_new(const GhosttyAllocator *allocator, GhosttyFormatter *formatter, GhosttyTerminal terminal)
GHOSTTY_API GhosttyResult ghostty_formatter_set(GhosttyFormatter formatter, GhosttyFormatterOption option, const void *value)
GHOSTTY_API void ghostty_formatter_free(GhosttyFormatter formatter)
GhosttyFormatterFormat
Definition types.h:333
struct GhosttyFormatterImpl * GhosttyFormatter
Definition types.h:304
@ GHOSTTY_FORMATTER_OPT_TRIM
Definition formatter.h:173
@ GHOSTTY_FORMATTER_OPT_EMIT
Definition formatter.h:151
@ GHOSTTY_FORMATTER_FORMAT_PLAIN
Definition types.h:335
GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_new(const GhosttyAllocator *allocator, GhosttyRenderStateRowCells *out_cells)
GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_get(GhosttyRenderStateRowCells cells, GhosttyRenderStateRowCellsData data, void *out)
GHOSTTY_API GhosttyResult ghostty_render_state_clean(GhosttyRenderState state)
GHOSTTY_API bool ghostty_render_state_row_cells_next(GhosttyRenderStateRowCells cells)
GHOSTTY_API GhosttyResult ghostty_render_state_update(GhosttyRenderState state, GhosttyTerminal terminal)
struct GhosttyRenderStateRowIteratorImpl * GhosttyRenderStateRowIterator
Definition types.h:259
struct GhosttyRenderStateImpl * GhosttyRenderState
Definition types.h:252
GHOSTTY_API GhosttyResult ghostty_render_state_new(const GhosttyAllocator *allocator, GhosttyRenderState *state)
GHOSTTY_API GhosttyResult ghostty_render_state_row_iterator_new(const GhosttyAllocator *allocator, GhosttyRenderStateRowIterator *out_iterator)
GHOSTTY_API void ghostty_render_state_row_cells_free(GhosttyRenderStateRowCells cells)
GHOSTTY_API void ghostty_render_state_row_iterator_free(GhosttyRenderStateRowIterator iterator)
GHOSTTY_API void ghostty_render_state_free(GhosttyRenderState state)
GHOSTTY_API GhosttyResult ghostty_render_state_get(GhosttyRenderState state, GhosttyRenderStateData data, void *out)
GHOSTTY_API bool ghostty_render_state_row_iterator_next_dirty(GhosttyRenderStateRowIterator iterator, uint16_t *out_y)
GHOSTTY_API GhosttyResult ghostty_render_state_row_get(GhosttyRenderStateRowIterator iterator, GhosttyRenderStateRowData data, void *out)
struct GhosttyRenderStateRowCellsImpl * GhosttyRenderStateRowCells
Definition types.h:266
@ GHOSTTY_RENDER_STATE_ROW_DATA_CELLS
Definition render.h:452
@ GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR
Definition render.h:128
@ GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_STYLE
Definition render.h:1005
@ GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_UTF8
Definition render.h:1078
#define GHOSTTY_STYLE_FLAG_BOLD
Definition style.h:140
struct GhosttyTerminalImpl * GhosttyTerminal
Definition types.h:196
GHOSTTY_API void ghostty_terminal_free(GhosttyTerminal terminal)
GHOSTTY_API void ghostty_terminal_vt_write(GhosttyTerminal terminal, const uint8_t *data, size_t len)
GHOSTTY_API GhosttyResult ghostty_terminal_new(const GhosttyAllocator *allocator, GhosttyTerminal *terminal, uint16_t cols, uint16_t rows)
size_t len
Definition types.h:463
GhosttyStyleFlags flags
Definition style.h:238