Compare commits
No commits in common. "main" and "v1.3.1" have entirely different histories.
|
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env nu
|
||||
|
||||
# A command to generate an agent prompt to diagnose and formulate
|
||||
# a plan for resolving a GitHub issue.
|
||||
#
|
||||
# IMPORTANT: This command is prompted to NOT write any code and to ONLY
|
||||
# produce a plan. You should still be vigilant when running this but that
|
||||
# is the expected behavior.
|
||||
#
|
||||
# The `<issue>` parameter can be either an issue number or a full GitHub
|
||||
# issue URL.
|
||||
def main [
|
||||
issue: any, # Ghostty issue number or URL
|
||||
--repo: string = "ghostty-org/ghostty" # GitHub repository in the format "owner/repo"
|
||||
] {
|
||||
# TODO: This whole script doesn't handle errors very well. I actually
|
||||
# don't know Nu well enough to know the proper way to handle it all.
|
||||
|
||||
let issueData = gh issue view $issue --json author,title,number,body,comments | from json
|
||||
let comments = $issueData.comments | each { |comment|
|
||||
$"
|
||||
### Comment by ($comment.author.login)
|
||||
($comment.body)
|
||||
" | str trim
|
||||
} | str join "\n\n"
|
||||
|
||||
$"
|
||||
Deep-dive on this GitHub issue. Find the problem and generate a plan.
|
||||
Do not write code. Explain the problem clearly and propose a comprehensive plan
|
||||
to solve it.
|
||||
|
||||
# ($issueData.title) \(($issueData.number)\)
|
||||
|
||||
## Description
|
||||
($issueData.body)
|
||||
|
||||
## Comments
|
||||
($comments)
|
||||
|
||||
## Your Tasks
|
||||
|
||||
You are an experienced software developer tasked with diagnosing issues.
|
||||
|
||||
1. Review the issue context and details.
|
||||
2. Examine the relevant parts of the codebase. Analyze the code thoroughly
|
||||
until you have a solid understanding of how it works.
|
||||
3. Explain the issue in detail, including the problem and its root cause.
|
||||
4. Create a comprehensive plan to solve the issue. The plan should include:
|
||||
- Required code changes
|
||||
- Potential impacts on other parts of the system
|
||||
- Necessary tests to be written or updated
|
||||
- Documentation updates
|
||||
- Performance considerations
|
||||
- Security implications
|
||||
- Backwards compatibility \(if applicable\)
|
||||
- Include the reference link to the source issue and any related discussions
|
||||
4. Think deeply about all aspects of the task. Consider edge cases, potential
|
||||
challenges, and best practices for addressing the issue. Review the plan
|
||||
with the oracle and adjust it based on its feedback.
|
||||
|
||||
**ONLY CREATE A PLAN. DO NOT WRITE ANY CODE.** Your task is to create
|
||||
a thorough, comprehensive strategy for understanding and resolving the issue.
|
||||
" | str trim
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
---
|
||||
name: writing-commit-messages
|
||||
description: >-
|
||||
Writes Git commit messages. Activates when the user asks to write
|
||||
a commit message, draft a commit message, or similar.
|
||||
---
|
||||
|
||||
# Writing Commit Messages
|
||||
|
||||
Write commit messages that follow commit style guidelines for the project.
|
||||
|
||||
## Format
|
||||
|
||||
```
|
||||
<subsystem>: <summary>
|
||||
|
||||
<reference issues/PRs/etc.>
|
||||
|
||||
<long form description>
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
### Subject line
|
||||
|
||||
- **Subsystem prefix**: Use a short, lowercase identifier for the
|
||||
area of code changed (e.g., `terminal`, `vt`, `lib`, `config`,
|
||||
`font`). Determine this from the file paths in the diff. If
|
||||
changes span the macOS app, use `macos`. For GTK, use `gtk`. For
|
||||
build system, use `build`. Use nested subsystems with `/` when
|
||||
helpful and exclusive (e.g., `terminal/osc`).
|
||||
- **Summary**: Lowercase start (not capitalized), imperative mood,
|
||||
no trailing period. Keep it concise—ideally under 60 characters
|
||||
total for the whole subject line.
|
||||
|
||||
### References
|
||||
|
||||
- If the change relates to a GitHub issue, PR, or discussion, list
|
||||
the relevant numbers on their own lines after the subject, separated
|
||||
by a blank line. E.g. `#1234`
|
||||
- If there are no references, omit this section entirely (no blank
|
||||
line).
|
||||
|
||||
### Long form description
|
||||
|
||||
- Describe **what changed**, **what the previous behavior was**,
|
||||
and **how the new behavior works** at a high level.
|
||||
- Use plain prose, not bullet points. Wrap lines at ~72 characters.
|
||||
- Focus on the _why_ and _how_ rather than restating the diff.
|
||||
- Keep the tone direct and technical without no filler phrases.
|
||||
- Don't exceed a handful of paragraphs; less is more.
|
||||
|
||||
## Workflow
|
||||
|
||||
- If `.jj` is present, use `jj` instead of `git` for all commands.
|
||||
- Run a diff to see what changes are present since the last commit.
|
||||
- Identify the subsystem from the changed file paths.
|
||||
- Identify any referenced issues/PRs from the diff context or
|
||||
branch name.
|
||||
- Draft the commit message following the format above.
|
||||
- Apply the commit
|
||||
- Don't push the commit; leave that to the user.
|
||||
|
|
@ -1,47 +1,3 @@
|
|||
#--------------------------------------------------------------------
|
||||
# Line endings
|
||||
#--------------------------------------------------------------------
|
||||
# Source code - always LF
|
||||
*.zig text eol=lf
|
||||
*.c text eol=lf
|
||||
*.h text eol=lf
|
||||
*.cpp text eol=lf
|
||||
*.m text eol=lf
|
||||
*.swift text eol=lf
|
||||
*.py text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.glsl text eol=lf
|
||||
*.blp text eol=lf
|
||||
|
||||
# Config/build files - always LF
|
||||
*.zon text eol=lf
|
||||
*.nix text eol=lf
|
||||
*.md text eol=lf
|
||||
*.json text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.yaml text eol=lf
|
||||
*.toml text eol=lf
|
||||
CMakeLists.txt text eol=lf
|
||||
*.cmake text eol=lf
|
||||
Makefile text eol=lf
|
||||
|
||||
# Text data files - always LF (embedded in Zig, parsed with \n split)
|
||||
*.txt text eol=lf
|
||||
|
||||
# Windows resource files - preserve as-is (native Windows tooling)
|
||||
*.rc -text
|
||||
*.manifest -text
|
||||
|
||||
# Binary files
|
||||
*.png binary
|
||||
*.ico binary
|
||||
*.icns binary
|
||||
*.ttf binary
|
||||
*.otf binary
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Linguist
|
||||
#--------------------------------------------------------------------
|
||||
build.zig.zon.nix linguist-generated=true
|
||||
build.zig.zon.txt linguist-generated=true
|
||||
build.zig.zon.json linguist-generated=true
|
||||
|
|
|
|||
|
|
@ -19,256 +19,152 @@
|
|||
# discussion by the author. Maintainers can denounce users by commenting
|
||||
# "!denounce" or "!denounce [username]" on a discussion.
|
||||
00-kat
|
||||
007hacky007
|
||||
00jciv00
|
||||
04cb
|
||||
0xdvc
|
||||
-4rh1t3ct0r7
|
||||
52dyd
|
||||
aalhendi
|
||||
aaron-ang
|
||||
abdurrahmanski
|
||||
abudvytis
|
||||
adrum
|
||||
agoodkind
|
||||
aindriu80
|
||||
ajiblock
|
||||
akimiojr
|
||||
alaasdk
|
||||
alanmoyano
|
||||
alaviss
|
||||
alexfeijoo44
|
||||
alexjuca
|
||||
alosarjos
|
||||
amadeus
|
||||
andrejdaskalov
|
||||
anhthang
|
||||
anmitalidev
|
||||
anthonyzhoon
|
||||
athaapa
|
||||
atomk
|
||||
b0uks
|
||||
b1nar10
|
||||
balazs-szucs
|
||||
barutsrb
|
||||
bch
|
||||
bennettp123
|
||||
benodiwal
|
||||
bernsno
|
||||
beryesa
|
||||
bitigchi
|
||||
bkircher
|
||||
bleikurr
|
||||
bo2themax
|
||||
brentschroeter
|
||||
brianc442
|
||||
c0x0o
|
||||
cespare
|
||||
charliie-dev
|
||||
chernetskyi
|
||||
chronologos
|
||||
cmwetherell
|
||||
crayxt
|
||||
craziestowl
|
||||
curtismoncoq
|
||||
-cznorth Automated advertising + likely AI communication
|
||||
d-dudas
|
||||
-daedaevibin
|
||||
daiimus
|
||||
damyanbogoev
|
||||
danneu
|
||||
danulqua
|
||||
dariogriffo
|
||||
davidsanchez222
|
||||
deblasis
|
||||
dervedro
|
||||
devsunb
|
||||
diaaeddin
|
||||
dkinzler
|
||||
dmehala
|
||||
dobbylee
|
||||
doprz
|
||||
douglance
|
||||
douglas
|
||||
douglas-macgregor
|
||||
drepper
|
||||
dzhlobo
|
||||
ekaterinepapava
|
||||
elias8
|
||||
-enkr1
|
||||
enzowilliam
|
||||
ephemera
|
||||
-eric-assetpass Try talking, not botting
|
||||
eriksremess
|
||||
erral
|
||||
-f1813483-netizen
|
||||
faukah
|
||||
filip7
|
||||
flou
|
||||
fornwall
|
||||
francescarpi
|
||||
fru1tworld
|
||||
gagbo
|
||||
ghokun
|
||||
gmile
|
||||
gordonbondon
|
||||
gpanders
|
||||
guilhermetk
|
||||
h3nock
|
||||
hakonhagland
|
||||
halosatrio
|
||||
heaths
|
||||
heddxh heddxh
|
||||
-highimpact-dev Disrespectful AI user
|
||||
hlcfan
|
||||
hqnna
|
||||
hulet
|
||||
i999rri
|
||||
icodesign
|
||||
illiakrauchanka
|
||||
j0hnm4r5
|
||||
jacobsandlund
|
||||
jake-stewart
|
||||
jamylak
|
||||
jarred-sumner
|
||||
jcollie
|
||||
jesusvazquez
|
||||
jguthmiller
|
||||
jmcgover
|
||||
jmr
|
||||
johnslavik
|
||||
jordandm
|
||||
josephmart
|
||||
jparise
|
||||
juniqlim
|
||||
justonia
|
||||
karesansui-u
|
||||
kataokatsuki
|
||||
kawarimidoll
|
||||
kayleung
|
||||
kenvandine
|
||||
khipp
|
||||
kierancanter
|
||||
kirwiisp
|
||||
kjvdven
|
||||
kloneets
|
||||
knu
|
||||
-kody-w
|
||||
koranir
|
||||
kristina8888
|
||||
kristofersoler
|
||||
kylesower
|
||||
laxystem
|
||||
lebdron
|
||||
lepips
|
||||
liby
|
||||
linustalacko
|
||||
lonsagisawa
|
||||
louisunlimited
|
||||
luisnquin
|
||||
lynicis
|
||||
mac0ne
|
||||
mahnokropotkinvich
|
||||
marijagjorgjieva
|
||||
markdorison
|
||||
markhuot
|
||||
marler8997
|
||||
marrocco-simone
|
||||
masterflitzer
|
||||
matkotiric
|
||||
mattn
|
||||
micaeljarniac
|
||||
michielvk
|
||||
miguelelgallo
|
||||
mihi314
|
||||
mikailmm
|
||||
minorcell
|
||||
misairuzame
|
||||
mischief
|
||||
mitchellh
|
||||
miupa
|
||||
mjbommar
|
||||
mohshami
|
||||
molechowski
|
||||
moonmao42
|
||||
-morgengeluk Appears to be using AI inappropriately even after it was requested they abide by the AI policy (there is clear evidence of the person-in-the-loop not attempting to clean up AI generated text, and their AI disclosure itself reads like AI-generated text and shows no signs of remorse or intent to improve).
|
||||
mpatankar6
|
||||
mrconnorkenway
|
||||
mrmage
|
||||
mtak
|
||||
natesmyth
|
||||
neo773
|
||||
neurosnap
|
||||
nicholas-ochoa
|
||||
nicosuave
|
||||
nikicat
|
||||
nmggithub
|
||||
noib3
|
||||
nolinmcfarland
|
||||
nouritsu
|
||||
nwehg
|
||||
ocean6954
|
||||
oshdubh
|
||||
otomn
|
||||
paaloeye
|
||||
pan93412
|
||||
pangoraw
|
||||
pauley-unsaturated
|
||||
peilingjiang
|
||||
peterdavehello
|
||||
philocalyst
|
||||
phush0
|
||||
piedrahitac
|
||||
pluiedev
|
||||
pouwerkerk
|
||||
poweruser64
|
||||
prakhar54-byte
|
||||
priyans-hu
|
||||
puzza007
|
||||
qwerasd205
|
||||
raphamorim
|
||||
reo101
|
||||
rewdy
|
||||
rgehan
|
||||
rhodes-b
|
||||
rightaditya
|
||||
rjwittams
|
||||
rmengelbrecht
|
||||
rmunn
|
||||
rockorager
|
||||
rpfaeffle
|
||||
samasaur1
|
||||
sandydoo
|
||||
secrus
|
||||
seruman
|
||||
seyoungjeong
|
||||
silveirapf
|
||||
slsrepo
|
||||
sunshine-syz
|
||||
tbrundige
|
||||
tdgroot
|
||||
tdslot
|
||||
thirstycrow
|
||||
thoutbeckers
|
||||
ticclick
|
||||
tnagatomi
|
||||
trag1c
|
||||
tristan957
|
||||
turbolent
|
||||
tweedbeetle
|
||||
uhojin
|
||||
unphased
|
||||
uzaaft
|
||||
vancluever
|
||||
vaughanandrews
|
||||
viruslobster
|
||||
vlsi
|
||||
voidnv
|
||||
wyounas
|
||||
yabbal
|
||||
yamshta
|
||||
ydah
|
||||
-zaviro
|
||||
zenyr
|
||||
zeshi09
|
||||
zubb
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
Hi @{author}, thanks for your interest!
|
||||
|
||||
Non-maintainers are not allowed to create issues in this repository — we ask that you create a discussion first. For more details on the why, see #3558 and our [CONTRIBUTING.md](https://github.com/ghostty-org/ghostty/blob/main/CONTRIBUTING.md).
|
||||
|
||||
This issue will be closed automatically.
|
||||
|
|
@ -41,7 +41,7 @@ jobs:
|
|||
mkdir dist
|
||||
tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
|
||||
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@401fe28a8384095fc1531b9d320b292f0ee45adb # v6.7
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@92ae9851ad316786193b1fd3f40c4b51eb5cb101 # v6.6
|
||||
with:
|
||||
bundle: com.mitchellh.ghostty
|
||||
manifest-path: dist/flatpak/com.mitchellh.ghostty.yml
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ on:
|
|||
|
||||
jobs:
|
||||
update-milestone:
|
||||
# Ignore bot-authored pull requests (dependabot, app bots, etc)
|
||||
# and CI-only PRs.
|
||||
if: github.event_name == 'issues' || (github.event.pull_request.user.type != 'Bot' && !startsWith(github.event.pull_request.title, 'ci:'))
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
name: Milestone Update
|
||||
steps:
|
||||
|
|
|
|||
|
|
@ -39,18 +39,18 @@ jobs:
|
|||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- name: Setup Nix
|
||||
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
|
||||
uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934 # v31.10.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ jobs:
|
|||
fi
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# Important so that build number generation works
|
||||
fetch-depth: 0
|
||||
|
|
@ -80,20 +80,20 @@ jobs:
|
|||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
|
||||
- uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934 # v31.10.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
|
@ -113,7 +113,7 @@ jobs:
|
|||
nix develop -c minisign -S -m "ghostty-source.tar.gz" -s minisign.key < minisign.password
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: source-tarball
|
||||
path: |-
|
||||
|
|
@ -134,10 +134,10 @@ jobs:
|
|||
ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
cache: |
|
||||
xcode
|
||||
|
|
@ -147,13 +147,13 @@ jobs:
|
|||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
determinate: true
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: XCode Select
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.3.app
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.2.app
|
||||
|
||||
- name: Xcode Version
|
||||
run: xcodebuild -version
|
||||
|
|
@ -282,7 +282,7 @@ jobs:
|
|||
zip -9 -r --symlinks ../../../ghostty-macos-universal-dsym.zip Ghostty.app.dSYM/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: macos
|
||||
path: |-
|
||||
|
|
@ -319,7 +319,7 @@ jobs:
|
|||
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Download macOS Artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
|
|
@ -353,7 +353,7 @@ jobs:
|
|||
mv appcast_new.xml appcast.xml
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: sparkle
|
||||
path: |-
|
||||
|
|
|
|||
|
|
@ -33,19 +33,19 @@ jobs:
|
|||
commit: ${{ steps.extract_build_info.outputs.commit }}
|
||||
commit_long: ${{ steps.extract_build_info.outputs.commit_long }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# Important so that build number generation works
|
||||
fetch-depth: 0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
|
||||
- uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934 # v31.10.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
|
@ -75,7 +75,7 @@ jobs:
|
|||
needs: [setup, build-macos]
|
||||
if: needs.setup.outputs.should_skip != 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Tip Tag
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
|
|
@ -90,7 +90,7 @@ jobs:
|
|||
env:
|
||||
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Install sentry-cli
|
||||
run: |
|
||||
|
|
@ -113,7 +113,7 @@ jobs:
|
|||
env:
|
||||
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Install sentry-cli
|
||||
run: |
|
||||
|
|
@ -136,7 +136,7 @@ jobs:
|
|||
env:
|
||||
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Install sentry-cli
|
||||
run: |
|
||||
|
|
@ -163,22 +163,22 @@ jobs:
|
|||
github.ref_name == 'main'
|
||||
)
|
||||
)
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
runs-on: namespace-profile-ghostty-md
|
||||
env:
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
|
||||
- uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934 # v31.10.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
|
@ -195,7 +195,7 @@ jobs:
|
|||
nix develop -c minisign -S -m ghostty-source.tar.gz -s minisign.key < minisign.password
|
||||
|
||||
- name: Update Release
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||
with:
|
||||
name: 'Ghostty Tip ("Nightly")'
|
||||
prerelease: true
|
||||
|
|
@ -206,165 +206,6 @@ jobs:
|
|||
ghostty-source.tar.gz.minisig
|
||||
token: ${{ secrets.GH_RELEASE_TOKEN }}
|
||||
|
||||
source-tarball-lib-vt:
|
||||
needs: [setup]
|
||||
if: |
|
||||
needs.setup.outputs.should_skip != 'true' &&
|
||||
(
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(
|
||||
github.repository_owner == 'ghostty-org' &&
|
||||
github.ref_name == 'main'
|
||||
)
|
||||
)
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
env:
|
||||
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
- name: Create Tarball
|
||||
run: |
|
||||
rm -rf zig-out/dist
|
||||
nix develop -c zig build dist -Demit-lib-vt=true
|
||||
cp zig-out/dist/*.tar.gz libghostty-vt-source.tar.gz
|
||||
|
||||
- name: Sign Tarball
|
||||
run: |
|
||||
echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
|
||||
echo -n "${{ secrets.MINISIGN_PASSWORD }}" > minisign.password
|
||||
nix develop -c minisign -S -m libghostty-vt-source.tar.gz -s minisign.key < minisign.password
|
||||
|
||||
- name: Update Release
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
with:
|
||||
name: 'Ghostty Tip ("Nightly")'
|
||||
prerelease: true
|
||||
tag_name: tip
|
||||
target_commitish: ${{ github.sha }}
|
||||
files: |
|
||||
libghostty-vt-source.tar.gz
|
||||
libghostty-vt-source.tar.gz.minisig
|
||||
token: ${{ secrets.GH_RELEASE_TOKEN }}
|
||||
|
||||
- name: Prep R2 Storage
|
||||
run: |
|
||||
mkdir -p blob/${GHOSTTY_COMMIT_LONG}
|
||||
cp libghostty-vt-source.tar.gz blob/${GHOSTTY_COMMIT_LONG}/libghostty-vt-source.tar.gz
|
||||
- name: Upload to R2
|
||||
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
|
||||
with:
|
||||
r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
|
||||
r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
|
||||
r2-secret-access-key: ${{ secrets.CF_R2_TIP_SECRET_KEY }}
|
||||
r2-bucket: ghostty-tip
|
||||
source-dir: blob
|
||||
destination-dir: ./
|
||||
|
||||
- name: Echo Release URLs
|
||||
run: |
|
||||
echo "Release URLs:"
|
||||
echo " Source Tarball: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/libghostty-vt-source.tar.gz"
|
||||
|
||||
build-lib-vt-xcframework:
|
||||
needs: [setup]
|
||||
if: |
|
||||
needs.setup.outputs.should_skip != 'true' &&
|
||||
(
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(
|
||||
github.repository_owner == 'ghostty-org' &&
|
||||
github.ref_name == 'main'
|
||||
)
|
||||
)
|
||||
runs-on: namespace-profile-ghostty-macos-tahoe
|
||||
env:
|
||||
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
|
||||
ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
with:
|
||||
cache: |
|
||||
xcode
|
||||
path: |
|
||||
/Users/runner/zig
|
||||
|
||||
# TODO(tahoe): https://github.com/NixOS/nix/issues/13342
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
determinate: true
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: Xcode Select
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.3.app
|
||||
|
||||
- name: Build XCFramework
|
||||
run: nix develop -c zig build -Demit-lib-vt -Doptimize=ReleaseFast
|
||||
|
||||
- name: Zip XCFramework
|
||||
run: |
|
||||
cd zig-out/lib
|
||||
zip -9 -r ../../ghostty-vt.xcframework.zip ghostty-vt.xcframework
|
||||
|
||||
- name: Sign XCFramework
|
||||
run: |
|
||||
echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
|
||||
echo -n "${{ secrets.MINISIGN_PASSWORD }}" > minisign.password
|
||||
nix develop -c minisign -S -m ghostty-vt.xcframework.zip -s minisign.key < minisign.password
|
||||
|
||||
- name: Update Release
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
with:
|
||||
name: 'Ghostty Tip ("Nightly")'
|
||||
prerelease: true
|
||||
tag_name: tip
|
||||
target_commitish: ${{ github.sha }}
|
||||
files: |
|
||||
ghostty-vt.xcframework.zip
|
||||
ghostty-vt.xcframework.zip.minisig
|
||||
token: ${{ secrets.GH_RELEASE_TOKEN }}
|
||||
|
||||
- name: Prep R2 Storage
|
||||
run: |
|
||||
mkdir -p blob/${GHOSTTY_COMMIT_LONG}
|
||||
cp ghostty-vt.xcframework.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-vt.xcframework.zip
|
||||
- name: Upload to R2
|
||||
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
|
||||
with:
|
||||
r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
|
||||
r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
|
||||
r2-secret-access-key: ${{ secrets.CF_R2_TIP_SECRET_KEY }}
|
||||
r2-bucket: ghostty-tip
|
||||
source-dir: blob
|
||||
destination-dir: ./
|
||||
|
||||
- name: Echo Release URLs
|
||||
run: |
|
||||
echo "Release URLs:"
|
||||
echo " XCFramework: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-vt.xcframework.zip"
|
||||
|
||||
build-macos:
|
||||
needs: [setup]
|
||||
if: |
|
||||
|
|
@ -387,13 +228,13 @@ jobs:
|
|||
ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# Important so that build number generation works
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
cache: |
|
||||
xcode
|
||||
|
|
@ -404,13 +245,13 @@ jobs:
|
|||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
determinate: true
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: XCode Select
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.3.app
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.2.app
|
||||
|
||||
- name: Xcode Version
|
||||
run: xcodebuild -version
|
||||
|
|
@ -537,7 +378,7 @@ jobs:
|
|||
|
||||
# Update Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||
with:
|
||||
name: 'Ghostty Tip ("Nightly")'
|
||||
prerelease: true
|
||||
|
|
@ -615,7 +456,7 @@ jobs:
|
|||
EOF
|
||||
|
||||
- name: Upload Release URLs
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v6.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v6.0
|
||||
with:
|
||||
name: release-urls-${{ inputs.pr || '0' }}
|
||||
path: release-urls.txt
|
||||
|
|
@ -643,13 +484,13 @@ jobs:
|
|||
ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# Important so that build number generation works
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
cache: |
|
||||
xcode
|
||||
|
|
@ -660,13 +501,13 @@ jobs:
|
|||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
determinate: true
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: XCode Select
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.3.app
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.2.app
|
||||
|
||||
- name: Xcode Version
|
||||
run: xcodebuild -version
|
||||
|
|
@ -786,7 +627,7 @@ jobs:
|
|||
|
||||
# Update Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||
with:
|
||||
name: 'Ghostty Tip ("Nightly")'
|
||||
prerelease: true
|
||||
|
|
@ -840,13 +681,13 @@ jobs:
|
|||
ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# Important so that build number generation works
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
cache: |
|
||||
xcode
|
||||
|
|
@ -857,13 +698,13 @@ jobs:
|
|||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
determinate: true
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: XCode Select
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.3.app
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.2.app
|
||||
|
||||
- name: Xcode Version
|
||||
run: xcodebuild -version
|
||||
|
|
@ -983,7 +824,7 @@ jobs:
|
|||
|
||||
# Update Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||
with:
|
||||
name: 'Ghostty Tip ("Nightly")'
|
||||
prerelease: true
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,22 +17,22 @@ jobs:
|
|||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
- name: Setup Nix
|
||||
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
|
||||
uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934 # v31.10.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
|
||||
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
|
@ -79,7 +79,7 @@ jobs:
|
|||
run: nix build .#ghostty
|
||||
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
|
||||
with:
|
||||
title: Update iTerm2 colorschemes
|
||||
base: main
|
||||
|
|
|
|||
|
|
@ -8,21 +8,15 @@ jobs:
|
|||
check:
|
||||
runs-on: namespace-profile-ghostty-xsm
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.VOUCH_APP_ID }}
|
||||
private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
sparse-checkout: .github/issue-unvouched-message
|
||||
|
||||
- uses: mitchellh/vouch/action/check-issue@52aec3d64655edf2fdb58f298e02da754a056daf # unreleased main
|
||||
- uses: mitchellh/vouch/action/check-issue@c6d80ead49839655b61b422700b7a3bc9d0804a9 # v1.4.2
|
||||
with:
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
auto-close: true
|
||||
auto-lock: true
|
||||
template-file: .github/issue-unvouched-message
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ jobs:
|
|||
check:
|
||||
runs-on: namespace-profile-ghostty-xsm
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.VOUCH_APP_ID }}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ jobs:
|
|||
manage:
|
||||
runs-on: namespace-profile-ghostty-xsm
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.VOUCH_APP_ID }}
|
||||
private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ jobs:
|
|||
manage:
|
||||
runs-on: namespace-profile-ghostty-xsm
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.VOUCH_APP_ID }}
|
||||
private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ jobs:
|
|||
sync:
|
||||
runs-on: namespace-profile-ghostty-xsm
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.VOUCH_APP_ID }}
|
||||
private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@
|
|||
zig-cache/
|
||||
.zig-cache/
|
||||
zig-out/
|
||||
build-cmake/
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
/build.zig.zon.bak
|
||||
/result*
|
||||
/.nixos-test-history
|
||||
|
|
|
|||
|
|
@ -26,6 +26,3 @@ website/.next
|
|||
# fuzz corpus files
|
||||
test/fuzz-libghostty/corpus/
|
||||
test/fuzz-libghostty/afl-out/
|
||||
|
||||
# Swift example build outputs
|
||||
example/swift-vt-xcframework/.build/
|
||||
|
|
|
|||
|
|
@ -16,15 +16,6 @@ A file for [guiding coding agents](https://agents.md/).
|
|||
- **Formatting (Swift)**: `swiftlint lint --strict --fix`
|
||||
- **Formatting (other)**: `prettier -w .`
|
||||
|
||||
## libghostty-vt
|
||||
|
||||
- Build: `zig build -Demit-lib-vt`
|
||||
- Build WASM: `zig build -Demit-lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall`
|
||||
- Test: `zig build test-lib-vt -Dtest-filter=<filter>`
|
||||
- Prefer this when the change is in a libghostty-vt file
|
||||
- All C enums in `include/ghostty/vt/` must have a `_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE`
|
||||
sentinel as the last entry to force int enum sizing (pre-C23 portability).
|
||||
|
||||
## Directory Structure
|
||||
|
||||
- Shared Zig core: `src/`
|
||||
|
|
|
|||
377
CMakeLists.txt
377
CMakeLists.txt
|
|
@ -1,377 +0,0 @@
|
|||
# CMake wrapper for libghostty-vt
|
||||
#
|
||||
# This file delegates to `zig build -Demit-lib-vt` to produce the shared library,
|
||||
# headers, and pkg-config file. It exists so that CMake-based projects can
|
||||
# consume libghostty-vt without interacting with the Zig build system
|
||||
# directly. However, downstream users do still require `zig` on the PATH.
|
||||
# Please consult the Ghostty docs for the required Zig version:
|
||||
#
|
||||
# https://ghostty.org/docs/install/build
|
||||
#
|
||||
# Building within the Ghostty repo
|
||||
# ---------------------------------
|
||||
#
|
||||
# cmake -B build
|
||||
# cmake --build build
|
||||
# cmake --install build --prefix /usr/local
|
||||
#
|
||||
# Pass extra flags to the Zig build with GHOSTTY_ZIG_BUILD_FLAGS:
|
||||
#
|
||||
# cmake -B build -DGHOSTTY_ZIG_BUILD_FLAGS="-Demit-macos-app=false"
|
||||
#
|
||||
# Integrating into a downstream CMake project
|
||||
# ---------------------------------------------
|
||||
#
|
||||
# Option 1 — FetchContent (recommended, no manual install step):
|
||||
#
|
||||
# include(FetchContent)
|
||||
# FetchContent_Declare(ghostty
|
||||
# GIT_REPOSITORY https://github.com/ghostty-org/ghostty.git
|
||||
# GIT_TAG main
|
||||
# )
|
||||
# FetchContent_MakeAvailable(ghostty)
|
||||
#
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt) # shared
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt-static) # static
|
||||
#
|
||||
# To use a local checkout instead of fetching:
|
||||
#
|
||||
# cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=/path/to/ghostty
|
||||
#
|
||||
# Option 2 — find_package (after installing to a prefix):
|
||||
#
|
||||
# find_package(ghostty-vt REQUIRED)
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt::ghostty-vt) # shared
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt::ghostty-vt-static) # static
|
||||
#
|
||||
# Cross-compilation
|
||||
# -------------------
|
||||
#
|
||||
# For building libghostty-vt for a non-native Zig target (e.g. cross-
|
||||
# compiling), use the ghostty_vt_add_target() function after FetchContent:
|
||||
#
|
||||
# FetchContent_MakeAvailable(ghostty)
|
||||
# ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu)
|
||||
#
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt-static-linux-amd64) # static
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt-linux-amd64) # shared
|
||||
#
|
||||
# This handles zig discovery, build-type-to-optimize mapping, and output
|
||||
# path conventions internally. Extra flags can be forwarded with ZIG_FLAGS:
|
||||
#
|
||||
# ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu
|
||||
# ZIG_FLAGS -Dsimd=false)
|
||||
#
|
||||
# See dist/cmake/README.md for more details, example/c-vt-cmake/ for a
|
||||
# complete working example, and example/c-vt-cmake-cross/ for a cross-
|
||||
# compilation example.
|
||||
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(ghostty-vt VERSION 0.1.0 LANGUAGES C)
|
||||
|
||||
# --- Options ----------------------------------------------------------------
|
||||
|
||||
set(GHOSTTY_ZIG_BUILD_FLAGS "" CACHE STRING "Additional flags to pass to zig build")
|
||||
|
||||
# Map CMake build types to Zig optimization levels. The result is stored in
|
||||
# _GHOSTTY_ZIG_OPT_FLAG so both the native build and ghostty_vt_add_target()
|
||||
# can reuse it without duplicating the mapping logic.
|
||||
set(_GHOSTTY_ZIG_OPT_FLAG "")
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" _bt)
|
||||
if(_bt STREQUAL "RELEASE" OR _bt STREQUAL "MINSIZEREL" OR _bt STREQUAL "RELWITHDEBINFO")
|
||||
set(_GHOSTTY_ZIG_OPT_FLAG "-Doptimize=ReleaseFast")
|
||||
endif()
|
||||
unset(_bt)
|
||||
endif()
|
||||
|
||||
if(_GHOSTTY_ZIG_OPT_FLAG)
|
||||
list(APPEND GHOSTTY_ZIG_BUILD_FLAGS "${_GHOSTTY_ZIG_OPT_FLAG}")
|
||||
endif()
|
||||
|
||||
# --- Find Zig ----------------------------------------------------------------
|
||||
|
||||
find_program(ZIG_EXECUTABLE zig REQUIRED)
|
||||
message(STATUS "Found zig: ${ZIG_EXECUTABLE}")
|
||||
|
||||
# --- Build via zig build -----------------------------------------------------
|
||||
|
||||
# The zig build installs into zig-out/ relative to the source tree.
|
||||
set(ZIG_OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zig-out")
|
||||
|
||||
# Shared library names (zig build produces both shared and static).
|
||||
if(APPLE)
|
||||
set(GHOSTTY_VT_LIBNAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
set(GHOSTTY_VT_SONAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt.0${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
set(GHOSTTY_VT_REALNAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt.0.1.0${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
elseif(WIN32)
|
||||
set(GHOSTTY_VT_LIBNAME "ghostty-vt.dll")
|
||||
set(GHOSTTY_VT_REALNAME "ghostty-vt.dll")
|
||||
set(GHOSTTY_VT_IMPLIB "ghostty-vt.lib")
|
||||
else()
|
||||
set(GHOSTTY_VT_LIBNAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
set(GHOSTTY_VT_SONAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt${CMAKE_SHARED_LIBRARY_SUFFIX}.0")
|
||||
set(GHOSTTY_VT_REALNAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt${CMAKE_SHARED_LIBRARY_SUFFIX}.0.1.0")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(GHOSTTY_VT_SHARED_LIBRARY "${ZIG_OUT_DIR}/bin/${GHOSTTY_VT_REALNAME}")
|
||||
else()
|
||||
set(GHOSTTY_VT_SHARED_LIBRARY "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_REALNAME}")
|
||||
endif()
|
||||
|
||||
# Static library name.
|
||||
# On Windows, the static lib is named "ghostty-vt-static.lib" to avoid
|
||||
# colliding with the DLL import library "ghostty-vt.lib".
|
||||
if(WIN32)
|
||||
set(GHOSTTY_VT_STATIC_REALNAME "ghostty-vt-static.lib")
|
||||
else()
|
||||
set(GHOSTTY_VT_STATIC_REALNAME "libghostty-vt.a")
|
||||
endif()
|
||||
set(GHOSTTY_VT_STATIC_LIBRARY "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_STATIC_REALNAME}")
|
||||
|
||||
# Ensure the output directories exist so CMake doesn't reject the
|
||||
# INTERFACE_INCLUDE_DIRECTORIES before the zig build has run.
|
||||
file(MAKE_DIRECTORY "${ZIG_OUT_DIR}/include")
|
||||
|
||||
# Custom command: run zig build -Demit-lib-vt (produces both shared and static)
|
||||
add_custom_command(
|
||||
OUTPUT "${GHOSTTY_VT_SHARED_LIBRARY}" "${GHOSTTY_VT_STATIC_LIBRARY}" "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_IMPLIB}"
|
||||
COMMAND "${ZIG_EXECUTABLE}" build -Demit-lib-vt ${GHOSTTY_ZIG_BUILD_FLAGS}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "Building libghostty-vt via zig build..."
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
add_custom_target(zig_build_lib_vt ALL
|
||||
DEPENDS "${GHOSTTY_VT_SHARED_LIBRARY}" "${GHOSTTY_VT_STATIC_LIBRARY}"
|
||||
)
|
||||
|
||||
# Tell CMake's clean target to also remove Zig's output directory.
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
ADDITIONAL_CLEAN_FILES "${ZIG_OUT_DIR}"
|
||||
)
|
||||
|
||||
# --- IMPORTED library targets ------------------------------------------------
|
||||
|
||||
# Shared
|
||||
add_library(ghostty-vt SHARED IMPORTED GLOBAL)
|
||||
set_target_properties(ghostty-vt PROPERTIES
|
||||
IMPORTED_LOCATION "${GHOSTTY_VT_SHARED_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${ZIG_OUT_DIR}/include"
|
||||
)
|
||||
if(APPLE)
|
||||
set_target_properties(ghostty-vt PROPERTIES
|
||||
IMPORTED_SONAME "@rpath/${GHOSTTY_VT_SONAME}"
|
||||
)
|
||||
elseif(WIN32)
|
||||
set_target_properties(ghostty-vt PROPERTIES
|
||||
IMPORTED_IMPLIB "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_IMPLIB}"
|
||||
)
|
||||
else()
|
||||
set_target_properties(ghostty-vt PROPERTIES
|
||||
IMPORTED_SONAME "${GHOSTTY_VT_SONAME}"
|
||||
)
|
||||
endif()
|
||||
add_dependencies(ghostty-vt zig_build_lib_vt)
|
||||
|
||||
# Static
|
||||
#
|
||||
# On Linux and macOS, the static library is a fat archive that bundles
|
||||
# the vendored SIMD dependencies (highway, simdutf). Consumers
|
||||
# only need to link libc.
|
||||
#
|
||||
# On Windows, the SIMD dependencies are not bundled and must be linked
|
||||
# separately.
|
||||
#
|
||||
# Building with -Dsimd=false removes all runtime dependencies.
|
||||
add_library(ghostty-vt-static STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(ghostty-vt-static PROPERTIES
|
||||
IMPORTED_LOCATION "${GHOSTTY_VT_STATIC_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${ZIG_OUT_DIR}/include"
|
||||
INTERFACE_COMPILE_DEFINITIONS "GHOSTTY_STATIC"
|
||||
)
|
||||
if(WIN32)
|
||||
# On Windows, the Zig standard library uses NT API functions
|
||||
# (NtClose, NtCreateSection, etc.) and kernel32 functions that
|
||||
# consumers must link when using the static library.
|
||||
set_target_properties(ghostty-vt-static PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "ntdll;kernel32"
|
||||
)
|
||||
endif()
|
||||
add_dependencies(ghostty-vt-static zig_build_lib_vt)
|
||||
|
||||
# --- Install ------------------------------------------------------------------
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Install shared library
|
||||
if(WIN32)
|
||||
# On Windows, install the DLL and PDB to bin/ and the import library to lib/
|
||||
install(FILES "${GHOSTTY_VT_SHARED_LIBRARY}" "${ZIG_OUT_DIR}/bin/ghostty-vt.pdb" TYPE BIN)
|
||||
install(FILES "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_IMPLIB}" TYPE LIB)
|
||||
else()
|
||||
install(FILES "${GHOSTTY_VT_SHARED_LIBRARY}" TYPE LIB)
|
||||
# Install symlinks
|
||||
install(CODE "
|
||||
execute_process(COMMAND \${CMAKE_COMMAND} -E create_symlink
|
||||
\"${GHOSTTY_VT_REALNAME}\"
|
||||
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${GHOSTTY_VT_SONAME}\")
|
||||
execute_process(COMMAND \${CMAKE_COMMAND} -E create_symlink
|
||||
\"${GHOSTTY_VT_SONAME}\"
|
||||
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${GHOSTTY_VT_LIBNAME}\")
|
||||
")
|
||||
endif()
|
||||
|
||||
# Install static library
|
||||
install(FILES "${GHOSTTY_VT_STATIC_LIBRARY}" TYPE LIB)
|
||||
|
||||
# Install headers
|
||||
install(DIRECTORY "${ZIG_OUT_DIR}/include/ghostty" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
# --- CMake package config for find_package() ----------------------------------
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# Generate the config file
|
||||
configure_package_config_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist/cmake/ghostty-vt-config.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ghostty-vt-config.cmake"
|
||||
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghostty-vt"
|
||||
)
|
||||
|
||||
# Generate the version file
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ghostty-vt-config-version.cmake"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
# Install the config files
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ghostty-vt-config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ghostty-vt-config-version.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghostty-vt"
|
||||
)
|
||||
|
||||
# --- Cross-compilation helper ------------------------------------------------
|
||||
#
|
||||
# For downstream projects that need to build libghostty-vt for a specific
|
||||
# Zig target triple. For native builds, use the IMPORTED targets above
|
||||
# (ghostty-vt, ghostty-vt-static) directly.
|
||||
#
|
||||
# Usage (in a downstream CMakeLists.txt after FetchContent_MakeAvailable):
|
||||
#
|
||||
# ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu)
|
||||
#
|
||||
# Creates:
|
||||
# ghostty-vt-static-linux-amd64 (IMPORTED STATIC library)
|
||||
# ghostty-vt-linux-amd64 (IMPORTED SHARED library)
|
||||
#
|
||||
# Optional ZIG_FLAGS to pass additional flags to zig build:
|
||||
#
|
||||
# ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu
|
||||
# ZIG_FLAGS -Dsimd=false)
|
||||
|
||||
function(ghostty_vt_add_target)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 _GVT "" "NAME;ZIG_TARGET" "ZIG_FLAGS")
|
||||
|
||||
if(NOT _GVT_NAME)
|
||||
message(FATAL_ERROR "ghostty_vt_add_target: NAME is required")
|
||||
endif()
|
||||
if(NOT _GVT_ZIG_TARGET)
|
||||
message(FATAL_ERROR "ghostty_vt_add_target: ZIG_TARGET is required")
|
||||
endif()
|
||||
|
||||
set(_src_dir "${CMAKE_CURRENT_FUNCTION_LIST_DIR}")
|
||||
set(_prefix "${CMAKE_CURRENT_BINARY_DIR}/ghostty-${_GVT_NAME}")
|
||||
|
||||
# Build flags
|
||||
set(_flags
|
||||
-Demit-lib-vt
|
||||
-Dtarget=${_GVT_ZIG_TARGET}
|
||||
--prefix "${_prefix}"
|
||||
)
|
||||
|
||||
# Default to ReleaseFast when no build type is set. Debug builds enable
|
||||
# UBSan in zig, and the sanitizer runtime is not available for all
|
||||
# cross-compilation targets.
|
||||
if(_GHOSTTY_ZIG_OPT_FLAG)
|
||||
list(APPEND _flags "${_GHOSTTY_ZIG_OPT_FLAG}")
|
||||
else()
|
||||
list(APPEND _flags "-Doptimize=ReleaseFast")
|
||||
endif()
|
||||
|
||||
if(_GVT_ZIG_FLAGS)
|
||||
list(APPEND _flags ${_GVT_ZIG_FLAGS})
|
||||
endif()
|
||||
|
||||
# Output paths
|
||||
set(_include_dir "${_prefix}/include")
|
||||
|
||||
if(_GVT_ZIG_TARGET MATCHES "windows")
|
||||
set(_static_lib "${_prefix}/lib/ghostty-vt-static.lib")
|
||||
set(_shared_lib "${_prefix}/bin/ghostty-vt.dll")
|
||||
set(_implib "${_prefix}/lib/ghostty-vt.lib")
|
||||
elseif(_GVT_ZIG_TARGET MATCHES "darwin|macos")
|
||||
set(_static_lib "${_prefix}/lib/libghostty-vt.a")
|
||||
set(_shared_lib "${_prefix}/lib/libghostty-vt.0.1.0.dylib")
|
||||
else()
|
||||
set(_static_lib "${_prefix}/lib/libghostty-vt.a")
|
||||
set(_shared_lib "${_prefix}/lib/libghostty-vt.so.0.1.0")
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY "${_include_dir}")
|
||||
|
||||
# Custom command: invoke zig build
|
||||
add_custom_command(
|
||||
OUTPUT "${_static_lib}" "${_shared_lib}"
|
||||
COMMAND "${ZIG_EXECUTABLE}" build ${_flags}
|
||||
WORKING_DIRECTORY "${_src_dir}"
|
||||
COMMENT "Building libghostty-vt for ${_GVT_ZIG_TARGET}..."
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
set(_build_target "zig_build_lib_vt_${_GVT_NAME}")
|
||||
add_custom_target(${_build_target} ALL
|
||||
DEPENDS "${_static_lib}" "${_shared_lib}"
|
||||
)
|
||||
|
||||
# Static target
|
||||
set(_static_target "ghostty-vt-static-${_GVT_NAME}")
|
||||
add_library(${_static_target} STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(${_static_target} PROPERTIES
|
||||
IMPORTED_LOCATION "${_static_lib}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_include_dir}"
|
||||
INTERFACE_COMPILE_DEFINITIONS "GHOSTTY_STATIC"
|
||||
)
|
||||
if(_GVT_ZIG_TARGET MATCHES "windows")
|
||||
set_target_properties(${_static_target} PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "ntdll;kernel32"
|
||||
)
|
||||
endif()
|
||||
add_dependencies(${_static_target} ${_build_target})
|
||||
|
||||
# Shared target
|
||||
set(_shared_target "ghostty-vt-${_GVT_NAME}")
|
||||
add_library(${_shared_target} SHARED IMPORTED GLOBAL)
|
||||
set_target_properties(${_shared_target} PROPERTIES
|
||||
IMPORTED_LOCATION "${_shared_lib}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_include_dir}"
|
||||
)
|
||||
if(_GVT_ZIG_TARGET MATCHES "windows")
|
||||
set_target_properties(${_shared_target} PROPERTIES
|
||||
IMPORTED_IMPLIB "${_implib}"
|
||||
)
|
||||
elseif(_GVT_ZIG_TARGET MATCHES "darwin|macos")
|
||||
set_target_properties(${_shared_target} PROPERTIES
|
||||
IMPORTED_SONAME "@rpath/libghostty-vt.0.dylib"
|
||||
)
|
||||
else()
|
||||
set_target_properties(${_shared_target} PROPERTIES
|
||||
IMPORTED_SONAME "libghostty-vt.so.0"
|
||||
)
|
||||
endif()
|
||||
add_dependencies(${_shared_target} ${_build_target})
|
||||
endfunction()
|
||||
|
|
@ -162,17 +162,14 @@
|
|||
/src/surface_mouse.zig @ghostty-org/terminal
|
||||
|
||||
# Localization
|
||||
/po/README_TRANSLATORS.md @ghostty-org/manager # *localization* manager.
|
||||
/po/com.mitchellh.ghostty.pot @ghostty-org/manager
|
||||
/src/os/i18n_locales.zig @ghostty-org/manager
|
||||
/po/be.po @ghostty-org/be_BY
|
||||
/po/README_TRANSLATORS.md @ghostty-org/localization
|
||||
/po/com.mitchellh.ghostty.pot @ghostty-org/localization
|
||||
/po/bg.po @ghostty-org/bg_BG
|
||||
/po/ca.po @ghostty-org/ca_ES
|
||||
/po/de.po @ghostty-org/de_DE
|
||||
/po/es_AR.po @ghostty-org/es_AR
|
||||
/po/es_BO.po @ghostty-org/es_BO
|
||||
/po/es_ES.po @ghostty-org/es_ES
|
||||
/po/eu.po @ghostty-org/eu_ES
|
||||
/po/fr.po @ghostty-org/fr_FR
|
||||
/po/ga.po @ghostty-org/ga_IE
|
||||
/po/he.po @ghostty-org/he_IL
|
||||
|
|
|
|||
|
|
@ -177,6 +177,11 @@ item is identified, it is moved to the issue tracker. **This pattern
|
|||
makes it easier for maintainers or contributors to find issues to work on
|
||||
since _every issue_ is ready to be worked on.**
|
||||
|
||||
If you are experiencing a bug and have clear steps to reproduce it, please
|
||||
open an issue. If you are experiencing a bug but you are not sure how to
|
||||
reproduce it or aren't sure if it's a bug, please open a discussion.
|
||||
If you have an idea for a feature, please open a discussion.
|
||||
|
||||
### Pull Requests Implement an Issue
|
||||
|
||||
Pull requests should be associated with a previously accepted issue.
|
||||
|
|
|
|||
|
|
@ -67,14 +67,6 @@ sudo xcode-select --switch /Applications/Xcode.app
|
|||
> You do not need to be running on macOS 26 to build Ghostty, you can
|
||||
> still use Xcode 26 on macOS 15 stable.
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> Zig 0.15.x has a [known linking issue](https://codeberg.org/ziglang/zig/issues/31658)
|
||||
> with **Xcode 26.4**. If you are on Xcode 26.4, you must use a
|
||||
> Homebrew-installed Zig (`brew install zig@0.15`) or our Nix flake,
|
||||
> both of which contain a patch that works around the issue. Alternatively,
|
||||
> you can downgrade to **Xcode 26.3**.
|
||||
|
||||
## AI and Agents
|
||||
|
||||
If you're using AI assistance with Ghostty, Ghostty provides an
|
||||
|
|
|
|||
145
README.md
145
README.md
|
|
@ -7,8 +7,6 @@
|
|||
<p align="center">
|
||||
Fast, native, feature-rich terminal emulator pushing modern features.
|
||||
<br />
|
||||
A native GUI or embeddable library via <code>libghostty</code>.
|
||||
<br />
|
||||
<a href="#about">About</a>
|
||||
·
|
||||
<a href="https://ghostty.org/download">Download</a>
|
||||
|
|
@ -28,13 +26,20 @@ fast, feature-rich, and native. While there are many excellent terminal
|
|||
emulators available, they all force you to choose between speed,
|
||||
features, or native UIs. Ghostty provides all three.
|
||||
|
||||
**`libghostty`** is a cross-platform, zero-dependency C and Zig library
|
||||
for building terminal emulators or utilizing terminal functionality
|
||||
(such as style parsing). Anyone can use `libghostty` to build a terminal
|
||||
emulator or embed a terminal into their own applications. See
|
||||
[Ghostling](https://github.com/ghostty-org/ghostling) for a minimal complete project
|
||||
example or the [`examples` directory](https://github.com/ghostty-org/ghostty/tree/main/example)
|
||||
for smaller examples of using `libghostty` in C and Zig.
|
||||
In all categories, I am not trying to claim that Ghostty is the
|
||||
best (i.e. the fastest, most feature-rich, or most native). But
|
||||
Ghostty is competitive in all three categories and Ghostty
|
||||
doesn't make you choose between them.
|
||||
|
||||
Ghostty also intends to push the boundaries of what is possible with a
|
||||
terminal emulator by exposing modern, opt-in features that enable CLI tool
|
||||
developers to build more feature rich, interactive applications.
|
||||
|
||||
While aiming for this ambitious goal, our first step is to make Ghostty
|
||||
one of the best fully standards compliant terminal emulator, remaining
|
||||
compatible with all existing shells and software while supporting all of
|
||||
the latest terminal innovations in the ecosystem. You can use Ghostty
|
||||
as a drop-in replacement for your existing terminal emulator.
|
||||
|
||||
For more details, see [About Ghostty](https://ghostty.org/docs/about).
|
||||
|
||||
|
|
@ -56,37 +61,30 @@ to get involved with Ghostty's development as well should also read the
|
|||
|
||||
## Roadmap and Status
|
||||
|
||||
Ghostty is stable and in use by millions of people and machines daily.
|
||||
|
||||
The high-level ambitious plan for the project, in order:
|
||||
|
||||
| # | Step | Status |
|
||||
| :-: | ------------------------------------------------------- | :----: |
|
||||
| 1 | Standards-compliant terminal emulation | ✅ |
|
||||
| 2 | Competitive performance | ✅ |
|
||||
| 3 | Rich windowing features -- multi-window, tabbing, panes | ✅ |
|
||||
| 4 | Native Platform Experiences | ✅ |
|
||||
| 5 | Cross-platform `libghostty` for Embeddable Terminals | ✅ |
|
||||
| 6 | Ghostty-only Terminal Control Sequences | ❌ |
|
||||
| # | Step | Status |
|
||||
| :-: | --------------------------------------------------------- | :----: |
|
||||
| 1 | Standards-compliant terminal emulation | ✅ |
|
||||
| 2 | Competitive performance | ✅ |
|
||||
| 3 | Basic customizability -- fonts, bg colors, etc. | ✅ |
|
||||
| 4 | Richer windowing features -- multi-window, tabbing, panes | ✅ |
|
||||
| 5 | Native Platform Experiences (i.e. Mac Preference Panel) | ⚠️ |
|
||||
| 6 | Cross-platform `libghostty` for Embeddable Terminals | ⚠️ |
|
||||
| 7 | Windows Terminals (including PowerShell, Cmd, WSL) | ❌ |
|
||||
| N | Fancy features (to be expanded upon later) | ❌ |
|
||||
|
||||
Additional details for each step in the big roadmap below:
|
||||
|
||||
#### Standards-Compliant Terminal Emulation
|
||||
|
||||
Ghostty implements all of the regularly used control sequences and
|
||||
can run every mainstream terminal program without issue. For legacy sequences,
|
||||
we've done a [comprehensive xterm audit](https://github.com/ghostty-org/ghostty/issues/632)
|
||||
Ghostty implements enough control sequences to be used by hundreds of
|
||||
testers daily for over the past year. Further, we've done a
|
||||
[comprehensive xterm audit](https://github.com/ghostty-org/ghostty/issues/632)
|
||||
comparing Ghostty's behavior to xterm and building a set of conformance
|
||||
test cases.
|
||||
|
||||
In addition to legacy sequences (what you'd call real "terminal" emulation),
|
||||
Ghostty also supports more modern sequences than almost any other terminal
|
||||
emulator. These features include things like the Kitty graphics protocol,
|
||||
Kitty image protocol, clipboard sequences, synchronized rendering,
|
||||
light/dark mode notifications, and many, many more.
|
||||
|
||||
We believe Ghostty is one of the most compliant and feature-rich terminal
|
||||
emulators available.
|
||||
We believe Ghostty is one of the most compliant terminal emulators available.
|
||||
|
||||
Terminal behavior is partially a de jure standard
|
||||
(i.e. [ECMA-48](https://ecma-international.org/publications-and-standards/standards/ecma-48/))
|
||||
|
|
@ -98,30 +96,33 @@ views as a "standard."
|
|||
|
||||
#### Competitive Performance
|
||||
|
||||
Ghostty is generally in the same performance category as the other highest
|
||||
performing terminal emulators.
|
||||
We need better benchmarks to continuously verify this, but Ghostty is
|
||||
generally in the same performance category as the other highest performing
|
||||
terminal emulators.
|
||||
|
||||
"The same performance category" means that Ghostty is much faster than
|
||||
traditional or "slow" terminals and is within an unnoticeable margin of the
|
||||
well-known "fast" terminals. For example, Ghostty and Alacritty are usually within
|
||||
a few percentage points of each other on various benchmarks, but are both
|
||||
something like 100x faster than Terminal.app and iTerm. However, Ghostty
|
||||
is much more feature rich than Alacritty and has a much more native app
|
||||
experience.
|
||||
For rendering, we have a multi-renderer architecture that uses OpenGL on
|
||||
Linux and Metal on macOS. As far as I'm aware, we're the only terminal
|
||||
emulator other than iTerm that uses Metal directly. And we're the only
|
||||
terminal emulator that has a Metal renderer that supports ligatures (iTerm
|
||||
uses a CPU renderer if ligatures are enabled). We can maintain around 60fps
|
||||
under heavy load and much more generally -- though the terminal is
|
||||
usually rendering much lower due to little screen changes.
|
||||
|
||||
This performance is achieved through high-level architectural decisions and
|
||||
low-level optimizations. At a high-level, Ghostty has a multi-threaded
|
||||
architecture with a dedicated read thread, write thread, and render thread
|
||||
per terminal. Our renderer uses OpenGL on Linux and Metal on macOS.
|
||||
Our read thread has a heavily optimized terminal parser that leverages
|
||||
CPU-specific SIMD instructions. Etc.
|
||||
For IO, we have a dedicated IO thread that maintains very little jitter
|
||||
under heavy IO load (i.e. `cat <big file>.txt`). On benchmarks for IO,
|
||||
we're usually within a small margin of other fast terminal emulators.
|
||||
For example, reading a dump of plain text is 4x faster compared to iTerm and
|
||||
Kitty, and 2x faster than Terminal.app. Alacritty is very fast but we're still
|
||||
around the same speed (give or take) and our app experience is much more
|
||||
feature rich.
|
||||
|
||||
#### Rich Windowing Features
|
||||
> [!NOTE]
|
||||
> Despite being _very fast_, there is a lot of room for improvement here.
|
||||
|
||||
#### Richer Windowing Features
|
||||
|
||||
The Mac and Linux (build with GTK) apps support multi-window, tabbing, and
|
||||
splits with additional features such as tab renaming, coloring, etc. These
|
||||
features allow for a higher degree of organization and customization than
|
||||
single-window terminals.
|
||||
splits.
|
||||
|
||||
#### Native Platform Experiences
|
||||
|
||||
|
|
@ -132,15 +133,10 @@ in Zig but we do a lot of platform-native things:
|
|||
- The macOS app is a true SwiftUI-based application with all the things you
|
||||
would expect such as real windowing, menu bars, a settings GUI, etc.
|
||||
- macOS uses a true Metal renderer with CoreText for font discovery.
|
||||
- macOS supports AppleScript, Apple Shortcuts (AppIntents), etc.
|
||||
- The Linux app is built with GTK.
|
||||
- The Linux app integrates deeply with systemd if available for things
|
||||
like always-on, new windows in a single instance, cgroup isolation, etc.
|
||||
|
||||
Our goal with Ghostty is for users of whatever platform they run Ghostty
|
||||
on to think that Ghostty was built for their platform first and maybe even
|
||||
exclusively. We want Ghostty to feel like a native app on every platform,
|
||||
for the best definition of "native" on each platform.
|
||||
There are more improvements to be made. The macOS settings window is still
|
||||
a work-in-progress. Similar improvements will follow with Linux.
|
||||
|
||||
#### Cross-platform `libghostty` for Embeddable Terminals
|
||||
|
||||
|
|
@ -149,40 +145,21 @@ C-compatible library for embedding a fast, feature-rich terminal emulator
|
|||
in any 3rd party project. This library is called `libghostty`.
|
||||
|
||||
Due to the scope of this project, we're breaking libghostty down into
|
||||
separate libraries, starting with `libghostty-vt`. The goal of
|
||||
separate actually libraries, starting with `libghostty-vt`. The goal of
|
||||
this project is to focus on parsing terminal sequences and maintaining
|
||||
terminal state. This is covered in more detail in this
|
||||
[blog post](https://mitchellh.com/writing/libghostty-is-coming).
|
||||
|
||||
`libghostty-vt` is already available and usable today for Zig and C and
|
||||
is compatible for macOS, Linux, Windows, and WebAssembly. The functionality
|
||||
is extremely stable (since its been proven in Ghostty GUI for a long time),
|
||||
but the API signatures are still in flux.
|
||||
is compatible for macOS, Linux, Windows, and WebAssembly. At the time of
|
||||
writing this, the API isn't stable yet and we haven't tagged an official
|
||||
release, but the core logic is well proven (since Ghostty uses it) and
|
||||
we're working hard on it now.
|
||||
|
||||
`libghostty` is already heavily in use. See [`examples`](https://github.com/ghostty-org/ghostty/tree/main/example)
|
||||
for small examples of using `libghostty` in C and Zig or the
|
||||
[Ghostling](https://github.com/ghostty-org/ghostling) project for a
|
||||
complete example. See [awesome-libghostty](https://github.com/Uzaaft/awesome-libghostty)
|
||||
for a list of projects and resources related to `libghostty`.
|
||||
|
||||
We haven't tagged libghostty with a version yet and we're still working
|
||||
on a better docs experience, but our [Doxygen website](https://libghostty.tip.ghostty.org/)
|
||||
is a good resource for the C API.
|
||||
|
||||
#### Ghostty-only Terminal Control Sequences
|
||||
|
||||
We want and believe that terminal applications can and should be able
|
||||
to do so much more. We've worked hard to support a wide variety of modern
|
||||
sequences created by other terminal emulators towards this end, but we also
|
||||
want to fill the gaps by creating our own sequences.
|
||||
|
||||
We've been hesitant to do this up until now because we don't want to create
|
||||
more fragmentation in the terminal ecosystem by creating sequences that only
|
||||
work in Ghostty. But, we do want to balance that with the desire to push the
|
||||
terminal forward with stagnant standards and the slow pace of change in the
|
||||
terminal ecosystem.
|
||||
|
||||
We haven't done any of this yet.
|
||||
The ultimate goal is not hypothetical! The macOS app is a `libghostty` consumer.
|
||||
The macOS app is a native Swift app developed in Xcode and `main()` is
|
||||
within Swift. The Swift app links to `libghostty` and uses the C API to
|
||||
render terminals.
|
||||
|
||||
## Crash Reports
|
||||
|
||||
|
|
|
|||
124
build.zig
124
build.zig
|
|
@ -3,17 +3,11 @@ const assert = std.debug.assert;
|
|||
const builtin = @import("builtin");
|
||||
const buildpkg = @import("src/build/main.zig");
|
||||
|
||||
/// App version from build.zig.zon.
|
||||
const app_zon_version = @import("build.zig.zon").version;
|
||||
|
||||
/// Libghostty version. We use a separate version from the app.
|
||||
const lib_version = "0.1.0-dev";
|
||||
|
||||
/// Minimum required zig version.
|
||||
const minimum_zig_version = @import("build.zig.zon").minimum_zig_version;
|
||||
const appVersion = @import("build.zig.zon").version;
|
||||
const minimumZigVersion = @import("build.zig.zon").minimum_zig_version;
|
||||
|
||||
comptime {
|
||||
buildpkg.requireZig(minimum_zig_version);
|
||||
buildpkg.requireZig(minimumZigVersion);
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
|
|
@ -21,24 +15,7 @@ pub fn build(b: *std.Build) !void {
|
|||
// want to know what options are available, you can run `--help` or
|
||||
// you can read `src/build/Config.zig`.
|
||||
|
||||
// If we have a VERSION file (present in source tarballs) then we
|
||||
// use that as the version source of truth. Otherwise we fall back
|
||||
// to what is in the build.zig.zon.
|
||||
const file_version: ?[]const u8 = if (b.build_root.handle.readFileAlloc(
|
||||
b.allocator,
|
||||
"VERSION",
|
||||
128,
|
||||
)) |content| std.mem.trim(
|
||||
u8,
|
||||
content,
|
||||
&std.ascii.whitespace,
|
||||
) else |_| null;
|
||||
|
||||
const config = try buildpkg.Config.init(
|
||||
b,
|
||||
file_version orelse app_zon_version,
|
||||
lib_version,
|
||||
);
|
||||
const config = try buildpkg.Config.init(b, appVersion);
|
||||
const test_filters = b.option(
|
||||
[][]const u8,
|
||||
"test-filter",
|
||||
|
|
@ -58,6 +35,7 @@ pub fn build(b: *std.Build) !void {
|
|||
|
||||
// All our steps which we'll hook up later. The steps are shown
|
||||
// up here just so that they are more self-documenting.
|
||||
const libvt_step = b.step("lib-vt", "Build libghostty-vt");
|
||||
const run_step = b.step("run", "Run the app");
|
||||
const run_valgrind_step = b.step(
|
||||
"run-valgrind",
|
||||
|
|
@ -113,6 +91,16 @@ pub fn build(b: *std.Build) !void {
|
|||
check_step.dependOn(dist.install_step);
|
||||
}
|
||||
|
||||
// libghostty (internal, big)
|
||||
const libghostty_shared = try buildpkg.GhosttyLib.initShared(
|
||||
b,
|
||||
&deps,
|
||||
);
|
||||
const libghostty_static = try buildpkg.GhosttyLib.initStatic(
|
||||
b,
|
||||
&deps,
|
||||
);
|
||||
|
||||
// libghostty-vt
|
||||
const libghostty_vt_shared = shared: {
|
||||
if (config.target.result.cpu.arch.isWasm()) {
|
||||
|
|
@ -127,49 +115,9 @@ pub fn build(b: *std.Build) !void {
|
|||
&mod,
|
||||
);
|
||||
};
|
||||
libghostty_vt_shared.install(libvt_step);
|
||||
libghostty_vt_shared.install(b.getInstallStep());
|
||||
|
||||
// libghostty-vt static lib
|
||||
const libghostty_vt_static = try buildpkg.GhosttyLibVt.initStatic(
|
||||
b,
|
||||
&mod,
|
||||
);
|
||||
if (config.is_dep) {
|
||||
// If we're a dependency, we need to install everything as-is
|
||||
// so that dep.artifact("ghostty-vt-static") works.
|
||||
libghostty_vt_static.install(b.getInstallStep());
|
||||
} else {
|
||||
// If we're not a dependency, we rename the static lib to
|
||||
// be idiomatic. On Windows, we use a distinct name to avoid
|
||||
// colliding with the DLL import library (ghostty-vt.lib).
|
||||
const static_lib_name = if (config.target.result.os.tag == .windows)
|
||||
"ghostty-vt-static.lib"
|
||||
else
|
||||
"libghostty-vt.a";
|
||||
b.getInstallStep().dependOn(&b.addInstallLibFile(
|
||||
libghostty_vt_static.output,
|
||||
static_lib_name,
|
||||
).step);
|
||||
}
|
||||
|
||||
// libghostty-vt xcframework (Apple only, universal binary).
|
||||
// Only when building on macOS (not cross-compiling) since
|
||||
// xcodebuild is required.
|
||||
if (config.emit_lib_vt and
|
||||
config.emit_xcframework and
|
||||
builtin.os.tag.isDarwin() and
|
||||
config.target.result.os.tag.isDarwin())
|
||||
{
|
||||
const apple_libs = try buildpkg.GhosttyLibVt.initStaticAppleUniversal(
|
||||
b,
|
||||
&config,
|
||||
&deps,
|
||||
&mod,
|
||||
);
|
||||
const xcframework = buildpkg.GhosttyLibVt.xcframework(&apple_libs, b);
|
||||
b.getInstallStep().dependOn(xcframework.step);
|
||||
}
|
||||
|
||||
// Helpgen
|
||||
if (config.emit_helpgen) deps.help_strings.install();
|
||||
|
||||
|
|
@ -180,35 +128,26 @@ pub fn build(b: *std.Build) !void {
|
|||
resources.install();
|
||||
if (i18n) |v| v.install();
|
||||
}
|
||||
} else if (!config.emit_lib_vt) {
|
||||
// The macOS Ghostty Library
|
||||
} else {
|
||||
// Libghostty
|
||||
//
|
||||
// This is NOT libghostty (even though its named that for historical
|
||||
// reasons). It is just the glue between Ghostty GUI on macOS and
|
||||
// the full Ghostty GUI core.
|
||||
const lib_shared = try buildpkg.GhosttyLib.initShared(b, &deps);
|
||||
const lib_static = try buildpkg.GhosttyLib.initStatic(b, &deps);
|
||||
// Note: libghostty is not stable for general purpose use. It is used
|
||||
// heavily by Ghostty on macOS but it isn't built to be reusable yet.
|
||||
// As such, these build steps are lacking. For example, the Darwin
|
||||
// build only produces an xcframework.
|
||||
|
||||
// We shouldn't have this guard but we don't currently
|
||||
// build on macOS this way ironically so we need to fix that.
|
||||
if (!config.target.result.os.tag.isDarwin()) {
|
||||
lib_shared.installHeader(); // Only need one header
|
||||
if (config.target.result.os.tag == .windows) {
|
||||
lib_shared.install("ghostty-internal.dll");
|
||||
lib_static.install("ghostty-internal-static.lib");
|
||||
} else {
|
||||
lib_shared.install("ghostty-internal.so");
|
||||
lib_static.install("ghostty-internal.a");
|
||||
}
|
||||
libghostty_shared.installHeader(); // Only need one header
|
||||
libghostty_shared.install("libghostty.so");
|
||||
libghostty_static.install("libghostty.a");
|
||||
}
|
||||
}
|
||||
|
||||
// macOS only artifacts. These will error if they're initialized for
|
||||
// other targets. In lib-vt mode emit_xcframework controls the lib-vt
|
||||
// xcframework above, not this one.
|
||||
if (!config.emit_lib_vt and config.target.result.os.tag.isDarwin() and
|
||||
(config.emit_xcframework or config.emit_macos_app))
|
||||
{
|
||||
// other targets.
|
||||
if (config.target.result.os.tag.isDarwin()) {
|
||||
// Ghostty xcframework
|
||||
const xcframework = try buildpkg.GhosttyXCFramework.init(
|
||||
b,
|
||||
|
|
@ -263,10 +202,7 @@ pub fn build(b: *std.Build) !void {
|
|||
|
||||
// On macOS we can run the macOS app. For "run" we always force
|
||||
// a native-only build so that we can run as quickly as possible.
|
||||
if (!config.emit_lib_vt and
|
||||
config.target.result.os.tag.isDarwin() and
|
||||
(config.emit_xcframework or config.emit_macos_app))
|
||||
{
|
||||
if (config.target.result.os.tag.isDarwin()) {
|
||||
const xcframework_native = try buildpkg.GhosttyXCFramework.init(
|
||||
b,
|
||||
&deps,
|
||||
|
|
@ -335,8 +271,8 @@ pub fn build(b: *std.Build) !void {
|
|||
test_lib_vt_step.dependOn(&mod_vt_c_test_run.step);
|
||||
}
|
||||
|
||||
// Tests (skip when building libghostty-vt)
|
||||
if (!config.emit_lib_vt) {
|
||||
// Tests
|
||||
{
|
||||
// Full unit tests
|
||||
const test_exe = b.addTest(.{
|
||||
.name = "ghostty-test",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.{
|
||||
.name = .ghostty,
|
||||
.version = "1.3.2-dev",
|
||||
.version = "1.3.1",
|
||||
.paths = .{""},
|
||||
.fingerprint = 0x64407a2a0b4147e5,
|
||||
.minimum_zig_version = "0.15.2",
|
||||
|
|
@ -76,6 +76,7 @@
|
|||
.opengl = .{ .path = "./pkg/opengl", .lazy = true },
|
||||
.sentry = .{ .path = "./pkg/sentry", .lazy = true },
|
||||
.simdutf = .{ .path = "./pkg/simdutf", .lazy = true },
|
||||
.utfcpp = .{ .path = "./pkg/utfcpp", .lazy = true },
|
||||
.wuffs = .{ .path = "./pkg/wuffs", .lazy = true },
|
||||
.zlib = .{ .path = "./pkg/zlib", .lazy = true },
|
||||
|
||||
|
|
@ -90,8 +91,8 @@
|
|||
.lazy = true,
|
||||
},
|
||||
.wayland_protocols = .{
|
||||
.url = "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz",
|
||||
.hash = "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA",
|
||||
.url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
|
||||
.hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
|
||||
.lazy = true,
|
||||
},
|
||||
.plasma_wayland_protocols = .{
|
||||
|
|
@ -116,8 +117,8 @@
|
|||
.apple_sdk = .{ .path = "./pkg/apple-sdk" },
|
||||
.android_ndk = .{ .path = "./pkg/android-ndk" },
|
||||
.iterm2_themes = .{
|
||||
.url = "https://deps.files.ghostty.org/ghostty-themes-release-20260525-155808-7335c0a.tgz",
|
||||
.hash = "N-V-__8AAGi9AwC7QV7hLqjN6iBkXA2y5dxw285nkSLlVB7I",
|
||||
.url = "https://deps.files.ghostty.org/ghostty-themes-release-20260216-151611-fc73ce3.tgz",
|
||||
.hash = "N-V-__8AABVbAwBwDRyZONfx553tvMW8_A2OKUoLzPUSRiLF",
|
||||
.lazy = true,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
"gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-": {
|
||||
"name": "gobject",
|
||||
"url": "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst",
|
||||
"hash": "sha256-OxS9/XC5aMJj1KhOcFP1ZZN7PI4ADw4f7ocx6V64mOc="
|
||||
"hash": "sha256-2b1DBvAIHY5LhItq3+q9L6tJgi7itnnrSAHc7fXWDEg="
|
||||
},
|
||||
"N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": {
|
||||
"name": "gtk4_layer_shell",
|
||||
|
|
@ -54,10 +54,10 @@
|
|||
"url": "https://github.com/ocornut/imgui/archive/refs/tags/v1.92.5-docking.tar.gz",
|
||||
"hash": "sha256-yBbCDox18+Fa6Gc1DnmSVQLRpqhZOLsac7iSfl8x+cs="
|
||||
},
|
||||
"N-V-__8AAGi9AwC7QV7hLqjN6iBkXA2y5dxw285nkSLlVB7I": {
|
||||
"N-V-__8AABVbAwBwDRyZONfx553tvMW8_A2OKUoLzPUSRiLF": {
|
||||
"name": "iterm2_themes",
|
||||
"url": "https://deps.files.ghostty.org/ghostty-themes-release-20260525-155808-7335c0a.tgz",
|
||||
"hash": "sha256-HGujRdQdWtVIf3GwCgQgjV9lbwWxJSIDJOWq3gOX3kU="
|
||||
"url": "https://deps.files.ghostty.org/ghostty-themes-release-20260216-151611-fc73ce3.tgz",
|
||||
"hash": "sha256-FCALuGoMgUq2lgnVALKAs5a20uuDXt8Gdt5KeJwKqP0="
|
||||
},
|
||||
"N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x": {
|
||||
"name": "jetbrains_mono",
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
"libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs": {
|
||||
"name": "libxev",
|
||||
"url": "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz",
|
||||
"hash": "sha256-1B9oJExVyOWRj+Y9d9eHkOBTlOYuEkcwGBUKdlgRhkg="
|
||||
"hash": "sha256-YAPqa5bkpRihKPkyMn15oRvTCZaxO3O66ymRY3lIfdc="
|
||||
},
|
||||
"N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK": {
|
||||
"name": "libxml2",
|
||||
|
|
@ -109,6 +109,11 @@
|
|||
"url": "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz",
|
||||
"hash": "sha256-tStvz8Ref6abHwahNiwVVHNETizAmZVVaxVsU7pmV+M="
|
||||
},
|
||||
"N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH": {
|
||||
"name": "utfcpp",
|
||||
"url": "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz",
|
||||
"hash": "sha256-/8ZooxDndgfTk/PBizJxXyI9oerExNbgV5oR345rWc8="
|
||||
},
|
||||
"uucode-0.1.0-ZZjBPj96QADXyt5sqwBJUnhaDYs_qBeeKijZvlRa0eqM": {
|
||||
"name": "uucode",
|
||||
"url": "git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732",
|
||||
|
|
@ -117,12 +122,12 @@
|
|||
"uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9": {
|
||||
"name": "uucode",
|
||||
"url": "https://deps.files.ghostty.org/uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9.tar.gz",
|
||||
"hash": "sha256-jLrhrmCXQ1T+LQP1JTBBB3Jn+1hCZfODbC4SdlfNdKg="
|
||||
"hash": "sha256-0KvuD0+L1urjwFF3fhbnxC2JZKqqAVWRxOVlcD9GX5U="
|
||||
},
|
||||
"vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS": {
|
||||
"name": "vaxis",
|
||||
"url": "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz",
|
||||
"hash": "sha256-zTyrZrIffM+GJIt973tKDeWHmOCwbn7KLDdQxSiK00Y="
|
||||
"hash": "sha256-LnIzK8icW1Qexua9SHaeHz+3V8QAbz0a+UC1T5sIjvY="
|
||||
},
|
||||
"N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t": {
|
||||
"name": "wayland",
|
||||
|
|
@ -134,11 +139,6 @@
|
|||
"url": "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
|
||||
"hash": "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg="
|
||||
},
|
||||
"N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA": {
|
||||
"name": "wayland_protocols",
|
||||
"url": "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz",
|
||||
"hash": "sha256-3S3xSrX0EDgleq7cxLX7msDuAY8/D5SvkJcCjmDTMiM="
|
||||
},
|
||||
"N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs": {
|
||||
"name": "wuffs",
|
||||
"url": "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz",
|
||||
|
|
@ -147,32 +147,32 @@
|
|||
"z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ": {
|
||||
"name": "z2d",
|
||||
"url": "https://deps.files.ghostty.org/z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ.tar.gz",
|
||||
"hash": "sha256-qD+XexnAjSanRAwr5ZIaPY1aQhNW5DFVJ4PYLwhIr2E="
|
||||
"hash": "sha256-afIdou/V7gk3/lXE0J5Ir8T7L5GgHvFnyMJ1rgRnl/c="
|
||||
},
|
||||
"zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh": {
|
||||
"name": "zf",
|
||||
"url": "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz",
|
||||
"hash": "sha256-BfAZILill3I/nBf1oWwol77N34Jcpm4hudC+XSeMgZY="
|
||||
"hash": "sha256-OwFdkorwTp4mJyvBXrTbtNmp1GnrbSkKDdrmc7d8RWg="
|
||||
},
|
||||
"zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi": {
|
||||
"name": "zig_js",
|
||||
"url": "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz",
|
||||
"hash": "sha256-r6GdXwrv+jTu0AkTlyN/FuO+N4X+l20gsbS59wrE7V4="
|
||||
"hash": "sha256-TCAY5WAV05UEuAkDhq2c6Tk/ODgAhdnDI3O/flb8c6M="
|
||||
},
|
||||
"zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK": {
|
||||
"name": "zig_objc",
|
||||
"url": "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz",
|
||||
"hash": "sha256-jWFQ5BrV880qqa9KypltWuRLqNSh21rDxt6Jxp0EoMM="
|
||||
"hash": "sha256-3YSvc3YlNW/NciyzCQnzsujXAmZ89XlxSqfqvArAjsw="
|
||||
},
|
||||
"wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe": {
|
||||
"name": "zig_wayland",
|
||||
"url": "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz",
|
||||
"hash": "sha256-1wRkixysjdFMyrATxlXdukAc34MwfNj0B6ydYVn+UKw="
|
||||
"hash": "sha256-TxRrc17Q1Sf1IOO/cdPpP3LD0PpYOujt06SFH3B5Ek4="
|
||||
},
|
||||
"zigimg-0.1.0-8_eo2vHnEwCIVW34Q14Ec-xUlzIoVg86-7FU2ypPtxms": {
|
||||
"name": "zigimg",
|
||||
"url": "https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz",
|
||||
"hash": "sha256-vkcTloGX+vRw7e6GYJLO9eocYaEOYjXYE0dT7jscZ4A="
|
||||
"hash": "sha256-LB7Xa6KzVRRUSwwnyWM+y6fDG+kIDjfnoBDJO1obxVM="
|
||||
},
|
||||
"N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o": {
|
||||
"name": "zlib",
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@
|
|||
{
|
||||
lib,
|
||||
linkFarm,
|
||||
fetchzip,
|
||||
fetchurl,
|
||||
fetchgit,
|
||||
runCommandLocal,
|
||||
zig_0_15,
|
||||
zstd,
|
||||
name ? "zig-packages",
|
||||
}: let
|
||||
unpackZigArtifact = {
|
||||
|
|
@ -19,7 +17,7 @@
|
|||
nativeBuildInputs = [zig_0_15];
|
||||
}
|
||||
''
|
||||
hash="$(cd "$TMPDIR" && zig fetch --global-cache-dir "$TMPDIR" ${artifact})"
|
||||
hash="$(zig fetch --global-cache-dir "$TMPDIR" ${artifact})"
|
||||
mv "$TMPDIR/p/$hash" "$out"
|
||||
chmod 755 "$out"
|
||||
'';
|
||||
|
|
@ -28,16 +26,8 @@
|
|||
name,
|
||||
url,
|
||||
hash,
|
||||
unpack,
|
||||
}: let
|
||||
artifact =
|
||||
if unpack
|
||||
then
|
||||
fetchzip {
|
||||
inherit url hash;
|
||||
nativeBuildInputs = [zstd];
|
||||
}
|
||||
else fetchurl {inherit url hash;};
|
||||
artifact = fetchurl {inherit url hash;};
|
||||
in
|
||||
unpackZigArtifact {inherit name artifact;};
|
||||
|
||||
|
|
@ -66,7 +56,6 @@
|
|||
name,
|
||||
url,
|
||||
hash,
|
||||
unpack,
|
||||
}: let
|
||||
parts = lib.splitString "://" url;
|
||||
proto = builtins.elemAt parts 0;
|
||||
|
|
@ -81,11 +70,11 @@
|
|||
url = "https://${path}";
|
||||
};
|
||||
http = fetchZig {
|
||||
inherit name hash unpack;
|
||||
inherit name hash;
|
||||
url = "http://${path}";
|
||||
};
|
||||
https = fetchZig {
|
||||
inherit name hash unpack;
|
||||
inherit name hash;
|
||||
url = "https://${path}";
|
||||
};
|
||||
};
|
||||
|
|
@ -99,7 +88,6 @@ in
|
|||
name = "bindings";
|
||||
url = "https://deps.files.ghostty.org/DearBindings_v0.17_ImGui_v1.92.5-docking.tar.gz";
|
||||
hash = "sha256-i/7FAOAJJvZ5hT7iPWfMOS08MYFzPKRwRzhlHT9wuqM=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -108,7 +96,6 @@ in
|
|||
name = "breakpad";
|
||||
url = "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz";
|
||||
hash = "sha256-bMqYlD0amQdmzvYQd8Ca/1k4Bj/heh7+EijlQSttatk=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -117,7 +104,6 @@ in
|
|||
name = "fontconfig";
|
||||
url = "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz";
|
||||
hash = "sha256-O6LdkhWHGKzsXKrxpxYEO1qgVcJ7CB2RSvPMtA3OilU=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -126,7 +112,6 @@ in
|
|||
name = "freetype";
|
||||
url = "https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz";
|
||||
hash = "sha256-QnIB9dUVFnDQXB9bRb713aHy592XHvVPD+qqf/0quQw=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -135,7 +120,6 @@ in
|
|||
name = "gettext";
|
||||
url = "https://deps.files.ghostty.org/gettext-0.24.tar.gz";
|
||||
hash = "sha256-yRhQPVk9cNr0hE0XWhPYFq+stmfAb7oeydzVACwVGLc=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -144,7 +128,6 @@ in
|
|||
name = "glslang";
|
||||
url = "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz";
|
||||
hash = "sha256-FKLtu1Ccs+UamlPj9eQ12/WXFgS0uDPmPmB26MCpl7U=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -152,8 +135,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "gobject";
|
||||
url = "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst";
|
||||
hash = "sha256-OxS9/XC5aMJj1KhOcFP1ZZN7PI4ADw4f7ocx6V64mOc=";
|
||||
unpack = true;
|
||||
hash = "sha256-2b1DBvAIHY5LhItq3+q9L6tJgi7itnnrSAHc7fXWDEg=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -162,7 +144,6 @@ in
|
|||
name = "gtk4_layer_shell";
|
||||
url = "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz";
|
||||
hash = "sha256-mChCgSYKXu9bT2OlXxbEv2p4ihAgptsDfssPcfozaYg=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -171,7 +152,6 @@ in
|
|||
name = "harfbuzz";
|
||||
url = "https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz";
|
||||
hash = "sha256-8WNRuv4hRyX+LB1bWfDZPkmQWkskeJn7kNcM/5U6K5s=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -180,7 +160,6 @@ in
|
|||
name = "highway";
|
||||
url = "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz";
|
||||
hash = "sha256-h9T4iT704I8iSXNgj/6/lCaKgTgLp5wS6IQZaMgKohI=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -189,16 +168,14 @@ in
|
|||
name = "imgui";
|
||||
url = "https://github.com/ocornut/imgui/archive/refs/tags/v1.92.5-docking.tar.gz";
|
||||
hash = "sha256-yBbCDox18+Fa6Gc1DnmSVQLRpqhZOLsac7iSfl8x+cs=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "N-V-__8AAGi9AwC7QV7hLqjN6iBkXA2y5dxw285nkSLlVB7I";
|
||||
name = "N-V-__8AABVbAwBwDRyZONfx553tvMW8_A2OKUoLzPUSRiLF";
|
||||
path = fetchZigArtifact {
|
||||
name = "iterm2_themes";
|
||||
url = "https://deps.files.ghostty.org/ghostty-themes-release-20260525-155808-7335c0a.tgz";
|
||||
hash = "sha256-HGujRdQdWtVIf3GwCgQgjV9lbwWxJSIDJOWq3gOX3kU=";
|
||||
unpack = false;
|
||||
url = "https://deps.files.ghostty.org/ghostty-themes-release-20260216-151611-fc73ce3.tgz";
|
||||
hash = "sha256-FCALuGoMgUq2lgnVALKAs5a20uuDXt8Gdt5KeJwKqP0=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -207,7 +184,6 @@ in
|
|||
name = "jetbrains_mono";
|
||||
url = "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz";
|
||||
hash = "sha256-xXppHouCrQmLWWPzlZAy5AOPORCHr3cViFulkEYQXMQ=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -216,7 +192,6 @@ in
|
|||
name = "libpng";
|
||||
url = "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz";
|
||||
hash = "sha256-/syVtGzwXo4/yKQUdQ4LparQDYnp/fF16U/wQcrxoDo=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -224,8 +199,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "libxev";
|
||||
url = "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz";
|
||||
hash = "sha256-1B9oJExVyOWRj+Y9d9eHkOBTlOYuEkcwGBUKdlgRhkg=";
|
||||
unpack = true;
|
||||
hash = "sha256-YAPqa5bkpRihKPkyMn15oRvTCZaxO3O66ymRY3lIfdc=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -234,7 +208,6 @@ in
|
|||
name = "libxml2";
|
||||
url = "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz";
|
||||
hash = "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -243,7 +216,6 @@ in
|
|||
name = "nerd_fonts_symbols_only";
|
||||
url = "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz";
|
||||
hash = "sha256-EWTRuVbUveJI17LwmYxDzJT1ICQxoVZKeTiVsec7DQQ=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -252,7 +224,6 @@ in
|
|||
name = "oniguruma";
|
||||
url = "https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz";
|
||||
hash = "sha256-ABqhIC54RI9MC/GkjHblVodrNvFtks4yB+zP1h2Z8qA=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -261,7 +232,6 @@ in
|
|||
name = "pixels";
|
||||
url = "https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz";
|
||||
hash = "sha256-Veg7FtCRCCUCvxSb9FfzH0IJLFmCZQ4/+657SIcb8Ro=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -270,7 +240,6 @@ in
|
|||
name = "plasma_wayland_protocols";
|
||||
url = "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz";
|
||||
hash = "sha256-XFi6IUrNjmvKNCbcCLAixGqN2Zeymhs+KLrfccIN9EE=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -279,7 +248,6 @@ in
|
|||
name = "sentry";
|
||||
url = "https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz";
|
||||
hash = "sha256-KsZJfMjWGo0xCT5HrduMmyxFsWsHBbszSoNbZCPDGN8=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -288,7 +256,14 @@ in
|
|||
name = "spirv_cross";
|
||||
url = "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz";
|
||||
hash = "sha256-tStvz8Ref6abHwahNiwVVHNETizAmZVVaxVsU7pmV+M=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH";
|
||||
path = fetchZigArtifact {
|
||||
name = "utfcpp";
|
||||
url = "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz";
|
||||
hash = "sha256-/8ZooxDndgfTk/PBizJxXyI9oerExNbgV5oR345rWc8=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -297,7 +272,6 @@ in
|
|||
name = "uucode";
|
||||
url = "git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732";
|
||||
hash = "sha256-sHPh+TQSdUGus/QTbj7KSJJkTuNTrK4VNmQDjS30Lf8=";
|
||||
unpack = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -305,8 +279,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "uucode";
|
||||
url = "https://deps.files.ghostty.org/uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9.tar.gz";
|
||||
hash = "sha256-jLrhrmCXQ1T+LQP1JTBBB3Jn+1hCZfODbC4SdlfNdKg=";
|
||||
unpack = true;
|
||||
hash = "sha256-0KvuD0+L1urjwFF3fhbnxC2JZKqqAVWRxOVlcD9GX5U=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -314,8 +287,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "vaxis";
|
||||
url = "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz";
|
||||
hash = "sha256-zTyrZrIffM+GJIt973tKDeWHmOCwbn7KLDdQxSiK00Y=";
|
||||
unpack = true;
|
||||
hash = "sha256-LnIzK8icW1Qexua9SHaeHz+3V8QAbz0a+UC1T5sIjvY=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -324,7 +296,6 @@ in
|
|||
name = "wayland";
|
||||
url = "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz";
|
||||
hash = "sha256-6kGR1o5DdnflHzqs3ieCmBAUTpMdOXoyfcYDXiw5xQ0=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -333,16 +304,6 @@ in
|
|||
name = "wayland_protocols";
|
||||
url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz";
|
||||
hash = "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA";
|
||||
path = fetchZigArtifact {
|
||||
name = "wayland_protocols";
|
||||
url = "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz";
|
||||
hash = "sha256-3S3xSrX0EDgleq7cxLX7msDuAY8/D5SvkJcCjmDTMiM=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -351,7 +312,6 @@ in
|
|||
name = "wuffs";
|
||||
url = "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz";
|
||||
hash = "sha256-nkzSCr6W5sTG7enDBXEIhgEm574uLD41UVR2wlC+HBM=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -359,8 +319,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "z2d";
|
||||
url = "https://deps.files.ghostty.org/z2d-0.10.0-j5P_Hu-6FgBsZNgwphIqh17jDnj8_yPtD8yzjO6PpHRQ.tar.gz";
|
||||
hash = "sha256-qD+XexnAjSanRAwr5ZIaPY1aQhNW5DFVJ4PYLwhIr2E=";
|
||||
unpack = true;
|
||||
hash = "sha256-afIdou/V7gk3/lXE0J5Ir8T7L5GgHvFnyMJ1rgRnl/c=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -368,8 +327,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "zf";
|
||||
url = "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz";
|
||||
hash = "sha256-BfAZILill3I/nBf1oWwol77N34Jcpm4hudC+XSeMgZY=";
|
||||
unpack = true;
|
||||
hash = "sha256-OwFdkorwTp4mJyvBXrTbtNmp1GnrbSkKDdrmc7d8RWg=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -377,8 +335,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "zig_js";
|
||||
url = "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz";
|
||||
hash = "sha256-r6GdXwrv+jTu0AkTlyN/FuO+N4X+l20gsbS59wrE7V4=";
|
||||
unpack = true;
|
||||
hash = "sha256-TCAY5WAV05UEuAkDhq2c6Tk/ODgAhdnDI3O/flb8c6M=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -386,8 +343,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "zig_objc";
|
||||
url = "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz";
|
||||
hash = "sha256-jWFQ5BrV880qqa9KypltWuRLqNSh21rDxt6Jxp0EoMM=";
|
||||
unpack = true;
|
||||
hash = "sha256-3YSvc3YlNW/NciyzCQnzsujXAmZ89XlxSqfqvArAjsw=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -395,8 +351,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "zig_wayland";
|
||||
url = "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz";
|
||||
hash = "sha256-1wRkixysjdFMyrATxlXdukAc34MwfNj0B6ydYVn+UKw=";
|
||||
unpack = true;
|
||||
hash = "sha256-TxRrc17Q1Sf1IOO/cdPpP3LD0PpYOujt06SFH3B5Ek4=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -404,8 +359,7 @@ in
|
|||
path = fetchZigArtifact {
|
||||
name = "zigimg";
|
||||
url = "https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz";
|
||||
hash = "sha256-vkcTloGX+vRw7e6GYJLO9eocYaEOYjXYE0dT7jscZ4A=";
|
||||
unpack = true;
|
||||
hash = "sha256-LB7Xa6KzVRRUSwwnyWM+y6fDG+kIDjfnoBDJO1obxVM=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -414,7 +368,6 @@ in
|
|||
name = "zlib";
|
||||
url = "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz";
|
||||
hash = "sha256-F+iIY/NgBnKrSRgvIXKBtvxNPHYr3jYZNeQ2qVIU0Fw=";
|
||||
unpack = false;
|
||||
};
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918
|
|||
https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz
|
||||
https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz
|
||||
https://deps.files.ghostty.org/gettext-0.24.tar.gz
|
||||
https://deps.files.ghostty.org/ghostty-themes-release-20260525-155808-7335c0a.tgz
|
||||
https://deps.files.ghostty.org/ghostty-themes-release-20260216-151611-fc73ce3.tgz
|
||||
https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz
|
||||
https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst
|
||||
https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz
|
||||
|
|
@ -20,6 +20,7 @@ https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d8
|
|||
https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz
|
||||
https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz
|
||||
https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz
|
||||
https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz
|
||||
https://deps.files.ghostty.org/uucode-0.2.0-ZZjBPqZVVABQepOqZHR7vV_NcaN-wats0IB6o-Exj6m9.tar.gz
|
||||
https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz
|
||||
https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz
|
||||
|
|
@ -33,4 +34,3 @@ https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e
|
|||
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
|
||||
https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz
|
||||
https://github.com/ocornut/imgui/archive/refs/tags/v1.92.5-docking.tar.gz
|
||||
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
# GhosttyZigCompiler.cmake — set up zig cc as a cross compiler
|
||||
#
|
||||
# Provides ghostty_zig_compiler() which configures zig cc / zig c++ as
|
||||
# the C/CXX compiler for a given Zig target triple. It creates small
|
||||
# wrapper scripts (shell on Unix, .cmd on Windows) and sets the
|
||||
# following CMake variables in the caller's scope:
|
||||
#
|
||||
# CMAKE_C_COMPILER, CMAKE_CXX_COMPILER,
|
||||
# CMAKE_C_COMPILER_FORCED, CMAKE_CXX_COMPILER_FORCED,
|
||||
# CMAKE_SYSTEM_NAME, CMAKE_EXECUTABLE_SUFFIX (Windows only)
|
||||
#
|
||||
# This file is self-contained with no dependencies on the ghostty
|
||||
# source tree. Copy it into your project and include it directly.
|
||||
# It cannot be consumed via FetchContent because it must run before
|
||||
# project(), but FetchContent_MakeAvailable triggers project()
|
||||
# internally.
|
||||
#
|
||||
# Must be called BEFORE project() — CMake reads the compiler variables
|
||||
# at project() time and won't re-detect after that.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# cmake_minimum_required(VERSION 3.19)
|
||||
#
|
||||
# include(cmake/GhosttyZigCompiler.cmake)
|
||||
# ghostty_zig_compiler(ZIG_TARGET x86_64-linux-gnu)
|
||||
#
|
||||
# project(myapp LANGUAGES C CXX)
|
||||
#
|
||||
# FetchContent_MakeAvailable(ghostty)
|
||||
# ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu)
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt-static-linux-amd64)
|
||||
#
|
||||
# See example/c-vt-cmake-cross/ for a complete working example.
|
||||
|
||||
include_guard(GLOBAL)
|
||||
|
||||
function(ghostty_zig_compiler)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 _GZC "" "ZIG_TARGET" "")
|
||||
|
||||
if(NOT _GZC_ZIG_TARGET)
|
||||
message(FATAL_ERROR "ghostty_zig_compiler: ZIG_TARGET is required")
|
||||
endif()
|
||||
|
||||
find_program(_GZC_ZIG zig REQUIRED)
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(_cc "${CMAKE_CURRENT_BINARY_DIR}/zig-cc.cmd")
|
||||
set(_cxx "${CMAKE_CURRENT_BINARY_DIR}/zig-cxx.cmd")
|
||||
file(WRITE "${_cc}" "@\"${_GZC_ZIG}\" cc -target ${_GZC_ZIG_TARGET} %*\n")
|
||||
file(WRITE "${_cxx}" "@\"${_GZC_ZIG}\" c++ -target ${_GZC_ZIG_TARGET} %*\n")
|
||||
else()
|
||||
set(_cc "${CMAKE_CURRENT_BINARY_DIR}/zig-cc")
|
||||
set(_cxx "${CMAKE_CURRENT_BINARY_DIR}/zig-c++")
|
||||
file(WRITE "${_cc}" "#!/bin/sh\nexec \"${_GZC_ZIG}\" cc -target ${_GZC_ZIG_TARGET} \"$@\"\n")
|
||||
file(WRITE "${_cxx}" "#!/bin/sh\nexec \"${_GZC_ZIG}\" c++ -target ${_GZC_ZIG_TARGET} \"$@\"\n")
|
||||
file(CHMOD "${_cc}" "${_cxx}"
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_COMPILER "${_cc}" PARENT_SCOPE)
|
||||
set(CMAKE_CXX_COMPILER "${_cxx}" PARENT_SCOPE)
|
||||
set(CMAKE_C_COMPILER_FORCED TRUE PARENT_SCOPE)
|
||||
set(CMAKE_CXX_COMPILER_FORCED TRUE PARENT_SCOPE)
|
||||
|
||||
if(_GZC_ZIG_TARGET MATCHES "windows")
|
||||
set(CMAKE_SYSTEM_NAME Windows PARENT_SCOPE)
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".exe" PARENT_SCOPE)
|
||||
elseif(_GZC_ZIG_TARGET MATCHES "linux")
|
||||
set(CMAKE_SYSTEM_NAME Linux PARENT_SCOPE)
|
||||
elseif(_GZC_ZIG_TARGET MATCHES "darwin|macos")
|
||||
set(CMAKE_SYSTEM_NAME Darwin PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
# CMake Support for libghostty-vt
|
||||
|
||||
The top-level `CMakeLists.txt` wraps the Zig build system so that CMake
|
||||
projects can consume libghostty-vt without invoking `zig build` manually.
|
||||
Running `cmake --build` triggers `zig build -Demit-lib-vt` automatically.
|
||||
|
||||
This means downstream projects do require a working Zig compiler on
|
||||
`PATH` to build, but don't need to know any Zig-specific details.
|
||||
|
||||
## Using FetchContent (recommended)
|
||||
|
||||
Add the following to your project's `CMakeLists.txt`:
|
||||
|
||||
```cmake
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(ghostty
|
||||
GIT_REPOSITORY https://github.com/ghostty-org/ghostty.git
|
||||
GIT_TAG main
|
||||
)
|
||||
FetchContent_MakeAvailable(ghostty)
|
||||
|
||||
add_executable(myapp main.c)
|
||||
target_link_libraries(myapp PRIVATE ghostty-vt)
|
||||
```
|
||||
|
||||
This fetches the Ghostty source, builds libghostty-vt via Zig during your
|
||||
CMake build, and links it into your target. Headers are added to the
|
||||
include path automatically.
|
||||
|
||||
### Using a local checkout
|
||||
|
||||
If you already have the Ghostty source checked out, skip the download by
|
||||
pointing CMake at it:
|
||||
|
||||
```shell-session
|
||||
cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=/path/to/ghostty
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
## Using find_package (install-based)
|
||||
|
||||
Build and install libghostty-vt first:
|
||||
|
||||
```shell-session
|
||||
cd /path/to/ghostty
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
cmake --install build --prefix /usr/local
|
||||
```
|
||||
|
||||
Then in your project:
|
||||
|
||||
```cmake
|
||||
find_package(ghostty-vt REQUIRED)
|
||||
|
||||
add_executable(myapp main.c)
|
||||
target_link_libraries(myapp PRIVATE ghostty-vt::ghostty-vt)
|
||||
```
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
For cross-compiling to a different Zig target triple, use
|
||||
`ghostty_vt_add_target()` after `FetchContent_MakeAvailable`:
|
||||
|
||||
```cmake
|
||||
FetchContent_MakeAvailable(ghostty)
|
||||
ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu)
|
||||
|
||||
add_executable(myapp main.c)
|
||||
target_link_libraries(myapp PRIVATE ghostty-vt-static-linux-amd64)
|
||||
```
|
||||
|
||||
### Using zig cc as the C/CXX compiler
|
||||
|
||||
When cross-compiling, the host C compiler can't link binaries for the
|
||||
target platform. `GhosttyZigCompiler.cmake` provides
|
||||
`ghostty_zig_compiler()` to set up `zig cc` as the C/CXX compiler for
|
||||
the cross target. It creates wrapper scripts (shell on Unix, `.cmd` on
|
||||
Windows) and configures `CMAKE_C_COMPILER`, `CMAKE_CXX_COMPILER`, and
|
||||
`CMAKE_SYSTEM_NAME`.
|
||||
|
||||
The module is self-contained — copy it into your project (e.g. to
|
||||
`cmake/`) and include it directly. It cannot be consumed via
|
||||
FetchContent because it must run before `project()`, but
|
||||
`FetchContent_MakeAvailable` triggers `project()` internally:
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
include(cmake/GhosttyZigCompiler.cmake)
|
||||
ghostty_zig_compiler(ZIG_TARGET x86_64-linux-gnu)
|
||||
|
||||
project(myapp LANGUAGES C CXX)
|
||||
|
||||
FetchContent_MakeAvailable(ghostty)
|
||||
ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu)
|
||||
|
||||
add_executable(myapp main.c)
|
||||
target_link_libraries(myapp PRIVATE ghostty-vt-static-linux-amd64)
|
||||
```
|
||||
|
||||
See `example/c-vt-cmake-cross/` for a complete working example.
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
set(_ghostty_vt_libdir "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
|
||||
|
||||
# Shared library target
|
||||
if(NOT TARGET ghostty-vt::ghostty-vt)
|
||||
add_library(ghostty-vt::ghostty-vt SHARED IMPORTED)
|
||||
|
||||
if(WIN32)
|
||||
set(_ghostty_vt_shared_location "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_BINDIR@/@GHOSTTY_VT_REALNAME@")
|
||||
else()
|
||||
set(_ghostty_vt_shared_location "${_ghostty_vt_libdir}/@GHOSTTY_VT_REALNAME@")
|
||||
endif()
|
||||
|
||||
set_target_properties(ghostty-vt::ghostty-vt PROPERTIES
|
||||
IMPORTED_LOCATION "${_ghostty_vt_shared_location}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@"
|
||||
)
|
||||
unset(_ghostty_vt_shared_location)
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(ghostty-vt::ghostty-vt PROPERTIES
|
||||
IMPORTED_SONAME "@rpath/@GHOSTTY_VT_SONAME@"
|
||||
INTERFACE_LINK_DIRECTORIES "${_ghostty_vt_libdir}"
|
||||
)
|
||||
# Ensure consumers can find the @rpath dylib at runtime
|
||||
set_property(TARGET ghostty-vt::ghostty-vt APPEND PROPERTY
|
||||
INTERFACE_LINK_OPTIONS "LINKER:-rpath,${_ghostty_vt_libdir}"
|
||||
)
|
||||
elseif(WIN32)
|
||||
set_target_properties(ghostty-vt::ghostty-vt PROPERTIES
|
||||
IMPORTED_IMPLIB "${_ghostty_vt_libdir}/@GHOSTTY_VT_IMPLIB@"
|
||||
)
|
||||
else()
|
||||
set_target_properties(ghostty-vt::ghostty-vt PROPERTIES
|
||||
IMPORTED_SONAME "@GHOSTTY_VT_SONAME@"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Static library target
|
||||
#
|
||||
# Consumers must link transitive dependencies themselves. By default (with
|
||||
# SIMD enabled): libc, libc++ (or libstdc++ on Linux), highway, and
|
||||
# simdutf. Building with -Dsimd=false removes the C++ / highway / simdutf
|
||||
# dependencies.
|
||||
if(NOT TARGET ghostty-vt::ghostty-vt-static)
|
||||
add_library(ghostty-vt::ghostty-vt-static STATIC IMPORTED)
|
||||
|
||||
set_target_properties(ghostty-vt::ghostty-vt-static PROPERTIES
|
||||
IMPORTED_LOCATION "${_ghostty_vt_libdir}/@GHOSTTY_VT_STATIC_REALNAME@"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@"
|
||||
)
|
||||
if(WIN32)
|
||||
set_target_properties(ghostty-vt::ghostty-vt-static PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "ntdll;kernel32"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
unset(_ghostty_vt_libdir)
|
||||
|
||||
check_required_components(ghostty-vt)
|
||||
|
|
@ -7,4 +7,5 @@ Actions=RunGhosttyDir
|
|||
[Desktop Action RunGhosttyDir]
|
||||
Name=Open Ghostty Here
|
||||
Icon=com.mitchellh.ghostty
|
||||
Exec=ghostty +new-window --working-directory=%F
|
||||
Exec=ghostty --working-directory=%F --gtk-single-instance=false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,3 @@
|
|||
dist/
|
||||
node_modules/
|
||||
example.wasm*
|
||||
build/
|
||||
.build/
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
# Example Libghostty Projects
|
||||
|
||||
Each example is a standalone project with its own `build.zig`,
|
||||
`build.zig.zon`, `README.md`, and `src/main.c` (or `.zig`). Examples are
|
||||
auto-discovered by CI via `example/*/build.zig.zon`, so no workflow file
|
||||
edits are needed when adding a new example.
|
||||
|
||||
## Adding a New Example
|
||||
|
||||
1. Copy an existing example directory (e.g., `c-vt-encode-focus/`) as a
|
||||
starting point.
|
||||
2. Update `build.zig.zon`: change `.name`, generate a **new unique**
|
||||
`.fingerprint` value (a random `u64` hex literal), and keep
|
||||
`.minimum_zig_version` matching the others.
|
||||
3. Update `build.zig`: change the executable `.name` to match the directory.
|
||||
4. Write a `README.md` following the existing format.
|
||||
|
||||
## Doxygen Snippet Tags
|
||||
|
||||
Example source files use Doxygen `@snippet` tags so the corresponding
|
||||
header in `include/ghostty/vt/` can reference them. Wrap the relevant
|
||||
code with `//! [snippet-name]` markers:
|
||||
|
||||
```c
|
||||
//! [my-snippet]
|
||||
int main() { ... }
|
||||
//! [my-snippet]
|
||||
```
|
||||
|
||||
The header then uses `@snippet <dir>/src/main.c my-snippet` instead of
|
||||
inline `@code` blocks. Never duplicate example code inline in the
|
||||
headers — always use `@snippet`. When modifying example code, keep the
|
||||
snippet markers in sync with the headers in `include/ghostty/vt/`.
|
||||
|
||||
## Conventions
|
||||
|
||||
- Executable names use underscores: `c_vt_encode_focus` (not hyphens).
|
||||
- All C examples link `ghostty-vt` via `lazyDependency("ghostty", ...)`.
|
||||
- `build.zig` files follow a common template — keep them consistent.
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Examples
|
||||
|
||||
Standalone projects demonstrating the Ghostty library APIs.
|
||||
The directories starting with `c-` use the C API and the directories
|
||||
starting with `zig-` use the Zig API.
|
||||
|
||||
Every example can be built and run using `zig build` and `zig build run`
|
||||
from within the respective example directory.
|
||||
Even the C API examples use the Zig build system (not the language) to
|
||||
build the project.
|
||||
|
||||
## Running an Example
|
||||
|
||||
```shell-session
|
||||
cd example/<dir>
|
||||
zig build run
|
||||
```
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Example: `ghostty-vt` Build Info
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` build info
|
||||
API to query compile-time build configuration.
|
||||
|
||||
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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_build_info",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_build_info,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0xc6b57ed4f83fb16,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [build-info-query]
|
||||
void query_build_info() {
|
||||
bool simd = false;
|
||||
bool kitty_graphics = false;
|
||||
bool tmux_control_mode = false;
|
||||
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_SIMD, &simd);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_KITTY_GRAPHICS, &kitty_graphics);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_TMUX_CONTROL_MODE, &tmux_control_mode);
|
||||
|
||||
printf("SIMD: %s\n", simd ? "enabled" : "disabled");
|
||||
printf("Kitty graphics: %s\n", kitty_graphics ? "enabled" : "disabled");
|
||||
printf("Tmux control mode: %s\n", tmux_control_mode ? "enabled" : "disabled");
|
||||
|
||||
GhosttyString version_string = {0};
|
||||
size_t version_major = 0;
|
||||
size_t version_minor = 0;
|
||||
size_t version_patch = 0;
|
||||
GhosttyString version_pre = {0};
|
||||
GhosttyString version_build = {0};
|
||||
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_STRING, &version_string);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_MAJOR, &version_major);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_MINOR, &version_minor);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_PATCH, &version_patch);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_PRE, &version_pre);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_BUILD, &version_build);
|
||||
|
||||
printf("Version: %.*s\n", (int)version_string.len, version_string.ptr);
|
||||
printf("Version major: %zu\n", version_major);
|
||||
printf("Version minor: %zu\n", version_minor);
|
||||
printf("Version patch: %zu\n", version_patch);
|
||||
if (version_pre.len > 0) {
|
||||
printf("Version pre : %.*s\n", (int)version_pre.len, version_pre.ptr);
|
||||
} else {
|
||||
printf("Version pre : (none)\n");
|
||||
}
|
||||
if (version_build.len > 0) {
|
||||
printf("Version build: %.*s\n", (int)version_build.len, version_build.ptr);
|
||||
} else {
|
||||
printf("Version build: (none)\n");
|
||||
}
|
||||
}
|
||||
//! [build-info-query]
|
||||
|
||||
int main() {
|
||||
query_build_info();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# --- Determine cross-compilation target before project() --------------------
|
||||
#
|
||||
# We need to know the target before project() so we can set up zig cc as the
|
||||
# C/C++ compiler for the cross target.
|
||||
|
||||
# Pick a cross-compilation target: build for a different OS than the host.
|
||||
# Can be overridden with -DZIG_TARGET=... on the command line.
|
||||
if(NOT ZIG_TARGET)
|
||||
# CMAKE_HOST_SYSTEM_PROCESSOR may not be set before project(), so
|
||||
# fall back to `uname -m`.
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR)
|
||||
set(_arch "${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
else()
|
||||
execute_process(COMMAND uname -m OUTPUT_VARIABLE _arch OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
if(_arch MATCHES "^(x86_64|AMD64)$")
|
||||
set(_arch "x86_64")
|
||||
elseif(_arch MATCHES "^(aarch64|arm64|ARM64)$")
|
||||
set(_arch "aarch64")
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(ZIG_TARGET "${_arch}-windows-gnu")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(ZIG_TARGET "${_arch}-linux-gnu")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(ZIG_TARGET "${_arch}-linux-gnu")
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Cannot derive ZIG_TARGET for ${CMAKE_HOST_SYSTEM_NAME}. "
|
||||
"Pass -DZIG_TARGET=... manually.")
|
||||
endif()
|
||||
|
||||
message(STATUS "Cross-compiling for ZIG_TARGET: ${ZIG_TARGET}")
|
||||
endif()
|
||||
|
||||
# --- Set up zig cc as the cross compiler ------------------------------------
|
||||
|
||||
# GhosttyZigCompiler.cmake must be called before project().
|
||||
# Downstream projects would copy this file into their tree; here we
|
||||
# include it directly from the repo.
|
||||
include(../../dist/cmake/GhosttyZigCompiler.cmake)
|
||||
ghostty_zig_compiler(ZIG_TARGET "${ZIG_TARGET}")
|
||||
|
||||
project(c-vt-cmake-cross LANGUAGES C CXX)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(ghostty
|
||||
GIT_REPOSITORY https://github.com/ghostty-org/ghostty.git
|
||||
GIT_TAG main
|
||||
)
|
||||
FetchContent_MakeAvailable(ghostty)
|
||||
|
||||
ghostty_vt_add_target(NAME cross ZIG_TARGET "${ZIG_TARGET}")
|
||||
|
||||
add_executable(c_vt_cmake_cross src/main.c)
|
||||
target_link_libraries(c_vt_cmake_cross PRIVATE ghostty-vt-static-cross)
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# c-vt-cmake-cross
|
||||
|
||||
Demonstrates using `ghostty_vt_add_target()` to cross-compile
|
||||
libghostty-vt with static linking. The target OS is chosen automatically:
|
||||
|
||||
| Host | Target |
|
||||
| ------- | --------------- |
|
||||
| Linux | Windows (MinGW) |
|
||||
| Windows | Linux (glibc) |
|
||||
| macOS | Linux (glibc) |
|
||||
|
||||
Override with `-DZIG_TARGET=...` if needed.
|
||||
|
||||
## Building
|
||||
|
||||
```shell-session
|
||||
cd example/c-vt-cmake-cross
|
||||
cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=../..
|
||||
cmake --build build
|
||||
file build/c_vt_cmake_cross
|
||||
```
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
// Create a terminal with a small grid
|
||||
GhosttyTerminal terminal;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Write some VT-encoded content into the terminal
|
||||
const char *commands[] = {
|
||||
"Hello from a \033[1mCMake\033[0m-built program!\r\n",
|
||||
"Line 2: \033[4munderlined\033[0m text\r\n",
|
||||
"Line 3: \033[31mred\033[0m \033[32mgreen\033[0m \033[34mblue\033[0m\r\n",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t *)commands[i],
|
||||
strlen(commands[i]));
|
||||
}
|
||||
|
||||
// Format the terminal contents as plain text
|
||||
GhosttyFormatterTerminalOptions fmt_opts =
|
||||
GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
|
||||
fmt_opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
|
||||
fmt_opts.trim = true;
|
||||
|
||||
GhosttyFormatter formatter;
|
||||
result = ghostty_formatter_terminal_new(NULL, &formatter, terminal, fmt_opts);
|
||||
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);
|
||||
|
||||
printf("Plain text (%zu bytes):\n", len);
|
||||
fwrite(buf, 1, len, stdout);
|
||||
printf("\n");
|
||||
|
||||
ghostty_free(NULL, buf, len);
|
||||
ghostty_formatter_free(formatter);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.19)
|
||||
project(c-vt-cmake-static LANGUAGES C)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(ghostty
|
||||
GIT_REPOSITORY https://github.com/ghostty-org/ghostty.git
|
||||
GIT_TAG main
|
||||
)
|
||||
set(GHOSTTY_ZIG_BUILD_FLAGS "-Dsimd=false" CACHE STRING "" FORCE)
|
||||
FetchContent_MakeAvailable(ghostty)
|
||||
|
||||
add_executable(c_vt_cmake_static src/main.c)
|
||||
target_link_libraries(c_vt_cmake_static PRIVATE ghostty-vt-static)
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# c-vt-cmake-static
|
||||
|
||||
Demonstrates consuming libghostty-vt as a **static** library from a CMake
|
||||
project using `FetchContent`. Creates a terminal, writes VT sequences into
|
||||
it, and formats the screen contents as plain text.
|
||||
|
||||
## Building
|
||||
|
||||
```shell-session
|
||||
cd example/c-vt-cmake-static
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
./build/c_vt_cmake_static
|
||||
```
|
||||
|
||||
To build against a local checkout instead of fetching from GitHub:
|
||||
|
||||
```shell-session
|
||||
cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=../..
|
||||
cmake --build build
|
||||
```
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
// Create a terminal with a small grid
|
||||
GhosttyTerminal terminal;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Write some VT-encoded content into the terminal
|
||||
const char *commands[] = {
|
||||
"Hello from a \033[1mCMake\033[0m-built program (static)!\r\n",
|
||||
"Line 2: \033[4munderlined\033[0m text\r\n",
|
||||
"Line 3: \033[31mred\033[0m \033[32mgreen\033[0m \033[34mblue\033[0m\r\n",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t *)commands[i],
|
||||
strlen(commands[i]));
|
||||
}
|
||||
|
||||
// Format the terminal contents as plain text
|
||||
GhosttyFormatterTerminalOptions fmt_opts =
|
||||
GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
|
||||
fmt_opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
|
||||
fmt_opts.trim = true;
|
||||
|
||||
GhosttyFormatter formatter;
|
||||
result = ghostty_formatter_terminal_new(NULL, &formatter, terminal, fmt_opts);
|
||||
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);
|
||||
|
||||
printf("Plain text (%zu bytes):\n", len);
|
||||
fwrite(buf, 1, len, stdout);
|
||||
printf("\n");
|
||||
|
||||
ghostty_free(NULL, buf, len);
|
||||
ghostty_formatter_free(formatter);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.19)
|
||||
project(c-vt-cmake LANGUAGES C)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(ghostty
|
||||
GIT_REPOSITORY https://github.com/ghostty-org/ghostty.git
|
||||
GIT_TAG main
|
||||
)
|
||||
FetchContent_MakeAvailable(ghostty)
|
||||
|
||||
add_executable(c_vt_cmake src/main.c)
|
||||
target_link_libraries(c_vt_cmake PRIVATE ghostty-vt)
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# c-vt-cmake
|
||||
|
||||
Demonstrates consuming libghostty-vt from a CMake project using
|
||||
`FetchContent`. Creates a terminal, writes VT sequences into it, and
|
||||
formats the screen contents as plain text.
|
||||
|
||||
## Building
|
||||
|
||||
```shell-session
|
||||
cd example/c-vt-cmake
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
./build/c_vt_cmake
|
||||
```
|
||||
|
||||
To build against a local checkout instead of fetching from GitHub:
|
||||
|
||||
```shell-session
|
||||
cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=../..
|
||||
cmake --build build
|
||||
```
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
// Create a terminal with a small grid
|
||||
GhosttyTerminal terminal;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Write some VT-encoded content into the terminal
|
||||
const char *commands[] = {
|
||||
"Hello from a \033[1mCMake\033[0m-built program!\r\n",
|
||||
"Line 2: \033[4munderlined\033[0m text\r\n",
|
||||
"Line 3: \033[31mred\033[0m \033[32mgreen\033[0m \033[34mblue\033[0m\r\n",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t *)commands[i],
|
||||
strlen(commands[i]));
|
||||
}
|
||||
|
||||
// Format the terminal contents as plain text
|
||||
GhosttyFormatterTerminalOptions fmt_opts =
|
||||
GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
|
||||
fmt_opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
|
||||
fmt_opts.trim = true;
|
||||
|
||||
GhosttyFormatter formatter;
|
||||
result = ghostty_formatter_terminal_new(NULL, &formatter, terminal, fmt_opts);
|
||||
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);
|
||||
|
||||
printf("Plain text (%zu bytes):\n", len);
|
||||
fwrite(buf, 1, len, stdout);
|
||||
printf("\n");
|
||||
|
||||
ghostty_free(NULL, buf, len);
|
||||
ghostty_formatter_free(formatter);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Example: `ghostty-vt` Terminal Colors
|
||||
|
||||
This contains a simple example of how to set default terminal colors,
|
||||
read effective and default color values, and observe how OSC overrides
|
||||
layer on top of defaults using the `ghostty-vt` C library.
|
||||
|
||||
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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_colors",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_colors,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0xe7ec4247f16d4fce,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [colors-set-defaults]
|
||||
/// Set up a dark color theme with custom palette entries.
|
||||
void set_color_theme(GhosttyTerminal terminal) {
|
||||
// Set default foreground (light gray) and background (dark)
|
||||
GhosttyColorRgb fg = { .r = 0xDD, .g = 0xDD, .b = 0xDD };
|
||||
GhosttyColorRgb bg = { .r = 0x1E, .g = 0x1E, .b = 0x2E };
|
||||
GhosttyColorRgb cursor = { .r = 0xF5, .g = 0xE0, .b = 0xDC };
|
||||
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_COLOR_FOREGROUND, &fg);
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_COLOR_BACKGROUND, &bg);
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_COLOR_CURSOR, &cursor);
|
||||
|
||||
// Set a custom palette — start from the built-in default and override
|
||||
// the first 8 entries with a custom dark theme.
|
||||
GhosttyColorRgb palette[256];
|
||||
ghostty_terminal_get(terminal, GHOSTTY_TERMINAL_DATA_COLOR_PALETTE, palette);
|
||||
|
||||
palette[GHOSTTY_COLOR_NAMED_BLACK] = (GhosttyColorRgb){ 0x45, 0x47, 0x5A };
|
||||
palette[GHOSTTY_COLOR_NAMED_RED] = (GhosttyColorRgb){ 0xF3, 0x8B, 0xA8 };
|
||||
palette[GHOSTTY_COLOR_NAMED_GREEN] = (GhosttyColorRgb){ 0xA6, 0xE3, 0xA1 };
|
||||
palette[GHOSTTY_COLOR_NAMED_YELLOW] = (GhosttyColorRgb){ 0xF9, 0xE2, 0xAF };
|
||||
palette[GHOSTTY_COLOR_NAMED_BLUE] = (GhosttyColorRgb){ 0x89, 0xB4, 0xFA };
|
||||
palette[GHOSTTY_COLOR_NAMED_MAGENTA] = (GhosttyColorRgb){ 0xF5, 0xC2, 0xE7 };
|
||||
palette[GHOSTTY_COLOR_NAMED_CYAN] = (GhosttyColorRgb){ 0x94, 0xE2, 0xD5 };
|
||||
palette[GHOSTTY_COLOR_NAMED_WHITE] = (GhosttyColorRgb){ 0xBA, 0xC2, 0xDE };
|
||||
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_COLOR_PALETTE, palette);
|
||||
}
|
||||
//! [colors-set-defaults]
|
||||
|
||||
//! [colors-read]
|
||||
/// Print the effective and default values for a color, showing how
|
||||
/// OSC overrides layer on top of defaults.
|
||||
void print_color(GhosttyTerminal terminal,
|
||||
const char* name,
|
||||
GhosttyTerminalData effective_data,
|
||||
GhosttyTerminalData default_data) {
|
||||
GhosttyColorRgb color;
|
||||
|
||||
GhosttyResult res = ghostty_terminal_get(terminal, effective_data, &color);
|
||||
if (res == GHOSTTY_SUCCESS) {
|
||||
printf(" %-12s effective: #%02X%02X%02X", name, color.r, color.g, color.b);
|
||||
} else {
|
||||
printf(" %-12s effective: (not set)", name);
|
||||
}
|
||||
|
||||
res = ghostty_terminal_get(terminal, default_data, &color);
|
||||
if (res == GHOSTTY_SUCCESS) {
|
||||
printf(" default: #%02X%02X%02X\n", color.r, color.g, color.b);
|
||||
} else {
|
||||
printf(" default: (not set)\n");
|
||||
}
|
||||
}
|
||||
|
||||
void print_all_colors(GhosttyTerminal terminal, const char* label) {
|
||||
printf("%s:\n", label);
|
||||
print_color(terminal, "foreground",
|
||||
GHOSTTY_TERMINAL_DATA_COLOR_FOREGROUND,
|
||||
GHOSTTY_TERMINAL_DATA_COLOR_FOREGROUND_DEFAULT);
|
||||
print_color(terminal, "background",
|
||||
GHOSTTY_TERMINAL_DATA_COLOR_BACKGROUND,
|
||||
GHOSTTY_TERMINAL_DATA_COLOR_BACKGROUND_DEFAULT);
|
||||
print_color(terminal, "cursor",
|
||||
GHOSTTY_TERMINAL_DATA_COLOR_CURSOR,
|
||||
GHOSTTY_TERMINAL_DATA_COLOR_CURSOR_DEFAULT);
|
||||
|
||||
// Show palette index 0 (black) as an example
|
||||
GhosttyColorRgb palette[256];
|
||||
ghostty_terminal_get(terminal, GHOSTTY_TERMINAL_DATA_COLOR_PALETTE, palette);
|
||||
printf(" %-12s effective: #%02X%02X%02X", "palette[0]",
|
||||
palette[0].r, palette[0].g, palette[0].b);
|
||||
|
||||
ghostty_terminal_get(terminal, GHOSTTY_TERMINAL_DATA_COLOR_PALETTE_DEFAULT,
|
||||
palette);
|
||||
printf(" default: #%02X%02X%02X\n", palette[0].r, palette[0].g, palette[0].b);
|
||||
}
|
||||
//! [colors-read]
|
||||
|
||||
//! [colors-main]
|
||||
int main() {
|
||||
// Create a terminal
|
||||
GhosttyTerminal terminal = NULL;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
if (ghostty_terminal_new(NULL, &terminal, opts) != GHOSTTY_SUCCESS) {
|
||||
fprintf(stderr, "Failed to create terminal\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Before setting any colors, everything is unset
|
||||
print_all_colors(terminal, "Before setting defaults");
|
||||
|
||||
// Set our color theme defaults
|
||||
set_color_theme(terminal);
|
||||
print_all_colors(terminal, "\nAfter setting defaults");
|
||||
|
||||
// Simulate an OSC override (e.g. a program running inside the
|
||||
// terminal changes the foreground via OSC 10)
|
||||
const char* osc_fg = "\x1B]10;rgb:FF/00/00\x1B\\";
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t*)osc_fg,
|
||||
strlen(osc_fg));
|
||||
print_all_colors(terminal, "\nAfter OSC foreground override");
|
||||
|
||||
// Clear the foreground default — the OSC override is still active
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_COLOR_FOREGROUND, NULL);
|
||||
print_all_colors(terminal, "\nAfter clearing foreground default");
|
||||
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
//! [colors-main]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Example: `ghostty-vt` Terminal Effects
|
||||
|
||||
This contains a simple example of how to register and use terminal
|
||||
effect callbacks (`write_pty`, `bell`, `title_changed`) with the
|
||||
`ghostty-vt` C library.
|
||||
|
||||
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
|
||||
```
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_effects,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0xc02634cd65f5b583,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [effects-write-pty]
|
||||
void on_write_pty(GhosttyTerminal terminal,
|
||||
void* userdata,
|
||||
const uint8_t* data,
|
||||
size_t len) {
|
||||
(void)terminal;
|
||||
(void)userdata;
|
||||
printf(" write_pty (%zu bytes): ", len);
|
||||
fwrite(data, 1, len, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
//! [effects-write-pty]
|
||||
|
||||
//! [effects-bell]
|
||||
void on_bell(GhosttyTerminal terminal, void* userdata) {
|
||||
(void)terminal;
|
||||
int* count = (int*)userdata;
|
||||
(*count)++;
|
||||
printf(" bell! (count=%d)\n", *count);
|
||||
}
|
||||
//! [effects-bell]
|
||||
|
||||
//! [effects-title-changed]
|
||||
void on_title_changed(GhosttyTerminal terminal, void* userdata) {
|
||||
(void)userdata;
|
||||
// Query the cursor position to confirm the terminal processed the
|
||||
// title change (the title itself is tracked by the embedder via the
|
||||
// OSC parser or its own state).
|
||||
uint16_t col = 0;
|
||||
ghostty_terminal_get(terminal, GHOSTTY_TERMINAL_DATA_CURSOR_X, &col);
|
||||
printf(" title changed (cursor at col %u)\n", col);
|
||||
}
|
||||
//! [effects-title-changed]
|
||||
|
||||
//! [effects-register]
|
||||
int main() {
|
||||
// Create a terminal
|
||||
GhosttyTerminal terminal = NULL;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
if (ghostty_terminal_new(NULL, &terminal, opts) != GHOSTTY_SUCCESS) {
|
||||
fprintf(stderr, "Failed to create terminal\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set up userdata — a simple bell counter
|
||||
int bell_count = 0;
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_USERDATA, &bell_count);
|
||||
|
||||
// Register effect callbacks
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_WRITE_PTY,
|
||||
(const void *)on_write_pty);
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_BELL,
|
||||
(const void *)on_bell);
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_TITLE_CHANGED,
|
||||
(const void *)on_title_changed);
|
||||
|
||||
// Feed VT data that triggers effects:
|
||||
|
||||
// 1. Bell (BEL = 0x07)
|
||||
printf("Sending BEL:\n");
|
||||
const uint8_t bel = 0x07;
|
||||
ghostty_terminal_vt_write(terminal, &bel, 1);
|
||||
|
||||
// 2. Title change (OSC 2 ; <title> ST)
|
||||
printf("Sending title change:\n");
|
||||
const char* title_seq = "\x1B]2;Hello Effects\x1B\\";
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t*)title_seq,
|
||||
strlen(title_seq));
|
||||
|
||||
// 3. Device status report (DECRQM for wraparound mode ?7)
|
||||
// triggers write_pty with the response
|
||||
printf("Sending DECRQM query:\n");
|
||||
const char* decrqm = "\x1B[?7$p";
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t*)decrqm,
|
||||
strlen(decrqm));
|
||||
|
||||
// 4. Another bell to show the counter increments
|
||||
printf("Sending another BEL:\n");
|
||||
ghostty_terminal_vt_write(terminal, &bel, 1);
|
||||
|
||||
printf("Total bells: %d\n", bell_count);
|
||||
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
//! [effects-register]
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Example: `ghostty-vt` Encode Focus
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` focus
|
||||
encoding API to encode focus gained/lost events 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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_encode_focus",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_encode_focus,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0x89f01fd829fcc550,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [focus-encode]
|
||||
int main() {
|
||||
char buf[8];
|
||||
size_t written = 0;
|
||||
|
||||
GhosttyResult result = ghostty_focus_encode(
|
||||
GHOSTTY_FOCUS_GAINED, buf, sizeof(buf), &written);
|
||||
|
||||
if (result == GHOSTTY_SUCCESS) {
|
||||
printf("Encoded %zu bytes: ", written);
|
||||
fwrite(buf, 1, written, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//! [focus-encode]
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_encode_key",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [key-encode]
|
||||
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;
|
||||
}
|
||||
//! [key-encode]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Example: `ghostty-vt` C Mouse Encoding
|
||||
|
||||
This example demonstrates how to use the `ghostty-vt` C library to encode mouse
|
||||
events into terminal escape sequences.
|
||||
|
||||
This example specifically shows how to:
|
||||
|
||||
1. Create a mouse encoder with the C API
|
||||
2. Configure tracking mode and output format (this example uses SGR)
|
||||
3. Set terminal geometry for pixel-to-cell coordinate mapping
|
||||
4. Create and configure a mouse event
|
||||
5. Encode the mouse event into a terminal escape sequence
|
||||
|
||||
The example encodes a left button press at pixel position (50, 40) using SGR
|
||||
format, producing an escape sequence like `\x1b[<0;6;3M`.
|
||||
|
||||
## Usage
|
||||
|
||||
Run the program:
|
||||
|
||||
```shell-session
|
||||
zig build run
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_encode_mouse",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0x413a8529a6dd3c51,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [mouse-encode]
|
||||
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;
|
||||
}
|
||||
//! [mouse-encode]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Example: `ghostty-vt` Terminal Formatter
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` terminal and
|
||||
formatter APIs to create a terminal, write VT-encoded content into it, and
|
||||
format the screen contents as plain text.
|
||||
|
||||
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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_formatter",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_formatter,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0x9e3758265677a0c4,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
// Create a terminal with a small grid
|
||||
GhosttyTerminal terminal;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Write VT-encoded content into the terminal to exercise various
|
||||
// cursor movement and styling sequences.
|
||||
const char *commands[] = {
|
||||
"Line 1: Hello World!\r\n", // Simple text on row 1
|
||||
"Line 2: \033[1mBold\033[0m and " // Bold text on row 2
|
||||
"\033[4mUnderline\033[0m\r\n",
|
||||
"Line 3: placeholder\r\n", // Will be overwritten below
|
||||
"\033[3;1H", // CUP: move cursor back to row 3, col 1
|
||||
"\033[2K", // EL: erase the entire line
|
||||
"Line 3: Overwritten!\r\n", // Rewrite row 3 with new content
|
||||
"\033[5;10H", // CUP: jump to row 5, col 10
|
||||
"Placed at (5,10)", // Write at that position
|
||||
"\033[1;72H", // CUP: jump to row 1, col 72
|
||||
"RIGHT->", // Near the right edge of row 1
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t *)commands[i],
|
||||
strlen(commands[i]));
|
||||
}
|
||||
|
||||
// Create a plain-text formatter for the terminal
|
||||
GhosttyFormatterTerminalOptions fmt_opts = GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
|
||||
fmt_opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
|
||||
fmt_opts.trim = true;
|
||||
|
||||
GhosttyFormatter formatter;
|
||||
result = ghostty_formatter_terminal_new(NULL, &formatter, terminal, fmt_opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Format into an allocated buffer
|
||||
uint8_t *buf = NULL;
|
||||
size_t len = 0;
|
||||
result = ghostty_formatter_format_alloc(formatter, NULL, &buf, &len);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Print the formatted output
|
||||
printf("Formatted output (%zu bytes):\n", len);
|
||||
fwrite(buf, 1, len, stdout);
|
||||
printf("\n");
|
||||
|
||||
// Clean up
|
||||
ghostty_free(NULL, buf, len);
|
||||
ghostty_formatter_free(formatter);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Example: `ghostty-vt` Tracked Grid References
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` terminal and
|
||||
tracked grid reference APIs to keep a long-lived reference to a cell as the
|
||||
terminal scrolls, detect when that reference loses its meaningful location,
|
||||
and move the same tracked handle to a new point.
|
||||
|
||||
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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_ref_tracked",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_grid_ref_tracked,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0x64bd14b59e76c294,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [grid-ref-tracked]
|
||||
static uint32_t codepoint_at_tracked_ref(GhosttyTrackedGridRef tracked) {
|
||||
GhosttyGridRef snapshot = GHOSTTY_INIT_SIZED(GhosttyGridRef);
|
||||
GhosttyResult result = ghostty_tracked_grid_ref_snapshot(tracked, &snapshot);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
GhosttyCell cell;
|
||||
result = ghostty_grid_ref_cell(&snapshot, &cell);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
bool has_text = false;
|
||||
ghostty_cell_get(cell, GHOSTTY_CELL_DATA_HAS_TEXT, &has_text);
|
||||
assert(has_text);
|
||||
|
||||
uint32_t codepoint = 0;
|
||||
ghostty_cell_get(cell, GHOSTTY_CELL_DATA_CODEPOINT, &codepoint);
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
int main() {
|
||||
GhosttyTerminal terminal;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.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";
|
||||
ghostty_terminal_vt_write(
|
||||
terminal, (const uint8_t *)text, strlen(text));
|
||||
|
||||
GhosttyTrackedGridRef tracked = NULL;
|
||||
GhosttyPoint alpha = {
|
||||
.tag = GHOSTTY_POINT_TAG_ACTIVE,
|
||||
.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";
|
||||
ghostty_terminal_vt_write(
|
||||
terminal, (const uint8_t *)more, strlen(more));
|
||||
|
||||
assert(ghostty_tracked_grid_ref_has_value(tracked));
|
||||
printf("tracked codepoint after scroll: %c\n",
|
||||
(char)codepoint_at_tracked_ref(tracked));
|
||||
|
||||
GhosttyPointCoordinate screen = {0};
|
||||
result = ghostty_tracked_grid_ref_point(
|
||||
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.
|
||||
ghostty_terminal_reset(terminal);
|
||||
assert(!ghostty_tracked_grid_ref_has_value(tracked));
|
||||
|
||||
GhosttyGridRef discarded = GHOSTTY_INIT_SIZED(GhosttyGridRef);
|
||||
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";
|
||||
ghostty_terminal_vt_write(
|
||||
terminal, (const uint8_t *)replacement, strlen(replacement));
|
||||
|
||||
GhosttyPoint echo = {
|
||||
.tag = GHOSTTY_POINT_TAG_ACTIVE,
|
||||
.value = { .coordinate = { .x = 0, .y = 0 } },
|
||||
};
|
||||
result = ghostty_tracked_grid_ref_set(tracked, terminal, echo);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
assert(ghostty_tracked_grid_ref_has_value(tracked));
|
||||
printf("tracked codepoint after reset/set: %c\n",
|
||||
(char)codepoint_at_tracked_ref(tracked));
|
||||
|
||||
ghostty_tracked_grid_ref_free(tracked);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
//! [grid-ref-tracked]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# 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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
#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]
|
||||
|
|
@ -29,7 +29,7 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
// Exe
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "c_vt_effects",
|
||||
.name = "c_vt_key_encode",
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
b.installArtifact(exe);
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
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});
|
||||
|
||||
// Create key event
|
||||
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_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.
|
||||
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");
|
||||
|
||||
ghostty_key_event_free(event);
|
||||
ghostty_key_encoder_free(encoder);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Example: `ghostty-vt` Kitty Graphics Protocol
|
||||
|
||||
This contains a simple example of how to use the system interface
|
||||
(`ghostty_sys_set`) to install a PNG decoder callback, then send
|
||||
a Kitty Graphics Protocol image via `ghostty_terminal_vt_write`.
|
||||
|
||||
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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_kitty_graphics",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_kitty_graphics,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0x432d40ecc8f15589,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [kitty-graphics-decode-png]
|
||||
/**
|
||||
* Minimal PNG decoder callback for the sys interface.
|
||||
*
|
||||
* A real implementation would use a PNG library (libpng, stb_image, etc.)
|
||||
* to decode the PNG data. This example uses a hardcoded 1x1 red pixel
|
||||
* since we know exactly what image we're sending.
|
||||
*
|
||||
* WARNING: This is only an example for providing a callback, it DOES NOT
|
||||
* actually decode the PNG it is passed. It hardcodes a response.
|
||||
*/
|
||||
bool decode_png(void* userdata,
|
||||
const GhosttyAllocator* allocator,
|
||||
const uint8_t* data,
|
||||
size_t data_len,
|
||||
GhosttySysImage* out) {
|
||||
int* count = (int*)userdata;
|
||||
(*count)++;
|
||||
printf(" decode_png called (size=%zu, call #%d)\n", data_len, *count);
|
||||
|
||||
/* Allocate RGBA pixel data through the provided allocator. */
|
||||
const size_t pixel_len = 4; /* 1x1 RGBA */
|
||||
uint8_t* pixels = ghostty_alloc(allocator, pixel_len);
|
||||
if (!pixels) return false;
|
||||
|
||||
/* Fill with red (R=255, G=0, B=0, A=255). */
|
||||
pixels[0] = 255;
|
||||
pixels[1] = 0;
|
||||
pixels[2] = 0;
|
||||
pixels[3] = 255;
|
||||
|
||||
out->width = 1;
|
||||
out->height = 1;
|
||||
out->data = pixels;
|
||||
out->data_len = pixel_len;
|
||||
return true;
|
||||
}
|
||||
//! [kitty-graphics-decode-png]
|
||||
|
||||
//! [kitty-graphics-write-pty]
|
||||
/**
|
||||
* write_pty callback to capture terminal responses.
|
||||
*
|
||||
* The Kitty graphics protocol sends an APC response back to the pty
|
||||
* when an image is loaded (unless suppressed with q=2).
|
||||
*/
|
||||
void on_write_pty(GhosttyTerminal terminal,
|
||||
void* userdata,
|
||||
const uint8_t* data,
|
||||
size_t len) {
|
||||
(void)terminal;
|
||||
(void)userdata;
|
||||
printf(" response (%zu bytes): ", len);
|
||||
fwrite(data, 1, len, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
//! [kitty-graphics-write-pty]
|
||||
|
||||
//! [kitty-graphics-main]
|
||||
int main() {
|
||||
/* Install the PNG decoder via the sys interface. */
|
||||
int decode_count = 0;
|
||||
ghostty_sys_set(GHOSTTY_SYS_OPT_USERDATA, &decode_count);
|
||||
ghostty_sys_set(GHOSTTY_SYS_OPT_DECODE_PNG, (const void*)decode_png);
|
||||
|
||||
/* Create a terminal with Kitty graphics enabled. */
|
||||
GhosttyTerminal terminal = NULL;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
if (ghostty_terminal_new(NULL, &terminal, opts) != GHOSTTY_SUCCESS) {
|
||||
fprintf(stderr, "Failed to create terminal\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set cell pixel dimensions so kitty graphics can compute grid sizes. */
|
||||
ghostty_terminal_resize(terminal, 80, 24, 8, 16);
|
||||
|
||||
/* Set a storage limit to enable Kitty graphics. */
|
||||
uint64_t storage_limit = 64 * 1024 * 1024; /* 64 MiB */
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_STORAGE_LIMIT,
|
||||
&storage_limit);
|
||||
|
||||
/* Install write_pty to see the protocol response. */
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_WRITE_PTY,
|
||||
(const void*)on_write_pty);
|
||||
|
||||
/*
|
||||
* Send a Kitty graphics command with an inline 1x1 PNG image.
|
||||
*
|
||||
* The escape sequence is:
|
||||
* ESC _G a=T,f=100,q=1; <base64 PNG data> ESC \
|
||||
*
|
||||
* Where:
|
||||
* a=T — transmit and display
|
||||
* f=100 — PNG format
|
||||
* q=1 — request a response (q=0 would suppress it)
|
||||
*/
|
||||
printf("Sending Kitty graphics PNG image:\n");
|
||||
const char* kitty_cmd =
|
||||
"\x1b_Ga=T,f=100,q=1;"
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAA"
|
||||
"DUlEQVR4nGP4z8DwHwAFAAH/iZk9HQAAAABJRU5ErkJggg=="
|
||||
"\x1b\\";
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t*)kitty_cmd,
|
||||
strlen(kitty_cmd));
|
||||
|
||||
printf("PNG decode calls: %d\n", decode_count);
|
||||
|
||||
/* Query the kitty graphics storage to verify the image was stored. */
|
||||
GhosttyKittyGraphics graphics = NULL;
|
||||
if (ghostty_terminal_get(terminal, GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS,
|
||||
&graphics) != GHOSTTY_SUCCESS || !graphics) {
|
||||
fprintf(stderr, "Failed to get kitty graphics storage\n");
|
||||
return 1;
|
||||
}
|
||||
printf("\nKitty graphics storage is available.\n");
|
||||
|
||||
/* Iterate placements to find the image ID. */
|
||||
GhosttyKittyGraphicsPlacementIterator iter = NULL;
|
||||
if (ghostty_kitty_graphics_placement_iterator_new(NULL, &iter) != GHOSTTY_SUCCESS) {
|
||||
fprintf(stderr, "Failed to create placement iterator\n");
|
||||
return 1;
|
||||
}
|
||||
if (ghostty_kitty_graphics_get(graphics,
|
||||
GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR, &iter) != GHOSTTY_SUCCESS) {
|
||||
fprintf(stderr, "Failed to get placement iterator\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int placement_count = 0;
|
||||
while (ghostty_kitty_graphics_placement_next(iter)) {
|
||||
placement_count++;
|
||||
uint32_t image_id = 0;
|
||||
uint32_t placement_id = 0;
|
||||
bool is_virtual = false;
|
||||
int32_t z = 0;
|
||||
|
||||
ghostty_kitty_graphics_placement_get_multi(iter, 4,
|
||||
(GhosttyKittyGraphicsPlacementData[]){
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IMAGE_ID,
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_PLACEMENT_ID,
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IS_VIRTUAL,
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Z,
|
||||
},
|
||||
(void*[]){ &image_id, &placement_id, &is_virtual, &z },
|
||||
NULL);
|
||||
|
||||
printf(" placement #%d: image_id=%u placement_id=%u virtual=%s z=%d\n",
|
||||
placement_count, image_id, placement_id,
|
||||
is_virtual ? "true" : "false", z);
|
||||
|
||||
/* Look up the image and print its properties. */
|
||||
GhosttyKittyGraphicsImage image =
|
||||
ghostty_kitty_graphics_image(graphics, image_id);
|
||||
if (!image) {
|
||||
fprintf(stderr, "Failed to look up image %u\n", image_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t width = 0, height = 0, number = 0;
|
||||
GhosttyKittyImageFormat format = 0;
|
||||
size_t data_len = 0;
|
||||
|
||||
ghostty_kitty_graphics_image_get_multi(image, 5,
|
||||
(GhosttyKittyGraphicsImageData[]){
|
||||
GHOSTTY_KITTY_IMAGE_DATA_NUMBER,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_WIDTH,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_HEIGHT,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_FORMAT,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN,
|
||||
},
|
||||
(void*[]){ &number, &width, &height, &format, &data_len },
|
||||
NULL);
|
||||
|
||||
printf(" image: number=%u size=%ux%u format=%d data_len=%zu\n",
|
||||
number, width, height, format, data_len);
|
||||
|
||||
/* Compute the rendered pixel size and grid size. */
|
||||
uint32_t px_w = 0, px_h = 0, cols = 0, rows = 0;
|
||||
if (ghostty_kitty_graphics_placement_pixel_size(iter, image, terminal,
|
||||
&px_w, &px_h) == GHOSTTY_SUCCESS) {
|
||||
printf(" rendered pixel size: %ux%u\n", px_w, px_h);
|
||||
}
|
||||
if (ghostty_kitty_graphics_placement_grid_size(iter, image, terminal,
|
||||
&cols, &rows) == GHOSTTY_SUCCESS) {
|
||||
printf(" grid size: %u cols x %u rows\n", cols, rows);
|
||||
}
|
||||
}
|
||||
printf("Total placements: %d\n", placement_count);
|
||||
ghostty_kitty_graphics_placement_iterator_free(iter);
|
||||
|
||||
/* Clean up. */
|
||||
ghostty_terminal_free(terminal);
|
||||
|
||||
/* Clear the sys callbacks. */
|
||||
ghostty_sys_set(GHOSTTY_SYS_OPT_DECODE_PNG, NULL);
|
||||
ghostty_sys_set(GHOSTTY_SYS_OPT_USERDATA, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//! [kitty-graphics-main]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# 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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [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;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# Example: `ghostty-vt` Paste Utilities
|
||||
# Example: `ghostty-vt` Paste Safety Check
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` paste
|
||||
utilities to check if paste data is safe and encode it for terminal input.
|
||||
utilities to check if paste data is safe.
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -2,41 +2,18 @@
|
|||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
//! [paste-safety]
|
||||
void safety_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("Safe to paste\n");
|
||||
}
|
||||
|
||||
if (!ghostty_paste_is_safe(unsafe_data, strlen(unsafe_data))) {
|
||||
printf("Unsafe! Contains newline\n");
|
||||
}
|
||||
}
|
||||
//! [paste-safety]
|
||||
|
||||
//! [paste-encode]
|
||||
void encode_example() {
|
||||
// The input buffer is modified in place (unsafe bytes are stripped).
|
||||
char data[] = "hello\nworld";
|
||||
char buf[64];
|
||||
size_t written = 0;
|
||||
|
||||
GhosttyResult result = ghostty_paste_encode(
|
||||
data, strlen(data), true, buf, sizeof(buf), &written);
|
||||
|
||||
if (result == GHOSTTY_SUCCESS) {
|
||||
printf("Encoded %zu bytes: ", written);
|
||||
fwrite(buf, 1, written, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
//! [paste-encode]
|
||||
|
||||
int main() {
|
||||
safety_example();
|
||||
// Test safe paste data
|
||||
const char *safe_data = "hello world";
|
||||
if (ghostty_paste_is_safe(safe_data, strlen(safe_data))) {
|
||||
printf("'%s' is safe to paste\n", safe_data);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Test unsafe paste data with bracketed paste end sequence
|
||||
const char *unsafe_escape = "evil\x1b[201~code";
|
||||
|
|
@ -50,7 +27,5 @@ int main() {
|
|||
printf("Empty data is safe\n");
|
||||
}
|
||||
|
||||
encode_example();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
# Example: `ghostty-vt` Render State
|
||||
|
||||
This contains an example of how to use the `ghostty-vt` render-state API
|
||||
to create a render state, update it from terminal content, iterate rows
|
||||
and cells, read styles and colors, inspect cursor and row-local selection
|
||||
state, and manage dirty tracking.
|
||||
|
||||
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
|
||||
```
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
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_render",
|
||||
.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);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
.{
|
||||
.name = .c_vt_render,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0xb10e18b2fab773c9,
|
||||
.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",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
/// Helper: resolve a style color to an RGB value using the palette.
|
||||
static GhosttyColorRgb resolve_color(GhosttyStyleColor color,
|
||||
const GhosttyRenderStateColors* colors,
|
||||
GhosttyColorRgb fallback) {
|
||||
switch (color.tag) {
|
||||
case GHOSTTY_STYLE_COLOR_RGB:
|
||||
return color.value.rgb;
|
||||
case GHOSTTY_STYLE_COLOR_PALETTE:
|
||||
return colors->palette[color.value.palette];
|
||||
default:
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
GhosttyResult result;
|
||||
|
||||
//! [render-state-update]
|
||||
// Create a terminal and render state, then update the render state
|
||||
// from the terminal. The render state captures a snapshot of everything
|
||||
// needed to draw a frame.
|
||||
GhosttyTerminal terminal = NULL;
|
||||
GhosttyTerminalOptions terminal_opts = {
|
||||
.cols = 40,
|
||||
.rows = 5,
|
||||
.max_scrollback = 10000,
|
||||
};
|
||||
result = ghostty_terminal_new(NULL, &terminal, terminal_opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
GhosttyRenderState render_state = NULL;
|
||||
result = ghostty_render_state_new(NULL, &render_state);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Feed some styled content into the terminal.
|
||||
const char* content =
|
||||
"Hello, \033[1;32mworld\033[0m!\r\n" // bold green "world"
|
||||
"\033[4munderlined\033[0m text\r\n" // underlined text
|
||||
"\033[38;2;255;128;0morange\033[0m\r\n"; // 24-bit orange fg
|
||||
ghostty_terminal_vt_write(
|
||||
terminal, (const uint8_t*)content, strlen(content));
|
||||
|
||||
// Select "underlined" on the second row. Render state exposes this
|
||||
// later as a row-local selected cell range.
|
||||
GhosttyGridRef selection_start = GHOSTTY_INIT_SIZED(GhosttyGridRef);
|
||||
GhosttyPoint selection_start_pt = {
|
||||
.tag = GHOSTTY_POINT_TAG_ACTIVE,
|
||||
.value = { .coordinate = { .x = 0, .y = 1 } },
|
||||
};
|
||||
result = ghostty_terminal_grid_ref(
|
||||
terminal, selection_start_pt, &selection_start);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
GhosttyGridRef selection_end = GHOSTTY_INIT_SIZED(GhosttyGridRef);
|
||||
GhosttyPoint selection_end_pt = {
|
||||
.tag = GHOSTTY_POINT_TAG_ACTIVE,
|
||||
.value = { .coordinate = { .x = 9, .y = 1 } },
|
||||
};
|
||||
result = ghostty_terminal_grid_ref(terminal, selection_end_pt, &selection_end);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
GhosttySelection selection = GHOSTTY_INIT_SIZED(GhosttySelection);
|
||||
selection.start = selection_start;
|
||||
selection.end = selection_end;
|
||||
result = ghostty_terminal_set(
|
||||
terminal, GHOSTTY_TERMINAL_OPT_SELECTION, &selection);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
result = ghostty_render_state_update(render_state, terminal);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
//! [render-state-update]
|
||||
|
||||
//! [render-dirty-check]
|
||||
// Check the global dirty state to decide how much work the renderer
|
||||
// needs to do. After rendering, reset it to false.
|
||||
GhosttyRenderStateDirty dirty;
|
||||
result = ghostty_render_state_get(
|
||||
render_state, GHOSTTY_RENDER_STATE_DATA_DIRTY, &dirty);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
switch (dirty) {
|
||||
case GHOSTTY_RENDER_STATE_DIRTY_FALSE:
|
||||
printf("Frame is clean, nothing to draw.\n");
|
||||
break;
|
||||
case GHOSTTY_RENDER_STATE_DIRTY_PARTIAL:
|
||||
printf("Partial redraw needed.\n");
|
||||
break;
|
||||
case GHOSTTY_RENDER_STATE_DIRTY_FULL:
|
||||
printf("Full redraw needed.\n");
|
||||
break;
|
||||
}
|
||||
//! [render-dirty-check]
|
||||
|
||||
//! [render-colors]
|
||||
// Retrieve colors (background, foreground, palette) from the render
|
||||
// state. These are needed to resolve palette-indexed cell colors.
|
||||
GhosttyRenderStateColors colors =
|
||||
GHOSTTY_INIT_SIZED(GhosttyRenderStateColors);
|
||||
result = ghostty_render_state_colors_get(render_state, &colors);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
printf("Background: #%02x%02x%02x\n",
|
||||
colors.background.r, colors.background.g, colors.background.b);
|
||||
printf("Foreground: #%02x%02x%02x\n",
|
||||
colors.foreground.r, colors.foreground.g, colors.foreground.b);
|
||||
//! [render-colors]
|
||||
|
||||
//! [render-cursor]
|
||||
// Read cursor position and visual style from the render state.
|
||||
bool cursor_visible = false;
|
||||
ghostty_render_state_get(
|
||||
render_state, GHOSTTY_RENDER_STATE_DATA_CURSOR_VISIBLE,
|
||||
&cursor_visible);
|
||||
|
||||
bool cursor_in_viewport = false;
|
||||
ghostty_render_state_get(
|
||||
render_state, GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_HAS_VALUE,
|
||||
&cursor_in_viewport);
|
||||
|
||||
if (cursor_visible && cursor_in_viewport) {
|
||||
uint16_t cx, cy;
|
||||
ghostty_render_state_get(
|
||||
render_state, GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_X, &cx);
|
||||
ghostty_render_state_get(
|
||||
render_state, GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_Y, &cy);
|
||||
|
||||
GhosttyRenderStateCursorVisualStyle style;
|
||||
ghostty_render_state_get(
|
||||
render_state, GHOSTTY_RENDER_STATE_DATA_CURSOR_VISUAL_STYLE,
|
||||
&style);
|
||||
|
||||
const char* style_name = "unknown";
|
||||
switch (style) {
|
||||
case GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BAR:
|
||||
style_name = "bar";
|
||||
break;
|
||||
case GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BLOCK:
|
||||
style_name = "block";
|
||||
break;
|
||||
case GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_UNDERLINE:
|
||||
style_name = "underline";
|
||||
break;
|
||||
case GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BLOCK_HOLLOW:
|
||||
style_name = "hollow";
|
||||
break;
|
||||
}
|
||||
printf("Cursor at (%u, %u), style: %s\n", cx, cy, style_name);
|
||||
}
|
||||
//! [render-cursor]
|
||||
|
||||
//! [render-row-iterate]
|
||||
// Iterate rows via the row iterator. For each dirty row, iterate its
|
||||
// cells, read codepoints/graphemes and styles, and emit ANSI-colored
|
||||
// output as a simple "renderer".
|
||||
GhosttyRenderStateRowIterator row_iter = NULL;
|
||||
result = ghostty_render_state_row_iterator_new(NULL, &row_iter);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
result = ghostty_render_state_get(
|
||||
render_state, GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR, &row_iter);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
GhosttyRenderStateRowCells cells = NULL;
|
||||
result = ghostty_render_state_row_cells_new(NULL, &cells);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
int row_index = 0;
|
||||
while (ghostty_render_state_row_iterator_next(row_iter)) {
|
||||
// Check per-row dirty state; a real renderer would skip clean rows.
|
||||
bool row_dirty = false;
|
||||
ghostty_render_state_row_get(
|
||||
row_iter, GHOSTTY_RENDER_STATE_ROW_DATA_DIRTY, &row_dirty);
|
||||
|
||||
printf("Row %2d [%s]: ", row_index,
|
||||
row_dirty ? "dirty" : "clean");
|
||||
|
||||
// Query the row-local selection range. Rows without a selection return
|
||||
// GHOSTTY_NO_VALUE; selected rows return inclusive start/end columns.
|
||||
GhosttyRenderStateRowSelection row_selection =
|
||||
GHOSTTY_INIT_SIZED(GhosttyRenderStateRowSelection);
|
||||
result = ghostty_render_state_row_get(
|
||||
row_iter, GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION, &row_selection);
|
||||
assert(result == GHOSTTY_SUCCESS || result == GHOSTTY_NO_VALUE);
|
||||
if (result == GHOSTTY_SUCCESS) {
|
||||
printf("selection=%u..%u ",
|
||||
row_selection.start_x, row_selection.end_x);
|
||||
}
|
||||
|
||||
// Get cells for this row (reuses the same cells handle).
|
||||
result = ghostty_render_state_row_get(
|
||||
row_iter, GHOSTTY_RENDER_STATE_ROW_DATA_CELLS, &cells);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
while (ghostty_render_state_row_cells_next(cells)) {
|
||||
// Get the grapheme length; 0 means the cell is empty.
|
||||
uint32_t grapheme_len = 0;
|
||||
ghostty_render_state_row_cells_get(
|
||||
cells, GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_LEN,
|
||||
&grapheme_len);
|
||||
|
||||
if (grapheme_len == 0) {
|
||||
putchar(' ');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read the style for this cell. Returns the default style for
|
||||
// cells that have no explicit styling.
|
||||
GhosttyStyle style = GHOSTTY_INIT_SIZED(GhosttyStyle);
|
||||
ghostty_render_state_row_cells_get(
|
||||
cells, GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_STYLE, &style);
|
||||
|
||||
// Resolve foreground color for this cell.
|
||||
GhosttyColorRgb fg =
|
||||
resolve_color(style.fg_color, &colors, colors.foreground);
|
||||
|
||||
// Emit ANSI true-color escape for the foreground.
|
||||
printf("\033[38;2;%u;%u;%um", fg.r, fg.g, fg.b);
|
||||
if (style.bold) printf("\033[1m");
|
||||
if (style.underline) printf("\033[4m");
|
||||
|
||||
// Read grapheme codepoints into a buffer and print them.
|
||||
// The buffer must be at least grapheme_len elements.
|
||||
uint32_t codepoints[16];
|
||||
uint32_t len = grapheme_len < 16 ? grapheme_len : 16;
|
||||
ghostty_render_state_row_cells_get(
|
||||
cells, GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_BUF,
|
||||
codepoints);
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
// Simple ASCII print; a real renderer would handle UTF-8.
|
||||
if (codepoints[i] < 128)
|
||||
putchar((char)codepoints[i]);
|
||||
else
|
||||
printf("U+%04X", codepoints[i]);
|
||||
}
|
||||
|
||||
printf("\033[0m"); // Reset style after each cell.
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Clear per-row dirty flag after "rendering" it.
|
||||
bool clean = false;
|
||||
ghostty_render_state_row_set(
|
||||
row_iter, GHOSTTY_RENDER_STATE_ROW_OPTION_DIRTY, &clean);
|
||||
|
||||
row_index++;
|
||||
}
|
||||
//! [render-row-iterate]
|
||||
|
||||
//! [render-dirty-reset]
|
||||
// After finishing the frame, reset the global dirty state so the next
|
||||
// update can report changes accurately.
|
||||
GhosttyRenderStateDirty clean_state = GHOSTTY_RENDER_STATE_DIRTY_FALSE;
|
||||
result = ghostty_render_state_set(
|
||||
render_state, GHOSTTY_RENDER_STATE_OPTION_DIRTY, &clean_state);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
//! [render-dirty-reset]
|
||||
|
||||
// Cleanup
|
||||
ghostty_render_state_row_cells_free(cells);
|
||||
ghostty_render_state_row_iterator_free(row_iter);
|
||||
ghostty_render_state_free(render_state);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Example: `ghostty-vt` Selection Gestures
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` selection
|
||||
gesture API from C. It creates synthetic press, drag, release, and deep-press
|
||||
events and formats the resulting selection snapshots.
|
||||
|
||||
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
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue