Skip to content

Commit 2cdf0ab

Browse files
committed
build(vt): carry vendored changes as Vendor/ghostty.patch
The submodule is pinned to an upstream commit; the cursor-semantic additions to include/ghostty/vt/terminal.h and src/terminal/c/terminal.zig live in the submodule working tree as uncommitted changes that a clean checkout (or CI) never sees. Freeze them as a tracked patch and apply it after every submodule update, before the VT build. - Vendor/ghostty.patch: git diff of the two vendored edits (validated with git apply on a clean worktree of the pinned HEAD) - docs/libghostty-vt.md: document the apply step and the .a/header sync requirement (ReleaseFast drops the enum bounds check → UB if mismatched) - ci.yml + release.yml: git apply ../ghostty.patch before "Build Ghostty VT"
1 parent 2ab8af3 commit 2cdf0ab

4 files changed

Lines changed: 88 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ jobs:
5656
echo "${GITHUB_WORKSPACE}/.tools/zig-${ZIG_ARCH}-macos-0.15.2" >> "$GITHUB_PATH"
5757
".tools/zig-${ZIG_ARCH}-macos-0.15.2/zig" version
5858
59+
- name: Apply ProGhostty VT patch
60+
working-directory: Vendor/ghostty
61+
run: |
62+
set -euxo pipefail
63+
git apply ../ghostty.patch
64+
test -f include/ghostty/vt/terminal.h
65+
5966
- name: Build Ghostty VT
6067
working-directory: Vendor/ghostty
6168
run: |

.github/workflows/release.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ jobs:
4444
echo "${GITHUB_WORKSPACE}/.tools/zig-${ZIG_ARCH}-macos-0.15.2" >> "$GITHUB_PATH"
4545
".tools/zig-${ZIG_ARCH}-macos-0.15.2/zig" version
4646
47+
- name: Apply ProGhostty VT patch
48+
working-directory: Vendor/ghostty
49+
run: |
50+
set -euxo pipefail
51+
git apply ../ghostty.patch
52+
test -f include/ghostty/vt/terminal.h
53+
4754
- name: Build Ghostty VT
4855
working-directory: Vendor/ghostty
4956
run: |

Vendor/ghostty.patch

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
diff --git a/include/ghostty/vt/terminal.h b/include/ghostty/vt/terminal.h
2+
index 0e6d048e1..e9d468254 100644
3+
--- a/include/ghostty/vt/terminal.h
4+
+++ b/include/ghostty/vt/terminal.h
5+
@@ -868,6 +868,17 @@ typedef enum GHOSTTY_ENUM_TYPED {
6+
* Output type: GhosttyKittyGraphics *
7+
*/
8+
GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS = 30,
9+
+
10+
+ /**
11+
+ * The semantic content of the active screen's cursor. After OSC 133;C the
12+
+ * cursor semantic flips to .output even though previously-written input
13+
+ * cells stay .input, so this distinguishes "cursor at a live input prompt"
14+
+ * from "cursor on a stale / running command line" that per-cell markers
15+
+ * cannot. Ghostty's prompt-click movement keys off this same state.
16+
+ *
17+
+ * Output type: GhosttyCellSemanticContent *
18+
+ */
19+
+ GHOSTTY_TERMINAL_DATA_CURSOR_SEMANTIC_CONTENT = 31,
20+
GHOSTTY_TERMINAL_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
21+
} GhosttyTerminalData;
22+
23+
diff --git a/src/terminal/c/terminal.zig b/src/terminal/c/terminal.zig
24+
index d3293f3bc..231547e50 100644
25+
--- a/src/terminal/c/terminal.zig
26+
+++ b/src/terminal/c/terminal.zig
27+
@@ -575,6 +575,7 @@ pub const TerminalData = enum(c_int) {
28+
kitty_image_medium_temp_file = 28,
29+
kitty_image_medium_shared_mem = 29,
30+
kitty_graphics = 30,
31+
+ cursor_semantic_content = 31,
32+
33+
/// Output type expected for querying the data of the given kind.
34+
pub fn OutType(comptime self: TerminalData) type {
35+
@@ -603,6 +604,7 @@ pub const TerminalData = enum(c_int) {
36+
.kitty_image_medium_shared_mem,
37+
=> bool,
38+
.kitty_graphics => KittyGraphics,
39+
+ .cursor_semantic_content => cell_c.SemanticContent,
40+
};
41+
}
42+
};
43+
@@ -712,6 +714,7 @@ fn getTyped(
44+
if (comptime !build_options.kitty_graphics) return .no_value;
45+
out.* = &t.screens.active.kitty_images;
46+
},
47+
+ .cursor_semantic_content => out.* = @enumFromInt(@intFromEnum(t.screens.active.cursor.semantic_content)),
48+
}
49+
50+
return .success;

docs/libghostty-vt.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,30 @@ tar -xf .tools/zig-aarch64-macos-0.15.2.tar.xz -C .tools
2929

3030
`.tools/` is intentionally ignored by git.
3131

32+
## ProGhostty Patch
33+
34+
`Vendor/ghostty.patch` carries ProGhostty's small additions to the vendored
35+
Ghostty source. The submodule is pinned to an upstream commit, so a clean
36+
checkout never contains these changes — the patch must be applied after every
37+
`git submodule update` and before building the VT library. CI applies it in both
38+
`ci.yml` and `release.yml`.
39+
40+
```bash
41+
git submodule update --init --recursive
42+
cd Vendor/ghostty
43+
git apply ../ghostty.patch
44+
cd ../..
45+
```
46+
47+
The patch adds `GHOSTTY_TERMINAL_DATA_CURSOR_SEMANTIC_CONTENT` (and its
48+
`getTyped` case) — the cursor semantic state ProGhostty's click-to-position
49+
uses to distinguish a live input prompt from a stale/running command line.
50+
51+
> **Keep `.a` and header in sync.** The rebuilt `libghostty-vt.a` references the
52+
> new enum value. The C shim and the `.a` must come from the same build; a
53+
> rebuilt `.a` without the applied patch (or vice-versa) is undefined behavior,
54+
> since the enum value is read with no runtime bounds check under ReleaseFast.
55+
3256
## Build VT Library
3357

3458
Run from `Vendor/ghostty`:

0 commit comments

Comments
 (0)