From 15b8976d643de69df2168aa99320557e6b95bc02 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 17 Mar 2026 17:00:51 -0700 Subject: [PATCH] docs: extract inline code examples into standalone projects Extract inline @code blocks from vt headers (size_report.h, modes.h, sgr.h, paste.h, mouse.h, key.h) into standalone buildable examples under example/. Each header now uses Doxygen @snippet tags to include code from the example source files, keeping documentation in sync with code that is verified to compile and run. New example projects: c-vt-size-report and c-vt-modes. Existing examples (c-vt-sgr, c-vt-paste, c-vt-mouse-encode, c-vt-key-encode) gain snippet markers so their code can be referenced from the headers. Conceptual snippets in key.h, mouse.h, and key/encoder.h that show terminal-state usage patterns remain inline since they cannot be compiled standalone. --- example/c-vt-key-encode/src/main.c | 45 +++++------------ example/c-vt-modes/README.md | 18 +++++++ example/c-vt-modes/build.zig | 42 ++++++++++++++++ example/c-vt-modes/build.zig.zon | 24 +++++++++ example/c-vt-modes/src/main.c | 45 +++++++++++++++++ example/c-vt-mouse-encode/src/main.c | 68 ++++++++------------------ example/c-vt-paste/src/main.c | 21 +++++--- example/c-vt-sgr/src/main.c | 43 ++++++++++++++-- example/c-vt-size-report/README.md | 17 +++++++ example/c-vt-size-report/build.zig | 42 ++++++++++++++++ example/c-vt-size-report/build.zig.zon | 24 +++++++++ example/c-vt-size-report/src/main.c | 27 ++++++++++ include/ghostty/vt/key.h | 39 +-------------- include/ghostty/vt/modes.h | 47 +----------------- include/ghostty/vt/mouse.h | 51 +------------------ include/ghostty/vt/paste.h | 21 +------- include/ghostty/vt/sgr.h | 37 +------------- include/ghostty/vt/size_report.h | 28 +---------- 18 files changed, 331 insertions(+), 308 deletions(-) create mode 100644 example/c-vt-modes/README.md create mode 100644 example/c-vt-modes/build.zig create mode 100644 example/c-vt-modes/build.zig.zon create mode 100644 example/c-vt-modes/src/main.c create mode 100644 example/c-vt-size-report/README.md create mode 100644 example/c-vt-size-report/build.zig create mode 100644 example/c-vt-size-report/build.zig.zon create mode 100644 example/c-vt-size-report/src/main.c diff --git a/example/c-vt-key-encode/src/main.c b/example/c-vt-key-encode/src/main.c index 82444f99d..99b782022 100644 --- a/example/c-vt-key-encode/src/main.c +++ b/example/c-vt-key-encode/src/main.c @@ -4,56 +4,37 @@ #include #include +//! [key-encode] int main() { + // Create encoder GhosttyKeyEncoder encoder; GhosttyResult result = ghostty_key_encoder_new(NULL, &encoder); assert(result == GHOSTTY_SUCCESS); - // Set kitty flags with all features enabled - ghostty_key_encoder_setopt(encoder, GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS, &(uint8_t){GHOSTTY_KITTY_KEY_ALL}); + // Enable Kitty keyboard protocol with all features + ghostty_key_encoder_setopt(encoder, GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS, + &(uint8_t){GHOSTTY_KITTY_KEY_ALL}); - // Create key event + // Create and configure key event for Ctrl+C press GhosttyKeyEvent event; result = ghostty_key_event_new(NULL, &event); assert(result == GHOSTTY_SUCCESS); - ghostty_key_event_set_action(event, GHOSTTY_KEY_ACTION_RELEASE); - ghostty_key_event_set_key(event, GHOSTTY_KEY_CONTROL_LEFT); + ghostty_key_event_set_action(event, GHOSTTY_KEY_ACTION_PRESS); + ghostty_key_event_set_key(event, GHOSTTY_KEY_C); ghostty_key_event_set_mods(event, GHOSTTY_MODS_CTRL); - printf("Encoding event: left ctrl release with all Kitty flags enabled\n"); - // Optionally, encode with null buffer to get required size. You can - // skip this step and provide a sufficiently large buffer directly. - // If there isn't enoug hspace, the function will return an out of memory - // error. - size_t required = 0; - result = ghostty_key_encoder_encode(encoder, event, NULL, 0, &required); - assert(result == GHOSTTY_OUT_OF_MEMORY); - printf("Required buffer size: %zu bytes\n", required); - - // Encode the key event. We don't use our required size above because - // that was just an example; we know 128 bytes is enough. + // Encode the key event char buf[128]; size_t written = 0; result = ghostty_key_encoder_encode(encoder, event, buf, sizeof(buf), &written); assert(result == GHOSTTY_SUCCESS); - printf("Encoded %zu bytes\n", written); - // Print the encoded sequence (hex and string) - printf("Hex: "); - for (size_t i = 0; i < written; i++) printf("%02x ", (unsigned char)buf[i]); - printf("\n"); - - printf("String: "); - for (size_t i = 0; i < written; i++) { - if (buf[i] == 0x1b) { - printf("\\x1b"); - } else { - printf("%c", buf[i]); - } - } - printf("\n"); + // Use the encoded sequence (e.g., write to terminal) + fwrite(buf, 1, written, stdout); + // Cleanup ghostty_key_event_free(event); ghostty_key_encoder_free(encoder); return 0; } +//! [key-encode] diff --git a/example/c-vt-modes/README.md b/example/c-vt-modes/README.md new file mode 100644 index 000000000..bd43c1799 --- /dev/null +++ b/example/c-vt-modes/README.md @@ -0,0 +1,18 @@ +# Example: `ghostty-vt` Mode Utilities + +This contains a simple example of how to use the `ghostty-vt` mode +utilities to pack and unpack terminal mode identifiers and encode +DECRPM responses. + +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 +``` diff --git a/example/c-vt-modes/build.zig b/example/c-vt-modes/build.zig new file mode 100644 index 000000000..1a4b3f8d8 --- /dev/null +++ b/example/c-vt-modes/build.zig @@ -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_modes", + .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); +} diff --git a/example/c-vt-modes/build.zig.zon b/example/c-vt-modes/build.zig.zon new file mode 100644 index 000000000..bdfeefdca --- /dev/null +++ b/example/c-vt-modes/build.zig.zon @@ -0,0 +1,24 @@ +.{ + .name = .c_vt_modes, + .version = "0.0.0", + .fingerprint = 0x67ce079ebc70a02a, + .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", + }, +} diff --git a/example/c-vt-modes/src/main.c b/example/c-vt-modes/src/main.c new file mode 100644 index 000000000..e957c9777 --- /dev/null +++ b/example/c-vt-modes/src/main.c @@ -0,0 +1,45 @@ +#include +#include + +//! [modes-pack-unpack] +void modes_example() { + // Create a mode for DEC mode 25 (cursor visible) + GhosttyMode tag = ghostty_mode_new(25, false); + printf("value=%u ansi=%d packed=0x%04x\n", + ghostty_mode_value(tag), + ghostty_mode_ansi(tag), + tag); + + // Create a mode for ANSI mode 4 (insert mode) + GhosttyMode ansi_tag = ghostty_mode_new(4, true); + printf("value=%u ansi=%d packed=0x%04x\n", + ghostty_mode_value(ansi_tag), + ghostty_mode_ansi(ansi_tag), + ansi_tag); +} +//! [modes-pack-unpack] + +//! [modes-decrpm] +void decrpm_example() { + char buf[32]; + size_t written = 0; + + // Encode a report that DEC mode 25 (cursor visible) is set + GhosttyResult result = ghostty_mode_report_encode( + GHOSTTY_MODE_CURSOR_VISIBLE, + GHOSTTY_MODE_REPORT_SET, + buf, sizeof(buf), &written); + + if (result == GHOSTTY_SUCCESS) { + printf("Encoded %zu bytes: ", written); + fwrite(buf, 1, written, stdout); + printf("\n"); // prints: ESC[?25;1$y + } +} +//! [modes-decrpm] + +int main() { + modes_example(); + decrpm_example(); + return 0; +} diff --git a/example/c-vt-mouse-encode/src/main.c b/example/c-vt-mouse-encode/src/main.c index 55f867252..d75ed9c54 100644 --- a/example/c-vt-mouse-encode/src/main.c +++ b/example/c-vt-mouse-encode/src/main.c @@ -4,75 +4,49 @@ #include #include +//! [mouse-encode] int main() { + // Create encoder GhosttyMouseEncoder encoder; GhosttyResult result = ghostty_mouse_encoder_new(NULL, &encoder); assert(result == GHOSTTY_SUCCESS); - // Set tracking mode to normal (button press/release) + // Configure SGR format with normal tracking ghostty_mouse_encoder_setopt(encoder, GHOSTTY_MOUSE_ENCODER_OPT_EVENT, - &(GhosttyMouseTrackingMode){GHOSTTY_MOUSE_TRACKING_NORMAL}); - - // Set output format to SGR + &(GhosttyMouseTrackingMode){GHOSTTY_MOUSE_TRACKING_NORMAL}); ghostty_mouse_encoder_setopt(encoder, GHOSTTY_MOUSE_ENCODER_OPT_FORMAT, - &(GhosttyMouseFormat){GHOSTTY_MOUSE_FORMAT_SGR}); + &(GhosttyMouseFormat){GHOSTTY_MOUSE_FORMAT_SGR}); - // Set terminal geometry so the encoder can map pixel positions to cells + // Set terminal geometry for coordinate mapping ghostty_mouse_encoder_setopt(encoder, GHOSTTY_MOUSE_ENCODER_OPT_SIZE, - &(GhosttyMouseEncoderSize){ - .size = sizeof(GhosttyMouseEncoderSize), - .screen_width = 800, - .screen_height = 600, - .cell_width = 10, - .cell_height = 20, - .padding_top = 0, - .padding_bottom = 0, - .padding_right = 0, - .padding_left = 0, - }); + &(GhosttyMouseEncoderSize){ + .size = sizeof(GhosttyMouseEncoderSize), + .screen_width = 800, .screen_height = 600, + .cell_width = 10, .cell_height = 20, + }); - // Create mouse event: left button press at pixel position (50, 40) + // Create and configure a left button press event GhosttyMouseEvent event; result = ghostty_mouse_event_new(NULL, &event); assert(result == GHOSTTY_SUCCESS); ghostty_mouse_event_set_action(event, GHOSTTY_MOUSE_ACTION_PRESS); ghostty_mouse_event_set_button(event, GHOSTTY_MOUSE_BUTTON_LEFT); - ghostty_mouse_event_set_position(event, (GhosttyMousePosition){.x = 50.0f, .y = 40.0f}); - printf("Encoding event: left button press at (50, 40) in SGR format\n"); + ghostty_mouse_event_set_position(event, + (GhosttyMousePosition){.x = 50.0f, .y = 40.0f}); - // Optionally, encode with null buffer to get required size. You can - // skip this step and provide a sufficiently large buffer directly. - // If there isn't enough space, the function will return an out of memory - // error. - size_t required = 0; - result = ghostty_mouse_encoder_encode(encoder, event, NULL, 0, &required); - assert(result == GHOSTTY_OUT_OF_MEMORY); - printf("Required buffer size: %zu bytes\n", required); - - // Encode the mouse event. We don't use our required size above because - // that was just an example; we know 128 bytes is enough. + // Encode the mouse event char buf[128]; size_t written = 0; - result = ghostty_mouse_encoder_encode(encoder, event, buf, sizeof(buf), &written); + result = ghostty_mouse_encoder_encode(encoder, event, + buf, sizeof(buf), &written); assert(result == GHOSTTY_SUCCESS); - printf("Encoded %zu bytes\n", written); - // Print the encoded sequence (hex and string) - printf("Hex: "); - for (size_t i = 0; i < written; i++) printf("%02x ", (unsigned char)buf[i]); - printf("\n"); - - printf("String: "); - for (size_t i = 0; i < written; i++) { - if (buf[i] == 0x1b) { - printf("\\x1b"); - } else { - printf("%c", buf[i]); - } - } - printf("\n"); + // Use the encoded sequence (e.g., write to terminal) + fwrite(buf, 1, written, stdout); + // Cleanup ghostty_mouse_event_free(event); ghostty_mouse_encoder_free(encoder); return 0; } +//! [mouse-encode] diff --git a/example/c-vt-paste/src/main.c b/example/c-vt-paste/src/main.c index 153861ca9..bb9e8e2a5 100644 --- a/example/c-vt-paste/src/main.c +++ b/example/c-vt-paste/src/main.c @@ -2,18 +2,23 @@ #include #include -int main() { - // Test safe paste data - const char *safe_data = "hello world"; +//! [paste-safety] +void basic_example() { + const char* safe_data = "hello world"; + const char* unsafe_data = "rm -rf /\n"; + if (ghostty_paste_is_safe(safe_data, strlen(safe_data))) { - printf("'%s' is safe to paste\n", safe_data); + printf("Safe to paste\n"); } - // Test unsafe paste data with newline - const char *unsafe_newline = "rm -rf /\n"; - if (!ghostty_paste_is_safe(unsafe_newline, strlen(unsafe_newline))) { - printf("'%s' is UNSAFE - contains newline\n", unsafe_newline); + if (!ghostty_paste_is_safe(unsafe_data, strlen(unsafe_data))) { + printf("Unsafe! Contains newline\n"); } +} +//! [paste-safety] + +int main() { + basic_example(); // Test unsafe paste data with bracketed paste end sequence const char *unsafe_escape = "evil\x1b[201~code"; diff --git a/example/c-vt-sgr/src/main.c b/example/c-vt-sgr/src/main.c index 21a529726..e213c0c93 100644 --- a/example/c-vt-sgr/src/main.c +++ b/example/c-vt-sgr/src/main.c @@ -2,12 +2,43 @@ #include #include -int main() { +//! [sgr-basic] +void basic_example() { // Create parser GhosttySgrParser parser; GhosttyResult result = ghostty_sgr_new(NULL, &parser); assert(result == GHOSTTY_SUCCESS); + // Parse "bold, red foreground" sequence: ESC[1;31m + uint16_t params[] = {1, 31}; + result = ghostty_sgr_set_params(parser, params, NULL, 2); + assert(result == GHOSTTY_SUCCESS); + + // Iterate through attributes + GhosttySgrAttribute attr; + while (ghostty_sgr_next(parser, &attr)) { + switch (attr.tag) { + case GHOSTTY_SGR_ATTR_BOLD: + printf("Bold enabled\n"); + break; + case GHOSTTY_SGR_ATTR_FG_8: + printf("Foreground color: %d\n", attr.value.fg_8); + break; + default: + break; + } + } + + // Cleanup + ghostty_sgr_free(parser); +} +//! [sgr-basic] + +void advanced_example() { + GhosttySgrParser parser; + GhosttyResult result = ghostty_sgr_new(NULL, &parser); + assert(result == GHOSTTY_SUCCESS); + // Parse a complex SGR sequence from Kakoune // This corresponds to the escape sequence: // ESC[4:3;38;2;51;51;51;48;2;170;170;170;58;2;255;97;136m @@ -26,10 +57,9 @@ int main() { result = ghostty_sgr_set_params(parser, params, separators, sizeof(params) / sizeof(params[0])); assert(result == GHOSTTY_SUCCESS); - printf("Parsing Kakoune SGR sequence:\n"); + printf("\nParsing Kakoune SGR sequence:\n"); printf("ESC[4:3;38;2;51;51;51;48;2;170;170;170;58;2;255;97;136m\n\n"); - // Iterate through attributes GhosttySgrAttribute attr; int count = 0; while (ghostty_sgr_next(parser, &attr)) { @@ -124,8 +154,11 @@ int main() { } printf("\nTotal attributes parsed: %d\n", count); - - // Cleanup ghostty_sgr_free(parser); +} + +int main() { + basic_example(); + advanced_example(); return 0; } diff --git a/example/c-vt-size-report/README.md b/example/c-vt-size-report/README.md new file mode 100644 index 000000000..0e6ef2c85 --- /dev/null +++ b/example/c-vt-size-report/README.md @@ -0,0 +1,17 @@ +# Example: `ghostty-vt` Size Report Encoding + +This contains a simple example of how to use the `ghostty-vt` size report +encoding API to encode terminal size reports into escape sequences. + +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 +``` diff --git a/example/c-vt-size-report/build.zig b/example/c-vt-size-report/build.zig new file mode 100644 index 000000000..fbd0f5e23 --- /dev/null +++ b/example/c-vt-size-report/build.zig @@ -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_size_report", + .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); +} diff --git a/example/c-vt-size-report/build.zig.zon b/example/c-vt-size-report/build.zig.zon new file mode 100644 index 000000000..71d10d343 --- /dev/null +++ b/example/c-vt-size-report/build.zig.zon @@ -0,0 +1,24 @@ +.{ + .name = .c_vt_size_report, + .version = "0.0.0", + .fingerprint = 0x17e8cdb658fab232, + .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", + }, +} diff --git a/example/c-vt-size-report/src/main.c b/example/c-vt-size-report/src/main.c new file mode 100644 index 000000000..99e9c10dc --- /dev/null +++ b/example/c-vt-size-report/src/main.c @@ -0,0 +1,27 @@ +#include +#include + +//! [size-report-encode] +int main() { + GhosttySizeReportSize size = { + .rows = 24, + .columns = 80, + .cell_width = 9, + .cell_height = 18, + }; + + char buf[64]; + size_t written = 0; + + GhosttyResult result = ghostty_size_report_encode( + GHOSTTY_SIZE_REPORT_MODE_2048, size, buf, sizeof(buf), &written); + + if (result == GHOSTTY_SUCCESS) { + printf("Encoded %zu bytes: ", written); + fwrite(buf, 1, written, stdout); + printf("\n"); + } + + return 0; +} +//! [size-report-encode] diff --git a/include/ghostty/vt/key.h b/include/ghostty/vt/key.h index e82a7596c..305cffe87 100644 --- a/include/ghostty/vt/key.h +++ b/include/ghostty/vt/key.h @@ -32,44 +32,7 @@ * * ## Example * - * @code{.c} - * #include - * #include - * #include - * - * int main() { - * // Create encoder - * GhosttyKeyEncoder encoder; - * GhosttyResult result = ghostty_key_encoder_new(NULL, &encoder); - * assert(result == GHOSTTY_SUCCESS); - * - * // Enable Kitty keyboard protocol with all features - * ghostty_key_encoder_setopt(encoder, GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS, - * &(uint8_t){GHOSTTY_KITTY_KEY_ALL}); - * - * // Create and configure key event for Ctrl+C press - * GhosttyKeyEvent event; - * result = ghostty_key_event_new(NULL, &event); - * assert(result == GHOSTTY_SUCCESS); - * ghostty_key_event_set_action(event, GHOSTTY_KEY_ACTION_PRESS); - * ghostty_key_event_set_key(event, GHOSTTY_KEY_C); - * ghostty_key_event_set_mods(event, GHOSTTY_MODS_CTRL); - * - * // Encode the key event - * char buf[128]; - * size_t written = 0; - * result = ghostty_key_encoder_encode(encoder, event, buf, sizeof(buf), &written); - * assert(result == GHOSTTY_SUCCESS); - * - * // Use the encoded sequence (e.g., write to terminal) - * fwrite(buf, 1, written, stdout); - * - * // Cleanup - * ghostty_key_event_free(event); - * ghostty_key_encoder_free(encoder); - * return 0; - * } - * @endcode + * @snippet c-vt-key-encode/src/main.c key-encode * * ## Example: Encoding with Terminal State * diff --git a/include/ghostty/vt/modes.h b/include/ghostty/vt/modes.h index 4454b2a50..53e148dd7 100644 --- a/include/ghostty/vt/modes.h +++ b/include/ghostty/vt/modes.h @@ -20,57 +20,14 @@ * * ## Example * - * @code{.c} - * #include - * #include - * - * int main() { - * // Create a mode for DEC mode 25 (cursor visible) - * GhosttyMode tag = ghostty_mode_new(25, false); - * printf("value=%u ansi=%d packed=0x%04x\n", - * ghostty_mode_value(tag), - * ghostty_mode_ansi(tag), - * tag); - * - * // Create a mode for ANSI mode 4 (insert mode) - * GhosttyMode ansi_tag = ghostty_mode_new(4, true); - * printf("value=%u ansi=%d packed=0x%04x\n", - * ghostty_mode_value(ansi_tag), - * ghostty_mode_ansi(ansi_tag), - * ansi_tag); - * - * return 0; - * } - * @endcode + * @snippet c-vt-modes/src/main.c modes-pack-unpack * * ## DECRPM Report Encoding * * Use ghostty_mode_report_encode() to encode a DECRPM response into a * caller-provided buffer: * - * @code{.c} - * #include - * #include - * - * int main() { - * char buf[32]; - * size_t written = 0; - * - * // Encode a report that DEC mode 25 (cursor visible) is set - * GhosttyResult result = ghostty_mode_report_encode( - * GHOSTTY_MODE_CURSOR_VISIBLE, - * GHOSTTY_MODE_REPORT_SET, - * buf, sizeof(buf), &written); - * - * if (result == GHOSTTY_SUCCESS) { - * printf("Encoded %zu bytes: ", written); - * fwrite(buf, 1, written, stdout); - * printf("\n"); // prints: ESC[?25;1$y - * } - * - * return 0; - * } - * @endcode + * @snippet c-vt-modes/src/main.c modes-decrpm * * @{ */ diff --git a/include/ghostty/vt/mouse.h b/include/ghostty/vt/mouse.h index f5f37ce7b..c4489d3e4 100644 --- a/include/ghostty/vt/mouse.h +++ b/include/ghostty/vt/mouse.h @@ -29,56 +29,7 @@ * * ## Example * - * @code{.c} - * #include - * #include - * #include - * - * int main() { - * // Create encoder - * GhosttyMouseEncoder encoder; - * GhosttyResult result = ghostty_mouse_encoder_new(NULL, &encoder); - * assert(result == GHOSTTY_SUCCESS); - * - * // Configure SGR format with normal tracking - * ghostty_mouse_encoder_setopt(encoder, GHOSTTY_MOUSE_ENCODER_OPT_EVENT, - * &(GhosttyMouseTrackingMode){GHOSTTY_MOUSE_TRACKING_NORMAL}); - * ghostty_mouse_encoder_setopt(encoder, GHOSTTY_MOUSE_ENCODER_OPT_FORMAT, - * &(GhosttyMouseFormat){GHOSTTY_MOUSE_FORMAT_SGR}); - * - * // Set terminal geometry for coordinate mapping - * ghostty_mouse_encoder_setopt(encoder, GHOSTTY_MOUSE_ENCODER_OPT_SIZE, - * &(GhosttyMouseEncoderSize){ - * .size = sizeof(GhosttyMouseEncoderSize), - * .screen_width = 800, .screen_height = 600, - * .cell_width = 10, .cell_height = 20, - * }); - * - * // Create and configure a left button press event - * GhosttyMouseEvent event; - * result = ghostty_mouse_event_new(NULL, &event); - * assert(result == GHOSTTY_SUCCESS); - * ghostty_mouse_event_set_action(event, GHOSTTY_MOUSE_ACTION_PRESS); - * ghostty_mouse_event_set_button(event, GHOSTTY_MOUSE_BUTTON_LEFT); - * ghostty_mouse_event_set_position(event, - * (GhosttyMousePosition){.x = 50.0f, .y = 40.0f}); - * - * // Encode the mouse event - * char buf[128]; - * size_t written = 0; - * result = ghostty_mouse_encoder_encode(encoder, event, - * buf, sizeof(buf), &written); - * assert(result == GHOSTTY_SUCCESS); - * - * // Use the encoded sequence (e.g., write to terminal) - * fwrite(buf, 1, written, stdout); - * - * // Cleanup - * ghostty_mouse_event_free(event); - * ghostty_mouse_encoder_free(encoder); - * return 0; - * } - * @endcode + * @snippet c-vt-mouse-encode/src/main.c mouse-encode * * ## Example: Encoding with Terminal State * diff --git a/include/ghostty/vt/paste.h b/include/ghostty/vt/paste.h index d90f303d4..b7212c801 100644 --- a/include/ghostty/vt/paste.h +++ b/include/ghostty/vt/paste.h @@ -18,26 +18,7 @@ * * ## Example * - * @code{.c} - * #include - * #include - * #include - * - * int main() { - * const char* safe_data = "hello world"; - * const char* unsafe_data = "rm -rf /\n"; - * - * if (ghostty_paste_is_safe(safe_data, strlen(safe_data))) { - * printf("Safe to paste\n"); - * } - * - * if (!ghostty_paste_is_safe(unsafe_data, strlen(unsafe_data))) { - * printf("Unsafe! Contains newline\n"); - * } - * - * return 0; - * } - * @endcode + * @snippet c-vt-paste/src/main.c paste-safety * * @{ */ diff --git a/include/ghostty/vt/sgr.h b/include/ghostty/vt/sgr.h index c81c1c87a..3b190a6b8 100644 --- a/include/ghostty/vt/sgr.h +++ b/include/ghostty/vt/sgr.h @@ -31,42 +31,7 @@ * * ## Example * - * @code{.c} - * #include - * #include - * #include - * - * int main() { - * // Create parser - * GhosttySgrParser parser; - * GhosttyResult result = ghostty_sgr_new(NULL, &parser); - * assert(result == GHOSTTY_SUCCESS); - * - * // Parse "bold, red foreground" sequence: ESC[1;31m - * uint16_t params[] = {1, 31}; - * result = ghostty_sgr_set_params(parser, params, NULL, 2); - * assert(result == GHOSTTY_SUCCESS); - * - * // Iterate through attributes - * GhosttySgrAttribute attr; - * while (ghostty_sgr_next(parser, &attr)) { - * switch (attr.tag) { - * case GHOSTTY_SGR_ATTR_BOLD: - * printf("Bold enabled\n"); - * break; - * case GHOSTTY_SGR_ATTR_FG_8: - * printf("Foreground color: %d\n", attr.value.fg_8); - * break; - * default: - * break; - * } - * } - * - * // Cleanup - * ghostty_sgr_free(parser); - * return 0; - * } - * @endcode + * @snippet c-vt-sgr/src/main.c sgr-basic * * @{ */ diff --git a/include/ghostty/vt/size_report.h b/include/ghostty/vt/size_report.h index 4622b5bcf..b2eb08995 100644 --- a/include/ghostty/vt/size_report.h +++ b/include/ghostty/vt/size_report.h @@ -22,33 +22,7 @@ * * ## Example * - * @code{.c} - * #include - * #include - * - * int main() { - * GhosttySizeReportSize size = { - * .rows = 24, - * .columns = 80, - * .cell_width = 9, - * .cell_height = 18, - * }; - * - * char buf[64]; - * size_t written = 0; - * - * GhosttyResult result = ghostty_size_report_encode( - * GHOSTTY_SIZE_REPORT_MODE_2048, size, buf, sizeof(buf), &written); - * - * if (result == GHOSTTY_SUCCESS) { - * printf("Encoded %zu bytes: ", written); - * fwrite(buf, 1, written, stdout); - * printf("\n"); - * } - * - * return 0; - * } - * @endcode + * @snippet c-vt-size-report/src/main.c size-report-encode * * @{ */