mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-03 00:18:35 +00:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
055281febf | ||
![]() |
64edc95e92 | ||
![]() |
359d735213 | ||
![]() |
e10eb8a2fd | ||
![]() |
8b047fb570 | ||
![]() |
f764c070bd | ||
![]() |
d06c9c7aae | ||
![]() |
eb0814c680 | ||
![]() |
7aff259fee | ||
![]() |
a2b6a9cf99 | ||
![]() |
4cb3aaece4 | ||
![]() |
7a3bbe0107 | ||
![]() |
5110ad053e | ||
![]() |
2be16d2242 | ||
![]() |
7053f5a537 | ||
![]() |
a905e14cc4 | ||
![]() |
e89036f716 | ||
![]() |
5880fa5321 | ||
![]() |
38503e7c33 | ||
![]() |
5429d1e3e2 | ||
![]() |
b6c3781cdc | ||
![]() |
12446d7d50 | ||
![]() |
d231e94535 | ||
![]() |
e3cdf0faae | ||
![]() |
a9f4d4941a | ||
![]() |
3d0846051f | ||
![]() |
6e5419c561 | ||
![]() |
1041a4cc9b | ||
![]() |
a09b39fb57 | ||
![]() |
093a72da05 | ||
![]() |
e0905ac794 | ||
![]() |
b34f3f7208 | ||
![]() |
51292a9793 | ||
![]() |
1cd0fb5dab | ||
![]() |
5c6a766ff6 | ||
![]() |
6b1fd76b7d | ||
![]() |
581846992d | ||
![]() |
86e5ec8ba5 | ||
![]() |
5a0bd8d1fa | ||
![]() |
28cdbe4f22 | ||
![]() |
a4126d025b | ||
![]() |
b4345d151a | ||
![]() |
af77332871 | ||
![]() |
c33ea2757c | ||
![]() |
6753507826 | ||
![]() |
7884909253 | ||
![]() |
812dc7cf2f | ||
![]() |
81027f2211 |
4
.github/workflows/nix.yml
vendored
4
.github/workflows/nix.yml
vendored
@@ -36,13 +36,13 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- name: Setup Nix
|
||||
uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
|
4
.github/workflows/release-tag.yml
vendored
4
.github/workflows/release-tag.yml
vendored
@@ -83,13 +83,13 @@ jobs:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
|
||||
|
7
.github/workflows/release-tip.yml
vendored
7
.github/workflows/release-tip.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
with:
|
||||
# Important so that build number generation works
|
||||
fetch-depth: 0
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -163,12 +163,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -579,6 +579,7 @@ jobs:
|
||||
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
|
||||
# validated by macOS even when an internet connection is not available.
|
||||
echo "Attach staple"
|
||||
xcrun stapler staple "Ghostty.dmg"
|
||||
xcrun stapler staple "macos/build/Release/Ghostty.app"
|
||||
|
||||
# Zip up the app
|
||||
|
2
.github/workflows/snap.yml
vendored
2
.github/workflows/snap.yml
vendored
@@ -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@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
|
235
.github/workflows/test.yml
vendored
235
.github/workflows/test.yml
vendored
@@ -12,10 +12,8 @@ jobs:
|
||||
needs:
|
||||
- build-bench
|
||||
- build-dist
|
||||
- build-examples
|
||||
- build-flatpak
|
||||
- build-freebsd
|
||||
- build-libghostty-vt
|
||||
- build-linux
|
||||
- build-linux-libghostty
|
||||
- build-nix
|
||||
@@ -24,10 +22,8 @@ jobs:
|
||||
- build-snap
|
||||
- build-windows
|
||||
- test
|
||||
- test-simd
|
||||
- test-gtk
|
||||
- test-sentry-linux
|
||||
- test-i18n
|
||||
- test-macos
|
||||
- pinact
|
||||
- prettier
|
||||
@@ -73,14 +69,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -91,42 +87,6 @@ jobs:
|
||||
- name: Build Benchmarks
|
||||
run: nix develop -c zig build -Demit-bench
|
||||
|
||||
build-examples:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
dir: [c-vt, zig-vt]
|
||||
name: Example ${{ matrix.dir }}
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
needs: test
|
||||
env:
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: Build Example
|
||||
run: |
|
||||
cd example/${{ matrix.dir }}
|
||||
nix develop -c zig build
|
||||
|
||||
build-flatpak:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -140,14 +100,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -174,14 +134,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -195,48 +155,6 @@ jobs:
|
||||
zig build \
|
||||
-Dsnap
|
||||
|
||||
build-libghostty-vt:
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
[
|
||||
aarch64-macos,
|
||||
x86_64-macos,
|
||||
aarch64-linux,
|
||||
x86_64-linux,
|
||||
x86_64-windows,
|
||||
]
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
needs: test
|
||||
env:
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
nix develop -c zig build lib-vt \
|
||||
-Dtarget=${{ matrix.target }} \
|
||||
-Dsimd=false
|
||||
|
||||
build-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -252,14 +170,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -281,14 +199,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -314,14 +232,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -360,14 +278,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -572,14 +490,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -614,14 +532,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -646,41 +564,6 @@ jobs:
|
||||
-Dgtk-x11=${{ matrix.x11 }} \
|
||||
-Dgtk-wayland=${{ matrix.wayland }}
|
||||
|
||||
test-simd:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
simd: ["true", "false"]
|
||||
name: Build -Dsimd=${{ matrix.simd }}
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
needs: test
|
||||
env:
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
nix develop -c zig build test -Dsimd=${{ matrix.simd }}
|
||||
|
||||
test-sentry-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -697,14 +580,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -745,41 +628,6 @@ jobs:
|
||||
- name: test
|
||||
run: nix develop -c zig build test --system ${{ steps.deps.outputs.deps }}
|
||||
|
||||
test-i18n:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
i18n: ["true", "false"]
|
||||
name: Build -Di18n=${{ matrix.simd }}
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
needs: test
|
||||
env:
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
nix develop -c zig build -Di18n=${{ matrix.i18n }}
|
||||
|
||||
zig-fmt:
|
||||
if: github.repository == 'ghostty-org/ghostty'
|
||||
runs-on: namespace-profile-ghostty-xsm
|
||||
@@ -790,12 +638,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -818,12 +666,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -845,12 +693,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -872,12 +720,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -899,12 +747,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -926,12 +774,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -960,12 +808,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -987,12 +835,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -1022,14 +870,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -1044,7 +892,6 @@ jobs:
|
||||
test-debian-13:
|
||||
name: Test build on Debian 13
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
timeout-minutes: 10
|
||||
needs: [test, build-dist]
|
||||
steps:
|
||||
- name: Install and configure Namespace CLI
|
||||
@@ -1110,14 +957,14 @@ jobs:
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
@@ -1152,7 +999,7 @@ jobs:
|
||||
sudo systemctl start ssh
|
||||
|
||||
- name: Set up FreeBSD VM
|
||||
uses: vmactions/freebsd-vm@487ce35b96fae3e60d45b521735f5aa436ecfade # v1.2.4
|
||||
uses: vmactions/freebsd-vm@05856381fab64eeee9b038a0818f6cec649ca17a # v1.2.3
|
||||
with:
|
||||
release: ${{ matrix.release }}
|
||||
copyback: false
|
||||
|
4
.github/workflows/update-colorschemes.yml
vendored
4
.github/workflows/update-colorschemes.yml
vendored
@@ -22,14 +22,14 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@7baedde84bbf5063413d621f282834bc2654d0c1 # v1.2.18
|
||||
uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
- name: Setup Nix
|
||||
uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||
uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
|
28
Doxyfile
28
Doxyfile
@@ -1,28 +0,0 @@
|
||||
# Doxyfile 1.13.2
|
||||
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "libghostty"
|
||||
INPUT = include/ghostty/vt.h
|
||||
INPUT_ENCODING = UTF-8
|
||||
RECURSIVE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# HTML Output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = zig-out/share/ghostty/doc/libghostty
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Man Output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
GENERATE_MAN = YES
|
||||
MAN_OUTPUT = zig-out/share/man
|
||||
MAN_EXTENSION = .3
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Other Output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
GENERATE_LATEX = NO
|
67
build.zig
67
build.zig
@@ -16,36 +16,20 @@ 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`.
|
||||
const config = try buildpkg.Config.init(b);
|
||||
const test_filters = b.option(
|
||||
[][]const u8,
|
||||
const test_filter = b.option(
|
||||
[]const u8,
|
||||
"test-filter",
|
||||
"Filter for test. Only applies to Zig tests.",
|
||||
) orelse &[0][]const u8{};
|
||||
|
||||
// Ghostty dependencies used by many artifacts.
|
||||
const deps = try buildpkg.SharedDeps.init(b, &config);
|
||||
|
||||
// The modules exported for Zig consumers of libghostty. If you're
|
||||
// writing a Zig program that uses libghostty, read this file.
|
||||
const mod = try buildpkg.GhosttyZig.init(
|
||||
b,
|
||||
&config,
|
||||
&deps,
|
||||
);
|
||||
|
||||
// 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",
|
||||
"Run the app under valgrind",
|
||||
);
|
||||
const test_step = b.step("test", "Run tests");
|
||||
const test_lib_vt_step = b.step(
|
||||
"test-lib-vt",
|
||||
"Run libghostty-vt tests",
|
||||
);
|
||||
const test_valgrind_step = b.step(
|
||||
"test-valgrind",
|
||||
"Run tests under valgrind",
|
||||
@@ -59,6 +43,10 @@ pub fn build(b: *std.Build) !void {
|
||||
const resources = try buildpkg.GhosttyResources.init(b, &config);
|
||||
const i18n = if (config.i18n) try buildpkg.GhosttyI18n.init(b, &config) else null;
|
||||
|
||||
// Ghostty dependencies used by many artifacts.
|
||||
const deps = try buildpkg.SharedDeps.init(b, &config);
|
||||
if (config.emit_helpgen) deps.help_strings.install();
|
||||
|
||||
// Ghostty executable, the actual runnable Ghostty program.
|
||||
const exe = try buildpkg.GhosttyExe.init(b, &config, &deps);
|
||||
|
||||
@@ -91,7 +79,7 @@ pub fn build(b: *std.Build) !void {
|
||||
check_step.dependOn(dist.install_step);
|
||||
}
|
||||
|
||||
// libghostty (internal, big)
|
||||
// libghostty
|
||||
const libghostty_shared = try buildpkg.GhosttyLib.initShared(
|
||||
b,
|
||||
&deps,
|
||||
@@ -101,17 +89,6 @@ pub fn build(b: *std.Build) !void {
|
||||
&deps,
|
||||
);
|
||||
|
||||
// libghostty-vt
|
||||
const libghostty_vt_shared = try buildpkg.GhosttyLibVt.initShared(
|
||||
b,
|
||||
&mod,
|
||||
);
|
||||
libghostty_vt_shared.install(libvt_step);
|
||||
libghostty_vt_shared.install(b.getInstallStep());
|
||||
|
||||
// Helpgen
|
||||
if (config.emit_helpgen) deps.help_strings.install();
|
||||
|
||||
// Runtime "none" is libghostty, anything else is an executable.
|
||||
if (config.app_runtime != .none) {
|
||||
if (config.emit_exe) {
|
||||
@@ -214,7 +191,7 @@ pub fn build(b: *std.Build) !void {
|
||||
run_step.dependOn(&macos_app_native_only.open.step);
|
||||
|
||||
// If we have no test filters, install the tests too
|
||||
if (test_filters.len == 0) {
|
||||
if (test_filter == null) {
|
||||
macos_app_native_only.addTestStepDependencies(test_step);
|
||||
}
|
||||
}
|
||||
@@ -245,33 +222,11 @@ pub fn build(b: *std.Build) !void {
|
||||
run_valgrind_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
// Zig module tests
|
||||
{
|
||||
const mod_vt_test = b.addTest(.{
|
||||
.root_module = mod.vt,
|
||||
.target = config.target,
|
||||
.optimize = config.optimize,
|
||||
.filters = test_filters,
|
||||
});
|
||||
const mod_vt_test_run = b.addRunArtifact(mod_vt_test);
|
||||
test_lib_vt_step.dependOn(&mod_vt_test_run.step);
|
||||
|
||||
const mod_vt_c_test = b.addTest(.{
|
||||
.root_module = mod.vt_c,
|
||||
.target = config.target,
|
||||
.optimize = config.optimize,
|
||||
.filters = test_filters,
|
||||
});
|
||||
const mod_vt_c_test_run = b.addRunArtifact(mod_vt_c_test);
|
||||
test_lib_vt_step.dependOn(&mod_vt_c_test_run.step);
|
||||
}
|
||||
|
||||
// Tests
|
||||
{
|
||||
// Full unit tests
|
||||
const test_exe = b.addTest(.{
|
||||
.name = "ghostty-test",
|
||||
.filters = test_filters,
|
||||
.filters = if (test_filter) |v| &.{v} else &.{},
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = config.baselineTarget(),
|
||||
@@ -281,6 +236,7 @@ pub fn build(b: *std.Build) !void {
|
||||
.unwind_tables = .sync,
|
||||
}),
|
||||
});
|
||||
|
||||
if (config.emit_test_exe) b.installArtifact(test_exe);
|
||||
_ = try deps.add(test_exe);
|
||||
|
||||
@@ -288,9 +244,6 @@ pub fn build(b: *std.Build) !void {
|
||||
const test_run = b.addRunArtifact(test_exe);
|
||||
test_step.dependOn(&test_run.step);
|
||||
|
||||
// Normal tests always test our libghostty modules
|
||||
test_step.dependOn(test_lib_vt_step);
|
||||
|
||||
// Valgrind test running
|
||||
const valgrind_run = b.addSystemCommand(&.{
|
||||
"valgrind",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.{
|
||||
.name = .ghostty,
|
||||
.version = "1.2.1",
|
||||
.version = "1.2.0",
|
||||
.paths = .{""},
|
||||
.fingerprint = 0x64407a2a0b4147e5,
|
||||
.minimum_zig_version = "0.14.1",
|
||||
@@ -37,15 +37,15 @@
|
||||
.hash = "N-V-__8AAB9YCQBaZtQjJZVndk-g_GDIK-NTZcIa63bFp9yZ",
|
||||
.lazy = true,
|
||||
},
|
||||
.uucode = .{
|
||||
.url = "https://github.com/jacobsandlund/uucode/archive/190706c6b56f0842d29778007f74f7d3d1335fc5.tar.gz",
|
||||
.hash = "uucode-0.1.0-ZZjBPpAFQABNCvd9cVPBg4I7233Ays-NWfWphPNqGbyE",
|
||||
.ziglyph = .{
|
||||
.url = "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz",
|
||||
.hash = "ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf",
|
||||
.lazy = true,
|
||||
},
|
||||
.zig_wayland = .{
|
||||
// codeberg ifreund/zig-wayland
|
||||
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
|
||||
.hash = "wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
|
||||
.lazy = true,
|
||||
},
|
||||
.zf = .{
|
||||
// natecraddock/zf
|
||||
@@ -56,8 +56,8 @@
|
||||
.gobject = .{
|
||||
// https://github.com/jcollie/ghostty-gobject based on zig_gobject
|
||||
// Temporary until we generate them at build time automatically.
|
||||
.url = "https://github.com/ghostty-org/zig-gobject/releases/download/2025-09-20-20-1/ghostty-gobject-2025-09-20-20-1.tar.zst",
|
||||
.hash = "gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV",
|
||||
.url = "https://github.com/jcollie/ghostty-gobject/releases/download/0.15.1-2025-09-04-48-1/ghostty-gobject-0.15.1-2025-09-04-48-1.tar.zst",
|
||||
.hash = "gobject-0.3.0-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z",
|
||||
.lazy = true,
|
||||
},
|
||||
|
||||
@@ -104,19 +104,17 @@
|
||||
.jetbrains_mono = .{
|
||||
.url = "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz",
|
||||
.hash = "N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x",
|
||||
.lazy = true,
|
||||
},
|
||||
.nerd_fonts_symbols_only = .{
|
||||
.url = "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz",
|
||||
.hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s",
|
||||
.lazy = true,
|
||||
},
|
||||
|
||||
// Other
|
||||
.apple_sdk = .{ .path = "./pkg/apple-sdk" },
|
||||
.iterm2_themes = .{
|
||||
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250922-150534-d28055b/ghostty-themes.tgz",
|
||||
.hash = "N-V-__8AACEnAwCkyrJ_XqdomYlR8bpuh0l8WDidEz-BAzIv",
|
||||
.url = "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz",
|
||||
.hash = "N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B",
|
||||
.lazy = true,
|
||||
},
|
||||
},
|
||||
|
22
build.zig.zon.json
generated
22
build.zig.zon.json
generated
@@ -24,10 +24,10 @@
|
||||
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
||||
"hash": "sha256-FKLtu1Ccs+UamlPj9eQ12/WXFgS0uDPmPmB26MCpl7U="
|
||||
},
|
||||
"gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV": {
|
||||
"gobject-0.3.0-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z": {
|
||||
"name": "gobject",
|
||||
"url": "https://github.com/ghostty-org/zig-gobject/releases/download/2025-09-20-20-1/ghostty-gobject-2025-09-20-20-1.tar.zst",
|
||||
"hash": "sha256-SXiqGm81aUn6yq1wFXgNTAULdKOHS/Rzkp5OgNkkcXo="
|
||||
"url": "https://github.com/jcollie/ghostty-gobject/releases/download/0.15.1-2025-09-04-48-1/ghostty-gobject-0.15.1-2025-09-04-48-1.tar.zst",
|
||||
"hash": "sha256-h6aKUerGlX2ATVEeoN03eWaqDqvUmKdedgpxrSoHvrY="
|
||||
},
|
||||
"N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": {
|
||||
"name": "gtk4_layer_shell",
|
||||
@@ -49,10 +49,10 @@
|
||||
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
|
||||
"hash": "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA="
|
||||
},
|
||||
"N-V-__8AACEnAwCkyrJ_XqdomYlR8bpuh0l8WDidEz-BAzIv": {
|
||||
"N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B": {
|
||||
"name": "iterm2_themes",
|
||||
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250922-150534-d28055b/ghostty-themes.tgz",
|
||||
"hash": "sha256-mdhUxAAqKxRRXwED2laabUo9ZZqZa/MZAsO0+Y9L7uQ="
|
||||
"url": "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz",
|
||||
"hash": "sha256-6rKNFpaUvSbvNZ0/+u0h4I/RRaV5V7xIPQ9y7eNVbCA="
|
||||
},
|
||||
"N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x": {
|
||||
"name": "jetbrains_mono",
|
||||
@@ -109,11 +109,6 @@
|
||||
"url": "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz",
|
||||
"hash": "sha256-/8ZooxDndgfTk/PBizJxXyI9oerExNbgV5oR345rWc8="
|
||||
},
|
||||
"uucode-0.1.0-ZZjBPpAFQABNCvd9cVPBg4I7233Ays-NWfWphPNqGbyE": {
|
||||
"name": "uucode",
|
||||
"url": "https://github.com/jacobsandlund/uucode/archive/190706c6b56f0842d29778007f74f7d3d1335fc5.tar.gz",
|
||||
"hash": "sha256-iq9Oyns5e5Tnz2BKPPPTuyJ03BN4bK0dsmSPE1s0wig="
|
||||
},
|
||||
"vaxis-0.1.0-BWNV_FUICQAFZnTCL11TUvnUr1Y0_ZdqtXHhd51d76Rn": {
|
||||
"name": "vaxis",
|
||||
"url": "git+https://github.com/rockorager/libvaxis#1f41c121e8fc153d9ce8c6eb64b2bbab68ad7d23",
|
||||
@@ -169,6 +164,11 @@
|
||||
"url": "git+https://github.com/TUSF/zigimg#31268548fe3276c0e95f318a6c0d2ab10565b58d",
|
||||
"hash": "sha256-oblfr2FIzuqq0FLo/RrzCwUX1NJJuT53EwD3nP3KwN0="
|
||||
},
|
||||
"ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf": {
|
||||
"name": "ziglyph",
|
||||
"url": "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz",
|
||||
"hash": "sha256-cse98+Ft8QUjX+P88yyYfaxJOJGQ9M7Ymw7jFxDz89k="
|
||||
},
|
||||
"N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o": {
|
||||
"name": "zlib",
|
||||
"url": "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz",
|
||||
|
28
build.zig.zon.nix
generated
28
build.zig.zon.nix
generated
@@ -123,11 +123,11 @@ in
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV";
|
||||
name = "gobject-0.3.0-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z";
|
||||
path = fetchZigArtifact {
|
||||
name = "gobject";
|
||||
url = "https://github.com/ghostty-org/zig-gobject/releases/download/2025-09-20-20-1/ghostty-gobject-2025-09-20-20-1.tar.zst";
|
||||
hash = "sha256-SXiqGm81aUn6yq1wFXgNTAULdKOHS/Rzkp5OgNkkcXo=";
|
||||
url = "https://github.com/jcollie/ghostty-gobject/releases/download/0.15.1-2025-09-04-48-1/ghostty-gobject-0.15.1-2025-09-04-48-1.tar.zst";
|
||||
hash = "sha256-h6aKUerGlX2ATVEeoN03eWaqDqvUmKdedgpxrSoHvrY=";
|
||||
};
|
||||
}
|
||||
{
|
||||
@@ -163,11 +163,11 @@ in
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "N-V-__8AACEnAwCkyrJ_XqdomYlR8bpuh0l8WDidEz-BAzIv";
|
||||
name = "N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B";
|
||||
path = fetchZigArtifact {
|
||||
name = "iterm2_themes";
|
||||
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250922-150534-d28055b/ghostty-themes.tgz";
|
||||
hash = "sha256-mdhUxAAqKxRRXwED2laabUo9ZZqZa/MZAsO0+Y9L7uQ=";
|
||||
url = "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz";
|
||||
hash = "sha256-6rKNFpaUvSbvNZ0/+u0h4I/RRaV5V7xIPQ9y7eNVbCA=";
|
||||
};
|
||||
}
|
||||
{
|
||||
@@ -258,14 +258,6 @@ in
|
||||
hash = "sha256-/8ZooxDndgfTk/PBizJxXyI9oerExNbgV5oR345rWc8=";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "uucode-0.1.0-ZZjBPpAFQABNCvd9cVPBg4I7233Ays-NWfWphPNqGbyE";
|
||||
path = fetchZigArtifact {
|
||||
name = "uucode";
|
||||
url = "https://github.com/jacobsandlund/uucode/archive/190706c6b56f0842d29778007f74f7d3d1335fc5.tar.gz";
|
||||
hash = "sha256-iq9Oyns5e5Tnz2BKPPPTuyJ03BN4bK0dsmSPE1s0wig=";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "vaxis-0.1.0-BWNV_FUICQAFZnTCL11TUvnUr1Y0_ZdqtXHhd51d76Rn";
|
||||
path = fetchZigArtifact {
|
||||
@@ -354,6 +346,14 @@ in
|
||||
hash = "sha256-oblfr2FIzuqq0FLo/RrzCwUX1NJJuT53EwD3nP3KwN0=";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf";
|
||||
path = fetchZigArtifact {
|
||||
name = "ziglyph";
|
||||
url = "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz";
|
||||
hash = "sha256-cse98+Ft8QUjX+P88yyYfaxJOJGQ9M7Ymw7jFxDz89k=";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o";
|
||||
path = fetchZigArtifact {
|
||||
|
6
build.zig.zon.txt
generated
6
build.zig.zon.txt
generated
@@ -8,6 +8,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-20250915-162204-b1fe546.tgz
|
||||
https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz
|
||||
https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz
|
||||
https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz
|
||||
@@ -25,10 +26,9 @@ https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.
|
||||
https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz
|
||||
https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz
|
||||
https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.tar.gz
|
||||
https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz
|
||||
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
|
||||
https://github.com/ghostty-org/zig-gobject/releases/download/2025-09-20-20-1/ghostty-gobject-2025-09-20-20-1.tar.zst
|
||||
https://github.com/jacobsandlund/uucode/archive/190706c6b56f0842d29778007f74f7d3d1335fc5.tar.gz
|
||||
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250922-150534-d28055b/ghostty-themes.tgz
|
||||
https://github.com/jcollie/ghostty-gobject/releases/download/0.15.1-2025-09-04-48-1/ghostty-gobject-0.15.1-2025-09-04-48-1.tar.zst
|
||||
https://github.com/mitchellh/libxev/archive/7f803181b158a10fec8619f793e3b4df515566cb.tar.gz
|
||||
https://github.com/mitchellh/zig-objc/archive/c9e917a4e15a983b672ca779c7985d738a2d517c.tar.gz
|
||||
https://github.com/natecraddock/zf/archive/7aacbe6d155d64d15937ca95ca6c014905eb531f.tar.gz
|
||||
|
189
example/app.ts
Normal file
189
example/app.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
import { ZigJS } from "zig-js";
|
||||
|
||||
const zjs = new ZigJS();
|
||||
const importObject = {
|
||||
module: {},
|
||||
env: {
|
||||
memory: new WebAssembly.Memory({
|
||||
initial: 25,
|
||||
maximum: 65536,
|
||||
shared: true,
|
||||
}),
|
||||
log: (ptr: number, len: number) => {
|
||||
const arr = new Uint8ClampedArray(zjs.memory.buffer, ptr, len);
|
||||
const data = arr.slice();
|
||||
const str = new TextDecoder("utf-8").decode(data);
|
||||
console.log(str);
|
||||
},
|
||||
},
|
||||
|
||||
...zjs.importObject(),
|
||||
};
|
||||
|
||||
const url = new URL("ghostty-wasm.wasm", import.meta.url);
|
||||
fetch(url.href)
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then((bytes) => WebAssembly.instantiate(bytes, importObject))
|
||||
.then((results) => {
|
||||
const memory = importObject.env.memory;
|
||||
const {
|
||||
malloc,
|
||||
free,
|
||||
config_new,
|
||||
config_free,
|
||||
config_load_string,
|
||||
config_finalize,
|
||||
face_new,
|
||||
face_free,
|
||||
face_render_glyph,
|
||||
face_debug_canvas,
|
||||
deferred_face_new,
|
||||
deferred_face_free,
|
||||
deferred_face_load,
|
||||
deferred_face_face,
|
||||
group_new,
|
||||
group_free,
|
||||
group_add_face,
|
||||
group_init_sprite_face,
|
||||
group_index_for_codepoint,
|
||||
group_render_glyph,
|
||||
group_cache_new,
|
||||
group_cache_free,
|
||||
group_cache_index_for_codepoint,
|
||||
group_cache_render_glyph,
|
||||
group_cache_atlas_grayscale,
|
||||
group_cache_atlas_color,
|
||||
atlas_new,
|
||||
atlas_free,
|
||||
atlas_debug_canvas,
|
||||
shaper_new,
|
||||
shaper_free,
|
||||
shaper_test,
|
||||
} = results.instance.exports;
|
||||
// Give us access to the zjs value for debugging.
|
||||
globalThis.zjs = zjs;
|
||||
console.log(zjs);
|
||||
|
||||
// Initialize our zig-js memory
|
||||
zjs.memory = memory;
|
||||
|
||||
// Helpers
|
||||
const makeStr = (str) => {
|
||||
const utf8 = new TextEncoder().encode(str);
|
||||
const ptr = malloc(utf8.byteLength);
|
||||
new Uint8Array(memory.buffer, ptr).set(utf8);
|
||||
return { ptr: ptr, len: utf8.byteLength };
|
||||
};
|
||||
|
||||
// Create our config
|
||||
const config = config_new();
|
||||
const config_str = makeStr("font-family = monospace");
|
||||
config_load_string(config, config_str.ptr, config_str.len);
|
||||
config_finalize(config);
|
||||
free(config_str.ptr);
|
||||
|
||||
// Create our atlas
|
||||
// const atlas = atlas_new(512, 0 /* grayscale */);
|
||||
|
||||
// Create some memory for our string
|
||||
const font_name = makeStr("monospace");
|
||||
|
||||
// Initialize our deferred face
|
||||
// const df = deferred_face_new(font_ptr, font.byteLength, 0 /* text */);
|
||||
//deferred_face_load(df, 72 /* size */);
|
||||
//const face = deferred_face_face(df);
|
||||
|
||||
// Initialize our font face
|
||||
//const face = face_new(font_ptr, font.byteLength, 72 /* size in px */);
|
||||
//free(font_ptr);
|
||||
|
||||
// Create our group
|
||||
const group = group_new(32 /* size */);
|
||||
group_add_face(
|
||||
group,
|
||||
0 /* regular */,
|
||||
deferred_face_new(font_name.ptr, font_name.len, 0 /* text */),
|
||||
);
|
||||
group_add_face(
|
||||
group,
|
||||
0 /* regular */,
|
||||
deferred_face_new(font_name.ptr, font_name.len, 1 /* emoji */),
|
||||
);
|
||||
|
||||
// Initialize our sprite font, without this we just use the browser.
|
||||
group_init_sprite_face(group);
|
||||
|
||||
// Create our group cache
|
||||
const group_cache = group_cache_new(group);
|
||||
|
||||
// Render a glyph
|
||||
// for (let i = 33; i <= 126; i++) {
|
||||
// const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
|
||||
// group_cache_render_glyph(group_cache, font_idx, i, 0);
|
||||
// //face_render_glyph(face, atlas, i);
|
||||
// }
|
||||
//
|
||||
// const emoji = ["🐏","🌞","🌚","🍱","💿","🐈","📃","📀","🕡","🙃"];
|
||||
// for (let i = 0; i < emoji.length; i++) {
|
||||
// const cp = emoji[i].codePointAt(0);
|
||||
// const font_idx = group_cache_index_for_codepoint(group_cache, cp, 0, -1 /* best choice */);
|
||||
// group_cache_render_glyph(group_cache, font_idx, cp, 0);
|
||||
// }
|
||||
|
||||
for (let i = 0x2500; i <= 0x257f; i++) {
|
||||
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
|
||||
group_cache_render_glyph(group_cache, font_idx, i, 0);
|
||||
}
|
||||
for (let i = 0x2580; i <= 0x259f; i++) {
|
||||
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
|
||||
group_cache_render_glyph(group_cache, font_idx, i, 0);
|
||||
}
|
||||
for (let i = 0x2800; i <= 0x28ff; i++) {
|
||||
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
|
||||
group_cache_render_glyph(group_cache, font_idx, i, 0);
|
||||
}
|
||||
for (let i = 0x1fb00; i <= 0x1fb3b; i++) {
|
||||
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
|
||||
group_cache_render_glyph(group_cache, font_idx, i, 0);
|
||||
}
|
||||
for (let i = 0x1fb3c; i <= 0x1fb6b; i++) {
|
||||
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
|
||||
group_cache_render_glyph(group_cache, font_idx, i, 0);
|
||||
}
|
||||
|
||||
//face_render_glyph(face, atlas, "橋".codePointAt(0));
|
||||
//face_render_glyph(face, atlas, "p".codePointAt(0));
|
||||
|
||||
// Debug our canvas
|
||||
//face_debug_canvas(face);
|
||||
|
||||
// Let's try shaping
|
||||
const shaper = shaper_new(120);
|
||||
//const input = makeStr("hello🐏");
|
||||
const input = makeStr("hello🐏👍🏽");
|
||||
shaper_test(shaper, group_cache, input.ptr, input.len);
|
||||
|
||||
const cp = 1114112;
|
||||
const font_idx = group_cache_index_for_codepoint(
|
||||
group_cache,
|
||||
cp,
|
||||
0,
|
||||
-1 /* best choice */,
|
||||
);
|
||||
group_cache_render_glyph(group_cache, font_idx, cp, -1);
|
||||
|
||||
// Debug our atlas canvas
|
||||
{
|
||||
const atlas = group_cache_atlas_grayscale(group_cache);
|
||||
const id = atlas_debug_canvas(atlas);
|
||||
document.getElementById("atlas-canvas").append(zjs.deleteValue(id));
|
||||
}
|
||||
|
||||
{
|
||||
const atlas = group_cache_atlas_color(group_cache);
|
||||
const id = atlas_debug_canvas(atlas);
|
||||
document.getElementById("atlas-color-canvas").append(zjs.deleteValue(id));
|
||||
}
|
||||
|
||||
//face_free(face);
|
||||
});
|
@@ -1,17 +0,0 @@
|
||||
# Example: `ghostty-vt` C Program
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` C library
|
||||
with a C program.
|
||||
|
||||
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",
|
||||
.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 = 0x413a8529b1255f9a,
|
||||
.minimum_zig_version = "0.14.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,36 +0,0 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
GhosttyOscParser parser;
|
||||
if (ghostty_osc_new(NULL, &parser) != GHOSTTY_SUCCESS) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Setup change window title command to change the title to "hello"
|
||||
ghostty_osc_next(parser, '0');
|
||||
ghostty_osc_next(parser, ';');
|
||||
const char *title = "hello";
|
||||
for (size_t i = 0; i < strlen(title); i++) {
|
||||
ghostty_osc_next(parser, title[i]);
|
||||
}
|
||||
|
||||
// End parsing and get command
|
||||
GhosttyOscCommand command = ghostty_osc_end(parser, 0);
|
||||
|
||||
// Get and print command type
|
||||
GhosttyOscCommandType type = ghostty_osc_command_type(command);
|
||||
printf("Command type: %d\n", type);
|
||||
|
||||
// Extract and print the title
|
||||
if (ghostty_osc_command_data(command, GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR, &title)) {
|
||||
printf("Extracted title: %s\n", title);
|
||||
} else {
|
||||
printf("Failed to extract title\n");
|
||||
}
|
||||
|
||||
ghostty_osc_free(parser);
|
||||
return 0;
|
||||
}
|
15
example/index.html
Normal file
15
example/index.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Ghostty Example</title>
|
||||
<script type="module" src="app.ts"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Open your console, we are just debugging here.</p>
|
||||
<p>The current <b>grayscale</b> font atlas is rendered below.</p>
|
||||
<div><div id="atlas-canvas" style="display: inline-block; border: 1px solid green;"></div></div>
|
||||
<p>The current <b>color</b> font atlas is rendered below.</p>
|
||||
<div><div id="atlas-color-canvas" style="display: inline-block; border: 1px solid blue;"></div></div>
|
||||
</body>
|
||||
</html>
|
4436
example/package-lock.json
generated
Normal file
4436
example/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
example/package.json
Normal file
22
example/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "ghostty example",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing ghostty and wasm.",
|
||||
"source": "index.html",
|
||||
"browserslist": "> 0.5%, last 2 versions, not dead",
|
||||
"scripts": {
|
||||
"start": "parcel",
|
||||
"build": "parcel build",
|
||||
"check": "tsc --noEmit"
|
||||
},
|
||||
"author": "Mitchell Hashimoto",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@parcel/transformer-inline-string": "^2.8.0",
|
||||
"parcel": "^2.8.0",
|
||||
"typescript": "^4.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"zig-js": "file:../vendor/zig-js/js"
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
# Example: `ghostty-vt` Zig Module
|
||||
|
||||
This contains a simple example of how to use the `ghostty-vt` Zig module
|
||||
exported by Ghostty to have access to a production grade terminal emulator.
|
||||
|
||||
Requires the Zig version stated in the `build.zig.zon` file.
|
||||
|
||||
## Usage
|
||||
|
||||
Run the program:
|
||||
|
||||
```shell-session
|
||||
zig build run
|
||||
```
|
@@ -1,50 +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 test_step = b.step("test", "Run unit tests");
|
||||
|
||||
const exe_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// 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.addImport(
|
||||
"ghostty-vt",
|
||||
dep.module("ghostty-vt"),
|
||||
);
|
||||
}
|
||||
|
||||
// Exe
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "zig_vt",
|
||||
.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);
|
||||
|
||||
// Test
|
||||
const exe_unit_tests = b.addTest(.{
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||
test_step.dependOn(&run_exe_unit_tests.step);
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
.{
|
||||
.name = .zig_vt,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0x6045575a7a8387e6,
|
||||
.minimum_zig_version = "0.14.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,26 +0,0 @@
|
||||
const std = @import("std");
|
||||
const ghostty_vt = @import("ghostty-vt");
|
||||
|
||||
pub fn main() !void {
|
||||
// Use a debug allocator so we get leak checking. You probably want
|
||||
// to replace this for release builds.
|
||||
var gpa: std.heap.DebugAllocator(.{}) = .init;
|
||||
defer _ = gpa.deinit();
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
// Initialize a terminal.
|
||||
var t: ghostty_vt.Terminal = try .init(alloc, .{
|
||||
.cols = 6,
|
||||
.rows = 40,
|
||||
});
|
||||
defer t.deinit(alloc);
|
||||
|
||||
// Write some text. It'll wrap because this is too long for our
|
||||
// columns size above (6).
|
||||
try t.printString("Hello, World!");
|
||||
|
||||
// Get the plain string view of the terminal screen.
|
||||
const str = try t.plainString(alloc);
|
||||
defer alloc.free(str);
|
||||
std.debug.print("{s}\n", .{str});
|
||||
}
|
18
flake.lock
generated
18
flake.lock
generated
@@ -49,15 +49,15 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1758360447,
|
||||
"narHash": "sha256-XDY3A83bclygHDtesRoaRTafUd80Q30D/Daf9KSG6bs=",
|
||||
"rev": "8eaee110344796db060382e15d3af0a9fc396e0e",
|
||||
"lastModified": 1755972213,
|
||||
"narHash": "sha256-VYK7aDAv8H1enXn1ECRHmGbeY6RqLnNwUJkOwloIsko=",
|
||||
"rev": "73e96df7cff5783f45e21342a75a1540c4eddce4",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-25.11pre864002.8eaee1103447/nixexprs.tar.xz"
|
||||
"url": "https://releases.nixos.org/nixos/unstable-small/nixos-25.11pre850642.73e96df7cff5/nixexprs.tar.xz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||
"url": "https://channels.nixos.org/nixos-unstable-small/nixexprs.tar.xz"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
@@ -115,17 +115,17 @@
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1758405547,
|
||||
"narHash": "sha256-WgaDgvIZMPvlZcZrpPMjkaalTBnGF2lTG+62znXctWM=",
|
||||
"lastModified": 1757167408,
|
||||
"narHash": "sha256-4XyJ6fmKd9wgJ7vHUQuULYy5ps2gUgkkDk/PrJb2OPY=",
|
||||
"owner": "jcollie",
|
||||
"repo": "zon2nix",
|
||||
"rev": "bf983aa90ff169372b9fa8c02e57ea75e0b42245",
|
||||
"rev": "dc78177e2ad28d5a407c9e783ee781bd559d7dd5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "jcollie",
|
||||
"repo": "zon2nix",
|
||||
"rev": "bf983aa90ff169372b9fa8c02e57ea75e0b42245",
|
||||
"rev": "dc78177e2ad28d5a407c9e783ee781bd559d7dd5",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@
|
||||
};
|
||||
|
||||
zon2nix = {
|
||||
url = "github:jcollie/zon2nix?rev=bf983aa90ff169372b9fa8c02e57ea75e0b42245";
|
||||
url = "github:jcollie/zon2nix?rev=dc78177e2ad28d5a407c9e783ee781bd559d7dd5";
|
||||
inputs = {
|
||||
# Don't override nixpkgs until Zig 0.15 is available in the Nix branch
|
||||
# we are using for "normal" builds.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
app-id: com.mitchellh.ghostty-debug
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: "49"
|
||||
runtime-version: "48"
|
||||
sdk: org.gnome.Sdk
|
||||
default-branch: tip
|
||||
command: ghostty
|
||||
|
@@ -1,6 +1,6 @@
|
||||
app-id: com.mitchellh.ghostty
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: "49"
|
||||
runtime-version: "48"
|
||||
sdk: org.gnome.Sdk
|
||||
default-branch: tip
|
||||
command: ghostty
|
||||
|
@@ -30,6 +30,19 @@ modules:
|
||||
contents: INPUT(libbz2.so)
|
||||
dest-filename: libbzip2.so
|
||||
|
||||
- name: blueprint-compiler
|
||||
buildsystem: meson
|
||||
cleanup:
|
||||
- "*"
|
||||
sources:
|
||||
- type: git
|
||||
url: https://gitlab.gnome.org/jwestman/blueprint-compiler.git
|
||||
tag: v0.16.0
|
||||
commit: 04ef0944db56ab01307a29aaa7303df6067cb3c0
|
||||
x-checker-data:
|
||||
type: git
|
||||
tag-pattern: ^v([\d.]+)$
|
||||
|
||||
- name: gtk4-layer-shell
|
||||
buildsystem: meson
|
||||
sources:
|
||||
|
@@ -31,9 +31,9 @@
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/ghostty-org/zig-gobject/releases/download/2025-09-20-20-1/ghostty-gobject-2025-09-20-20-1.tar.zst",
|
||||
"dest": "vendor/p/gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV",
|
||||
"sha256": "4978aa1a6f356949facaad7015780d4c050b74a3874bf473929e4e80d924717a"
|
||||
"url": "https://github.com/jcollie/ghostty-gobject/releases/download/0.15.1-2025-09-04-48-1/ghostty-gobject-0.15.1-2025-09-04-48-1.tar.zst",
|
||||
"dest": "vendor/p/gobject-0.3.0-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z",
|
||||
"sha256": "87a68a51eac6957d804d511ea0dd377966aa0eabd498a75e760a71ad2a07beb6"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
@@ -61,9 +61,9 @@
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250922-150534-d28055b/ghostty-themes.tgz",
|
||||
"dest": "vendor/p/N-V-__8AACEnAwCkyrJ_XqdomYlR8bpuh0l8WDidEz-BAzIv",
|
||||
"sha256": "99d854c4002a2b14515f0103da569a6d4a3d659a996bf31902c3b4f98f4beee4"
|
||||
"url": "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz",
|
||||
"dest": "vendor/p/N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B",
|
||||
"sha256": "eab28d169694bd26ef359d3ffaed21e08fd145a57957bc483d0f72ede3556c20"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
@@ -131,12 +131,6 @@
|
||||
"dest": "vendor/p/N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH",
|
||||
"sha256": "ffc668a310e77607d393f3c18b32715f223da1eac4c4d6e0579a11df8e6b59cf"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/jacobsandlund/uucode/archive/190706c6b56f0842d29778007f74f7d3d1335fc5.tar.gz",
|
||||
"dest": "vendor/p/uucode-0.1.0-ZZjBPpAFQABNCvd9cVPBg4I7233Ays-NWfWphPNqGbyE",
|
||||
"sha256": "8aaf4eca7b397b94e7cf604a3cf3d3bb2274dc13786cad1db2648f135b34c228"
|
||||
},
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/rockorager/libvaxis",
|
||||
@@ -203,6 +197,12 @@
|
||||
"commit": "31268548fe3276c0e95f318a6c0d2ab10565b58d",
|
||||
"dest": "vendor/p/zigimg-0.1.0-lly-O6N2EABOxke8dqyzCwhtUCAafqP35zC7wsZ4Ddxj"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz",
|
||||
"dest": "vendor/p/ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf",
|
||||
"sha256": "72c7bdf3e16df105235fe3fcf32c987dac49389190f4ced89b0ee31710f3f3d9"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz",
|
||||
|
@@ -1,455 +0,0 @@
|
||||
/**
|
||||
* @file vt.h
|
||||
*
|
||||
* libghostty-vt - Virtual terminal sequence parsing library
|
||||
*
|
||||
* This library provides functionality for parsing and handling terminal
|
||||
* escape sequences as well as maintaining terminal state such as styles,
|
||||
* cursor position, screen, scrollback, and more.
|
||||
*
|
||||
* WARNING: This is an incomplete, work-in-progress API. It is not yet
|
||||
* stable and is definitely going to change.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage libghostty-vt - Virtual Terminal Sequence Parser
|
||||
*
|
||||
* libghostty-vt is a C library which implements a modern terminal emulator,
|
||||
* extracted from the [Ghostty](https://ghostty.org) terminal emulator.
|
||||
*
|
||||
* libghostty-vt contains the logic for handling the core parts of a terminal
|
||||
* emulator: parsing terminal escape sequences and maintaining terminal state.
|
||||
* It can handle scrollback, line wrapping, reflow on resize, and more.
|
||||
*
|
||||
* @warning This library is currently in development and the API is not yet stable.
|
||||
* Breaking changes are expected in future versions. Use with caution in production code.
|
||||
*
|
||||
* @section groups_sec API Reference
|
||||
*
|
||||
* The API is organized into the following groups:
|
||||
* - @ref osc "OSC Parser" - Parse OSC (Operating System Command) sequences
|
||||
* - @ref allocator "Memory Management" - Memory management and custom allocators
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_H
|
||||
#define GHOSTTY_VT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
/**
|
||||
* Opaque handle to an OSC parser instance.
|
||||
*
|
||||
* This handle represents an OSC (Operating System Command) parser that can
|
||||
* be used to parse the contents of OSC sequences. This isn't a full VT
|
||||
* parser; it is only the OSC parser component. This is useful if you have
|
||||
* a parser already and want to only extract and handle OSC sequences.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef struct GhosttyOscParser *GhosttyOscParser;
|
||||
|
||||
/**
|
||||
* Opaque handle to a single OSC command.
|
||||
*
|
||||
* This handle represents a parsed OSC (Operating System Command) command.
|
||||
* The command can be queried for its type and associated data using
|
||||
* `ghostty_osc_command_type` and `ghostty_osc_command_data`.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef struct GhosttyOscCommand *GhosttyOscCommand;
|
||||
|
||||
/**
|
||||
* Result codes for libghostty-vt operations.
|
||||
*/
|
||||
typedef enum {
|
||||
/** Operation completed successfully */
|
||||
GHOSTTY_SUCCESS = 0,
|
||||
/** Operation failed due to failed allocation */
|
||||
GHOSTTY_OUT_OF_MEMORY = -1,
|
||||
} GhosttyResult;
|
||||
|
||||
/**
|
||||
* OSC command types.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef enum {
|
||||
GHOSTTY_OSC_COMMAND_INVALID = 0,
|
||||
GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE = 1,
|
||||
GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_ICON = 2,
|
||||
GHOSTTY_OSC_COMMAND_PROMPT_START = 3,
|
||||
GHOSTTY_OSC_COMMAND_PROMPT_END = 4,
|
||||
GHOSTTY_OSC_COMMAND_END_OF_INPUT = 5,
|
||||
GHOSTTY_OSC_COMMAND_END_OF_COMMAND = 6,
|
||||
GHOSTTY_OSC_COMMAND_CLIPBOARD_CONTENTS = 7,
|
||||
GHOSTTY_OSC_COMMAND_REPORT_PWD = 8,
|
||||
GHOSTTY_OSC_COMMAND_MOUSE_SHAPE = 9,
|
||||
GHOSTTY_OSC_COMMAND_COLOR_OPERATION = 10,
|
||||
GHOSTTY_OSC_COMMAND_KITTY_COLOR_PROTOCOL = 11,
|
||||
GHOSTTY_OSC_COMMAND_SHOW_DESKTOP_NOTIFICATION = 12,
|
||||
GHOSTTY_OSC_COMMAND_HYPERLINK_START = 13,
|
||||
GHOSTTY_OSC_COMMAND_HYPERLINK_END = 14,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_SLEEP = 15,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_SHOW_MESSAGE_BOX = 16,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_CHANGE_TAB_TITLE = 17,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_PROGRESS_REPORT = 18,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_WAIT_INPUT = 19,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_GUIMACRO = 20,
|
||||
} GhosttyOscCommandType;
|
||||
|
||||
/**
|
||||
* OSC command data types.
|
||||
*
|
||||
* These values specify what type of data to extract from an OSC command
|
||||
* using `ghostty_osc_command_data`.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef enum {
|
||||
/** Invalid data type. Never results in any data extraction. */
|
||||
GHOSTTY_OSC_DATA_INVALID = 0,
|
||||
|
||||
/**
|
||||
* Window title string data.
|
||||
*
|
||||
* Valid for: GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE
|
||||
*
|
||||
* Output type: const char ** (pointer to null-terminated string)
|
||||
*
|
||||
* Lifetime: Valid until the next call to any ghostty_osc_* function with
|
||||
* the same parser instance. Memory is owned by the parser.
|
||||
*/
|
||||
GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR = 1,
|
||||
} GhosttyOscCommandData;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Allocator Interface
|
||||
|
||||
/** @defgroup allocator Memory Management
|
||||
*
|
||||
* libghostty-vt does require memory allocation for various operations,
|
||||
* but is resilient to allocation failures and will gracefully handle
|
||||
* out-of-memory situations by returning error codes.
|
||||
*
|
||||
* The exact memory management semantics are documented in the relevant
|
||||
* functions and data structures.
|
||||
*
|
||||
* libghostty-vt uses explicit memory allocation via an allocator
|
||||
* interface provided by GhosttyAllocator. The interface is based on the
|
||||
* [Zig](https://ziglang.org) allocator interface, since this has been
|
||||
* shown to be a flexible and powerful interface in practice and enables
|
||||
* a wide variety of allocation strategies.
|
||||
*
|
||||
* **For the common case, you can pass NULL as the allocator for any
|
||||
* function that accepts one,** and libghostty will use a default allocator.
|
||||
* The default allocator will be libc malloc/free if libc is linked.
|
||||
* Otherwise, a custom allocator is used (currently Zig's SMP allocator)
|
||||
* that doesn't require any external dependencies.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* For simple use cases, you can ignore this interface entirely by passing NULL
|
||||
* as the allocator parameter to functions that accept one. This will use the
|
||||
* default allocator (typically libc malloc/free, if libc is linked, but
|
||||
* we provide our own default allocator if libc isn't linked).
|
||||
*
|
||||
* To use a custom allocator:
|
||||
* 1. Implement the GhosttyAllocatorVtable function pointers
|
||||
* 2. Create a GhosttyAllocator struct with your vtable and context
|
||||
* 3. Pass the allocator to functions that accept one
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function table for custom memory allocator operations.
|
||||
*
|
||||
* This vtable defines the interface for a custom memory allocator. All
|
||||
* function pointers must be valid and non-NULL.
|
||||
*
|
||||
* @ingroup allocator
|
||||
*
|
||||
* If you're not going to use a custom allocator, you can ignore all of
|
||||
* this. All functions that take an allocator pointer allow NULL to use a
|
||||
* default allocator.
|
||||
*
|
||||
* The interface is based on the Zig allocator interface. I'll say up front
|
||||
* that it is easy to look at this interface and think "wow, this is really
|
||||
* overcomplicated". The reason for this complexity is well thought out by
|
||||
* the Zig folks, and it enables a diverse set of allocation strategies
|
||||
* as shown by the Zig ecosystem. As a consolation, please note that many
|
||||
* of the arguments are only needed for advanced use cases and can be
|
||||
* safely ignored in simple implementations. For example, if you look at
|
||||
* the Zig implementation of the libc allocator in `lib/std/heap.zig`
|
||||
* (search for CAllocator), you'll see it is very simple.
|
||||
*
|
||||
* We chose to align with the Zig allocator interface because:
|
||||
*
|
||||
* 1. It is a proven interface that serves a wide variety of use cases
|
||||
* in the real world via the Zig ecosystem. It's shown to work.
|
||||
*
|
||||
* 2. Our core implementation itself is Zig, and this lets us very
|
||||
* cheaply and easily convert between C and Zig allocators.
|
||||
*
|
||||
* NOTE(mitchellh): In the future, we can have default implementations of
|
||||
* resize/remap and allow those to be null.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Return a pointer to `len` bytes with specified `alignment`, or return
|
||||
* `NULL` indicating the allocation failed.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param len Number of bytes to allocate
|
||||
* @param alignment Required alignment for the allocation. Guaranteed to
|
||||
* be a power of two between 1 and 16 inclusive.
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
* @return Pointer to allocated memory, or NULL if allocation failed
|
||||
*/
|
||||
void* (*alloc)(void *ctx, size_t len, uint8_t alignment, uintptr_t ret_addr);
|
||||
|
||||
/**
|
||||
* Attempt to expand or shrink memory in place.
|
||||
*
|
||||
* `memory_len` must equal the length requested from the most recent
|
||||
* successful call to `alloc`, `resize`, or `remap`. `alignment` must
|
||||
* equal the same value that was passed as the `alignment` parameter to
|
||||
* the original `alloc` call.
|
||||
*
|
||||
* `new_len` must be greater than zero.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param memory Pointer to the memory block to resize
|
||||
* @param memory_len Current size of the memory block
|
||||
* @param alignment Alignment (must match original allocation)
|
||||
* @param new_len New requested size
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
* @return true if resize was successful in-place, false if relocation would be required
|
||||
*/
|
||||
bool (*resize)(void *ctx, void *memory, size_t memory_len, uint8_t alignment, size_t new_len, uintptr_t ret_addr);
|
||||
|
||||
/**
|
||||
* Attempt to expand or shrink memory, allowing relocation.
|
||||
*
|
||||
* `memory_len` must equal the length requested from the most recent
|
||||
* successful call to `alloc`, `resize`, or `remap`. `alignment` must
|
||||
* equal the same value that was passed as the `alignment` parameter to
|
||||
* the original `alloc` call.
|
||||
*
|
||||
* A non-`NULL` return value indicates the resize was successful. The
|
||||
* allocation may have same address, or may have been relocated. In either
|
||||
* case, the allocation now has size of `new_len`. A `NULL` return value
|
||||
* indicates that the resize would be equivalent to allocating new memory,
|
||||
* copying the bytes from the old memory, and then freeing the old memory.
|
||||
* In such case, it is more efficient for the caller to perform the copy.
|
||||
*
|
||||
* `new_len` must be greater than zero.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param memory Pointer to the memory block to remap
|
||||
* @param memory_len Current size of the memory block
|
||||
* @param alignment Alignment (must match original allocation)
|
||||
* @param new_len New requested size
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
* @return Pointer to resized memory (may be relocated), or NULL if manual copy is needed
|
||||
*/
|
||||
void* (*remap)(void *ctx, void *memory, size_t memory_len, uint8_t alignment, size_t new_len, uintptr_t ret_addr);
|
||||
|
||||
/**
|
||||
* Free and invalidate a region of memory.
|
||||
*
|
||||
* `memory_len` must equal the length requested from the most recent
|
||||
* successful call to `alloc`, `resize`, or `remap`. `alignment` must
|
||||
* equal the same value that was passed as the `alignment` parameter to
|
||||
* the original `alloc` call.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param memory Pointer to the memory block to free
|
||||
* @param memory_len Size of the memory block
|
||||
* @param alignment Alignment (must match original allocation)
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
*/
|
||||
void (*free)(void *ctx, void *memory, size_t memory_len, uint8_t alignment, uintptr_t ret_addr);
|
||||
} GhosttyAllocatorVtable;
|
||||
|
||||
/**
|
||||
* Custom memory allocator.
|
||||
*
|
||||
* For functions that take an allocator pointer, a NULL pointer indicates
|
||||
* that the default allocator should be used. The default allocator will
|
||||
* be libc malloc/free if we're linking to libc. If libc isn't linked,
|
||||
* a custom allocator is used (currently Zig's SMP allocator).
|
||||
*
|
||||
* @ingroup allocator
|
||||
*
|
||||
* Usage example:
|
||||
* @code
|
||||
* GhosttyAllocator allocator = {
|
||||
* .vtable = &my_allocator_vtable,
|
||||
* .ctx = my_allocator_state
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Opaque context pointer passed to all vtable functions.
|
||||
* This allows the allocator implementation to maintain state
|
||||
* or reference external resources needed for memory management.
|
||||
*/
|
||||
void *ctx;
|
||||
|
||||
/**
|
||||
* Pointer to the allocator's vtable containing function pointers
|
||||
* for memory operations (alloc, resize, remap, free).
|
||||
*/
|
||||
const GhosttyAllocatorVtable *vtable;
|
||||
} GhosttyAllocator;
|
||||
|
||||
/** @} */ // end of allocator group
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
/** @defgroup osc OSC Parser
|
||||
*
|
||||
* OSC (Operating System Command) sequence parser and command handling.
|
||||
*
|
||||
* The parser operates in a streaming fashion, processing input byte-by-byte
|
||||
* to handle OSC sequences that may arrive in fragments across multiple reads.
|
||||
* This interface makes it easy to integrate into most environments and avoids
|
||||
* over-allocating buffers.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* 1. Create a parser instance with ghostty_osc_new()
|
||||
* 2. Feed bytes to the parser using ghostty_osc_next()
|
||||
* 3. Finalize parsing with ghostty_osc_end() to get the command
|
||||
* 4. Query command type and extract data using ghostty_osc_command_type()
|
||||
* and ghostty_osc_command_data()
|
||||
* 5. Free the parser with ghostty_osc_free() when done
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new OSC parser instance.
|
||||
*
|
||||
* Creates a new OSC (Operating System Command) parser using the provided
|
||||
* allocator. The parser must be freed using ghostty_vt_osc_free() when
|
||||
* no longer needed.
|
||||
*
|
||||
* @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator
|
||||
* @param parser Pointer to store the created parser handle
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*/
|
||||
GhosttyResult ghostty_osc_new(const GhosttyAllocator *allocator, GhosttyOscParser *parser);
|
||||
|
||||
/**
|
||||
* Free an OSC parser instance.
|
||||
*
|
||||
* Releases all resources associated with the OSC parser. After this call,
|
||||
* the parser handle becomes invalid and must not be used.
|
||||
*
|
||||
* @param parser The parser handle to free (may be NULL)
|
||||
*/
|
||||
void ghostty_osc_free(GhosttyOscParser parser);
|
||||
|
||||
/**
|
||||
* Reset an OSC parser instance to its initial state.
|
||||
*
|
||||
* Resets the parser state, clearing any partially parsed OSC sequences
|
||||
* and returning the parser to its initial state. This is useful for
|
||||
* reusing a parser instance or recovering from parse errors.
|
||||
*
|
||||
* @param parser The parser handle to reset, must not be null.
|
||||
*/
|
||||
void ghostty_osc_reset(GhosttyOscParser parser);
|
||||
|
||||
/**
|
||||
* Parse the next byte in an OSC sequence.
|
||||
*
|
||||
* Processes a single byte as part of an OSC sequence. The parser maintains
|
||||
* internal state to track the progress through the sequence. Call this
|
||||
* function for each byte in the sequence data.
|
||||
*
|
||||
* When finished pumping the parser with bytes, call ghostty_osc_end
|
||||
* to get the final result.
|
||||
*
|
||||
* @param parser The parser handle, must not be null.
|
||||
* @param byte The next byte to parse
|
||||
*/
|
||||
void ghostty_osc_next(GhosttyOscParser parser, uint8_t byte);
|
||||
|
||||
/**
|
||||
* Finalize OSC parsing and retrieve the parsed command.
|
||||
*
|
||||
* Call this function after feeding all bytes of an OSC sequence to the parser
|
||||
* using ghostty_osc_next() with the exception of the terminating character
|
||||
* (ESC or ST). This function finalizes the parsing process and returns the
|
||||
* parsed OSC command.
|
||||
*
|
||||
* The return value is never NULL. Invalid commands will return a command
|
||||
* with type GHOSTTY_OSC_COMMAND_INVALID.
|
||||
*
|
||||
* The terminator parameter specifies the byte that terminated the OSC sequence
|
||||
* (typically 0x07 for BEL or 0x5C for ST after ESC). This information is
|
||||
* preserved in the parsed command so that responses can use the same terminator
|
||||
* format for better compatibility with the calling program. For commands that
|
||||
* do not require a response, this parameter is ignored and the resulting
|
||||
* command will not retain the terminator information.
|
||||
*
|
||||
* The returned command handle is valid until the next call to any
|
||||
* `ghostty_osc_*` function with the same parser instance with the exception
|
||||
* of command introspection functions such as `ghostty_osc_command_type`.
|
||||
*
|
||||
* @param parser The parser handle, must not be null.
|
||||
* @param terminator The terminating byte of the OSC sequence (0x07 for BEL, 0x5C for ST)
|
||||
* @return Handle to the parsed OSC command
|
||||
*/
|
||||
GhosttyOscCommand ghostty_osc_end(GhosttyOscParser parser, uint8_t terminator);
|
||||
|
||||
/**
|
||||
* Get the type of an OSC command.
|
||||
*
|
||||
* Returns the type identifier for the given OSC command. This can be used
|
||||
* to determine what kind of command was parsed and what data might be
|
||||
* available from it.
|
||||
*
|
||||
* @param command The OSC command handle to query (may be NULL)
|
||||
* @return The command type, or GHOSTTY_OSC_COMMAND_INVALID if command is NULL
|
||||
*/
|
||||
GhosttyOscCommandType ghostty_osc_command_type(GhosttyOscCommand command);
|
||||
|
||||
/**
|
||||
* Extract data from an OSC command.
|
||||
*
|
||||
* Extracts typed data from the given OSC command based on the specified
|
||||
* data type. The output pointer must be of the appropriate type for the
|
||||
* requested data kind. Valid command types, output types, and memory
|
||||
* safety information are documented in the `GhosttyOscCommandData` enum.
|
||||
*
|
||||
* @param command The OSC command handle to query (may be NULL)
|
||||
* @param data The type of data to extract
|
||||
* @param out Pointer to store the extracted data (type depends on data parameter)
|
||||
* @return true if data extraction was successful, false otherwise
|
||||
*/
|
||||
bool ghostty_osc_command_data(GhosttyOscCommand command, GhosttyOscCommandData data, void *out);
|
||||
|
||||
/** @} */ // end of osc group
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_H */
|
@@ -10,19 +10,147 @@
|
||||
29C15B1D2CDC3B2900520DD4 /* bat in Resources */ = {isa = PBXBuildFile; fileRef = 29C15B1C2CDC3B2000520DD4 /* bat */; };
|
||||
55154BE02B33911F001622DC /* ghostty in Resources */ = {isa = PBXBuildFile; fileRef = 55154BDF2B33911F001622DC /* ghostty */; };
|
||||
552964E62B34A9B400030505 /* vim in Resources */ = {isa = PBXBuildFile; fileRef = 552964E52B34A9B400030505 /* vim */; };
|
||||
857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 857F63802A5E64F200CA4815 /* MainMenu.xib */; };
|
||||
9351BE8E3D22937F003B3499 /* nvim in Resources */ = {isa = PBXBuildFile; fileRef = 9351BE8E2D22937F003B3499 /* nvim */; };
|
||||
A50297352DFA0F3400B4E924 /* Double+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50297342DFA0F3300B4E924 /* Double+Extension.swift */; };
|
||||
A505D21D2E1A2FA20018808F /* FileHandle+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A505D21C2E1A2F9E0018808F /* FileHandle+Extension.swift */; };
|
||||
A505D21F2E1B6DE00018808F /* NSWorkspace+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A505D21E2E1B6DDC0018808F /* NSWorkspace+Extension.swift */; };
|
||||
A511940F2E050595007258CC /* CloseTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A511940E2E050590007258CC /* CloseTerminalIntent.swift */; };
|
||||
A51194112E05A483007258CC /* QuickTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194102E05A480007258CC /* QuickTerminalIntent.swift */; };
|
||||
A51194132E05D006007258CC /* Optional+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194122E05D003007258CC /* Optional+Extension.swift */; };
|
||||
A51194172E05D964007258CC /* PermissionRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194162E05D95E007258CC /* PermissionRequest.swift */; };
|
||||
A51194192E05DFC4007258CC /* IntentPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194182E05DFBB007258CC /* IntentPermission.swift */; };
|
||||
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
||||
A514C8D72B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
||||
A514C8D82B54DC6800493A16 /* Ghostty.App.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */; };
|
||||
A51544FE2DFB111C009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51544FD2DFB1110009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift */; };
|
||||
A51545002DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib in Resources */ = {isa = PBXBuildFile; fileRef = A51544FF2DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib */; };
|
||||
A51B78472AF4B58B00F3EDB9 /* TitlebarTabsVenturaTerminalWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51B78462AF4B58B00F3EDB9 /* TitlebarTabsVenturaTerminalWindow.swift */; };
|
||||
A51BFC1E2B2FB5CE00E92F16 /* About.xib in Resources */ = {isa = PBXBuildFile; fileRef = A51BFC1D2B2FB5CE00E92F16 /* About.xib */; };
|
||||
A51BFC202B2FB64F00E92F16 /* AboutController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51BFC1F2B2FB64F00E92F16 /* AboutController.swift */; };
|
||||
A51BFC222B2FB6B400E92F16 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51BFC212B2FB6B400E92F16 /* AboutView.swift */; };
|
||||
A51BFC272B30F1B800E92F16 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = A51BFC262B30F1B800E92F16 /* Sparkle */; };
|
||||
A51BFC2B2B30F6BE00E92F16 /* UpdateDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51BFC2A2B30F6BE00E92F16 /* UpdateDelegate.swift */; };
|
||||
A5278A9B2AA05B2600CD3039 /* Ghostty.Input.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5278A9A2AA05B2600CD3039 /* Ghostty.Input.swift */; };
|
||||
A52FFF572CA90484000C6A5B /* QuickTerminalScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A52FFF562CA90481000C6A5B /* QuickTerminalScreen.swift */; };
|
||||
A52FFF592CAA4FF3000C6A5B /* Fullscreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A52FFF582CAA4FF1000C6A5B /* Fullscreen.swift */; };
|
||||
A52FFF5B2CAA54B1000C6A5B /* FullscreenMode+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A52FFF5A2CAA54A8000C6A5B /* FullscreenMode+Extension.swift */; };
|
||||
A52FFF5D2CAB4D08000C6A5B /* NSScreen+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A52FFF5C2CAB4D05000C6A5B /* NSScreen+Extension.swift */; };
|
||||
A5333E1C2B5A1CE3008AEFF7 /* CrossKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5333E1B2B5A1CE3008AEFF7 /* CrossKit.swift */; };
|
||||
A5333E1D2B5A1CE3008AEFF7 /* CrossKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5333E1B2B5A1CE3008AEFF7 /* CrossKit.swift */; };
|
||||
A5333E202B5A2111008AEFF7 /* SurfaceView_UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5333E152B59DE8E008AEFF7 /* SurfaceView_UIKit.swift */; };
|
||||
A5333E222B5A2128008AEFF7 /* SurfaceView_AppKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5333E212B5A2128008AEFF7 /* SurfaceView_AppKit.swift */; };
|
||||
A5333E232B5A219A008AEFF7 /* SurfaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BBB29B6FC330055DE60 /* SurfaceView.swift */; };
|
||||
A5333E242B5A22D9008AEFF7 /* Ghostty.Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A56D58852ACDDB4100508D2C /* Ghostty.Shell.swift */; };
|
||||
A53426352A7DA53D00EBB7A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */; };
|
||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
||||
A53A297B2DB2E49700B6E02C /* CommandPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A297A2DB2E49400B6E02C /* CommandPalette.swift */; };
|
||||
A53A297F2DB4480F00B6E02C /* EventModifiers+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */; };
|
||||
A53A29812DB44A6100B6E02C /* KeyboardShortcut+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */; };
|
||||
A53A29882DB69D2F00B6E02C /* TerminalCommandPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A29872DB69D2C00B6E02C /* TerminalCommandPalette.swift */; };
|
||||
A53A6C032CCC1B7F00943E98 /* Ghostty.Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A6C022CCC1B7D00943E98 /* Ghostty.Action.swift */; };
|
||||
A53D0C8E2B53B0EA00305CE6 /* GhosttyKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */; };
|
||||
A53D0C942B53B43700305CE6 /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53D0C932B53B43700305CE6 /* iOSApp.swift */; };
|
||||
A53D0C952B53B4D800305CE6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; };
|
||||
A53D0C9B2B543F3B00305CE6 /* Ghostty.App.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */; };
|
||||
A53D0C9C2B543F7B00305CE6 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB729B6F53A0055DE60 /* Package.swift */; };
|
||||
A546F1142D7B68D7003B11A0 /* locale in Resources */ = {isa = PBXBuildFile; fileRef = A546F1132D7B68D7003B11A0 /* locale */; };
|
||||
A54B0CE92D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CE82D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift */; };
|
||||
A54B0CEB2D0CFB4C00CBEFF8 /* NSImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CEA2D0CFB4A00CBEFF8 /* NSImage+Extension.swift */; };
|
||||
A54B0CED2D0CFB7700CBEFF8 /* ColorizedGhosttyIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CEC2D0CFB7300CBEFF8 /* ColorizedGhosttyIcon.swift */; };
|
||||
A54B0CEF2D0D2E2800CBEFF8 /* ColorizedGhosttyIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CEE2D0D2E2400CBEFF8 /* ColorizedGhosttyIconImage.swift */; };
|
||||
A54D786C2CA7978E001B19B1 /* BaseTerminalController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54D786B2CA79788001B19B1 /* BaseTerminalController.swift */; };
|
||||
A553F4062E05E93000257779 /* Optional+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194122E05D003007258CC /* Optional+Extension.swift */; };
|
||||
A553F4072E05E93D00257779 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A586366A2DF0A98900E04A10 /* Array+Extension.swift */; };
|
||||
A553F4132E06EB1600257779 /* Ghostty.icon in Resources */ = {isa = PBXBuildFile; fileRef = A553F4122E06EB1600257779 /* Ghostty.icon */; };
|
||||
A553F4142E06EB1600257779 /* Ghostty.icon in Resources */ = {isa = PBXBuildFile; fileRef = A553F4122E06EB1600257779 /* Ghostty.icon */; };
|
||||
A5593FDF2DF8D57C00B47B10 /* TerminalWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5593FDE2DF8D57100B47B10 /* TerminalWindow.swift */; };
|
||||
A5593FE12DF8D74000B47B10 /* HiddenTitlebarTerminalWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5593FE02DF8D73400B47B10 /* HiddenTitlebarTerminalWindow.swift */; };
|
||||
A5593FE32DF8D78600B47B10 /* TerminalHiddenTitlebar.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5593FE22DF8D78600B47B10 /* TerminalHiddenTitlebar.xib */; };
|
||||
A5593FE52DF8DE3000B47B10 /* TerminalTabsTitlebarVentura.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5593FE42DF8DE3000B47B10 /* TerminalTabsTitlebarVentura.xib */; };
|
||||
A5593FE72DF927D200B47B10 /* TransparentTitlebarTerminalWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5593FE62DF927CC00B47B10 /* TransparentTitlebarTerminalWindow.swift */; };
|
||||
A5593FE92DF927DF00B47B10 /* TerminalTransparentTitlebar.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5593FE82DF927DF00B47B10 /* TerminalTransparentTitlebar.xib */; };
|
||||
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB729B6F53A0055DE60 /* Package.swift */; };
|
||||
A55B7BBC29B6FC330055DE60 /* SurfaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BBB29B6FC330055DE60 /* SurfaceView.swift */; };
|
||||
A56B880B2A840447007A0E29 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A56B880A2A840447007A0E29 /* Carbon.framework */; };
|
||||
A56D58862ACDDB4100508D2C /* Ghostty.Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A56D58852ACDDB4100508D2C /* Ghostty.Shell.swift */; };
|
||||
A56D58892ACDE6CA00508D2C /* ServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A56D58882ACDE6CA00508D2C /* ServiceProvider.swift */; };
|
||||
A571AB1D2A206FCF00248498 /* GhosttyKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */; };
|
||||
A57D79272C9C879B001D522E /* SecureInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57D79262C9C8798001D522E /* SecureInput.swift */; };
|
||||
A586167C2B7703CC009BDB1D /* fish in Resources */ = {isa = PBXBuildFile; fileRef = A586167B2B7703CC009BDB1D /* fish */; };
|
||||
A586365F2DEE6C2300E04A10 /* SplitTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = A586365E2DEE6C2100E04A10 /* SplitTree.swift */; };
|
||||
A58636662DEF964100E04A10 /* TerminalSplitTreeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58636652DEF963F00E04A10 /* TerminalSplitTreeView.swift */; };
|
||||
A586366B2DF0A98C00E04A10 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A586366A2DF0A98900E04A10 /* Array+Extension.swift */; };
|
||||
A586366F2DF25D8600E04A10 /* Duration+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A586366E2DF25D8300E04A10 /* Duration+Extension.swift */; };
|
||||
A58636712DF298FB00E04A10 /* ExpiringUndoManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58636702DF298F700E04A10 /* ExpiringUndoManager.swift */; };
|
||||
A58636732DF4813400E04A10 /* UndoManager+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58636722DF4813000E04A10 /* UndoManager+Extension.swift */; };
|
||||
A5874D992DAD751B00E83852 /* CGS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5874D982DAD751A00E83852 /* CGS.swift */; };
|
||||
A5874D9D2DAD786100E83852 /* NSWindow+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5874D9C2DAD785F00E83852 /* NSWindow+Extension.swift */; };
|
||||
A59444F729A2ED5200725BBA /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59444F629A2ED5200725BBA /* SettingsView.swift */; };
|
||||
A59630972AEE163600D64628 /* HostingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59630962AEE163600D64628 /* HostingWindow.swift */; };
|
||||
A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */ = {isa = PBXBuildFile; fileRef = A59630992AEE1C6400D64628 /* Terminal.xib */; };
|
||||
A596309C2AEE1C9E00D64628 /* TerminalController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A596309B2AEE1C9E00D64628 /* TerminalController.swift */; };
|
||||
A596309E2AEE1D6C00D64628 /* TerminalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A596309D2AEE1D6C00D64628 /* TerminalView.swift */; };
|
||||
A5985CD72C320C4500C57AD3 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5985CD62C320C4500C57AD3 /* String+Extension.swift */; };
|
||||
A5985CD82C320C4500C57AD3 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5985CD62C320C4500C57AD3 /* String+Extension.swift */; };
|
||||
A5985CE62C33060F00C57AD3 /* man in Resources */ = {isa = PBXBuildFile; fileRef = A5985CE52C33060F00C57AD3 /* man */; };
|
||||
A599CDB02CF103F60049FA26 /* NSAppearance+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A599CDAF2CF103F20049FA26 /* NSAppearance+Extension.swift */; };
|
||||
A59FB5CF2AE0DB50009128F3 /* InspectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59FB5CE2AE0DB50009128F3 /* InspectorView.swift */; };
|
||||
A59FB5D12AE0DEA7009128F3 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59FB5D02AE0DEA7009128F3 /* MetalView.swift */; };
|
||||
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */ = {isa = PBXBuildFile; fileRef = A5A1F8842A489D6800D1E8BC /* terminfo */; };
|
||||
A5A2A3CA2D4445E30033CF96 /* Dock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A2A3C92D4445E20033CF96 /* Dock.swift */; };
|
||||
A5A2A3CC2D444ABB0033CF96 /* NSApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */; };
|
||||
A5A6F72A2CC41B8900B232A5 /* AppInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A6F7292CC41B8700B232A5 /* AppInfo.swift */; };
|
||||
A5AEB1652D5BE7D000513529 /* LastWindowPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5AEB1642D5BE7BF00513529 /* LastWindowPosition.swift */; };
|
||||
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; };
|
||||
A5B4EA852DFE691B0022C3A2 /* NSMenuItem+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B4EA842DFE69140022C3A2 /* NSMenuItem+Extension.swift */; };
|
||||
A5BB78B92DF9D8CE009AC3FA /* QuickTerminalSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5BB78B82DF9D8CE009AC3FA /* QuickTerminalSize.swift */; };
|
||||
A5CA378C2D2A4DEB00931030 /* KeyboardLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */; };
|
||||
A5CA378E2D31D6C300931030 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378D2D31D6C100931030 /* Weak.swift */; };
|
||||
A5CBD0562C9E65B80017A1AE /* DraggableWindowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CBD0552C9E65A50017A1AE /* DraggableWindowView.swift */; };
|
||||
A5CBD0582C9F30960017A1AE /* Cursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CBD0572C9F30860017A1AE /* Cursor.swift */; };
|
||||
A5CBD0592C9F37B10017A1AE /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFFE29C2410700646FDA /* Backport.swift */; };
|
||||
A5CBD05C2CA0C5C70017A1AE /* QuickTerminal.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5CBD05B2CA0C5C70017A1AE /* QuickTerminal.xib */; };
|
||||
A5CBD05E2CA0C5EC0017A1AE /* QuickTerminalController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CBD05D2CA0C5E70017A1AE /* QuickTerminalController.swift */; };
|
||||
A5CBD0602CA0C90A0017A1AE /* QuickTerminalWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CBD05F2CA0C9080017A1AE /* QuickTerminalWindow.swift */; };
|
||||
A5CBD0642CA122E70017A1AE /* QuickTerminalPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CBD0632CA122E70017A1AE /* QuickTerminalPosition.swift */; };
|
||||
A5CBD06B2CA322430017A1AE /* GlobalEventTap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CBD06A2CA322320017A1AE /* GlobalEventTap.swift */; };
|
||||
A5CC36132C9CD72D004D6760 /* SecureInputOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CC36122C9CD729004D6760 /* SecureInputOverlay.swift */; };
|
||||
A5CC36152C9CDA06004D6760 /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CC36142C9CDA03004D6760 /* View+Extension.swift */; };
|
||||
A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5CDF1902AAF9A5800513312 /* ConfigurationErrors.xib */; };
|
||||
A5CDF1932AAF9E0800513312 /* ConfigurationErrorsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CDF1922AAF9E0800513312 /* ConfigurationErrorsController.swift */; };
|
||||
A5CDF1952AAFA19600513312 /* ConfigurationErrorsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CDF1942AAFA19600513312 /* ConfigurationErrorsView.swift */; };
|
||||
A5CEAFDC29B8009000646FDA /* SplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFDB29B8009000646FDA /* SplitView.swift */; };
|
||||
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFDD29B8058B00646FDA /* SplitView.Divider.swift */; };
|
||||
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFFE29C2410700646FDA /* Backport.swift */; };
|
||||
A5CF66D42D289CEE00139794 /* NSEvent+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CF66D32D289CEA00139794 /* NSEvent+Extension.swift */; };
|
||||
A5CF66D72D29DDB500139794 /* Ghostty.Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CF66D62D29DDB100139794 /* Ghostty.Event.swift */; };
|
||||
A5D0AF3B2B36A1DE00D21823 /* TerminalRestorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D0AF3A2B36A1DE00D21823 /* TerminalRestorable.swift */; };
|
||||
A5D0AF3D2B37804400D21823 /* CodableBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D0AF3C2B37804400D21823 /* CodableBridge.swift */; };
|
||||
A5D689BE2E654D98002E2346 /* Ghostty.Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A6C022CCC1B7D00943E98 /* Ghostty.Action.swift */; };
|
||||
A5E112932AF73E6E00C6E0C2 /* ClipboardConfirmation.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5E112922AF73E6E00C6E0C2 /* ClipboardConfirmation.xib */; };
|
||||
A5E112952AF73E8A00C6E0C2 /* ClipboardConfirmationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E112942AF73E8A00C6E0C2 /* ClipboardConfirmationController.swift */; };
|
||||
A5E112972AF7401B00C6E0C2 /* ClipboardConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E112962AF7401B00C6E0C2 /* ClipboardConfirmationView.swift */; };
|
||||
A5E4082A2E022E9E0035FEAC /* TabGroupCloseCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408292E022E9B0035FEAC /* TabGroupCloseCoordinator.swift */; };
|
||||
A5E4082E2E0237460035FEAC /* NewTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E4082D2E0237410035FEAC /* NewTerminalIntent.swift */; };
|
||||
A5E408302E0271320035FEAC /* GhosttyIntentError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E4082F2E0271320035FEAC /* GhosttyIntentError.swift */; };
|
||||
A5E408322E02FEDF0035FEAC /* TerminalEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408312E02FEDC0035FEAC /* TerminalEntity.swift */; };
|
||||
A5E408342E0320140035FEAC /* GetTerminalDetailsIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408332E03200F0035FEAC /* GetTerminalDetailsIntent.swift */; };
|
||||
A5E408382E03C7DA0035FEAC /* Ghostty.Surface.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408372E03C7D80035FEAC /* Ghostty.Surface.swift */; };
|
||||
A5E4083A2E0449BD0035FEAC /* Ghostty.Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408392E0449BB0035FEAC /* Ghostty.Command.swift */; };
|
||||
A5E4083C2E044DB50035FEAC /* Ghostty.Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E4083B2E044DB40035FEAC /* Ghostty.Error.swift */; };
|
||||
A5E408402E04532C0035FEAC /* CommandEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E4083F2E04532A0035FEAC /* CommandEntity.swift */; };
|
||||
A5E408432E047D0B0035FEAC /* CommandPaletteIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408422E047D060035FEAC /* CommandPaletteIntent.swift */; };
|
||||
A5E408452E0483FD0035FEAC /* KeybindIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408442E0483F80035FEAC /* KeybindIntent.swift */; };
|
||||
A5E408472E04852B0035FEAC /* InputIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E408462E0485270035FEAC /* InputIntent.swift */; };
|
||||
A5F9A1F22E7C7301005AFACE /* SurfaceProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5F9A1F12E7C7301005AFACE /* SurfaceProgressBar.swift */; };
|
||||
A5FEB3002ABB69450068369E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5FEB2FF2ABB69450068369E /* main.swift */; };
|
||||
AEE8B3452B9AA39600260C5E /* NSPasteboard+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE8B3442B9AA39600260C5E /* NSPasteboard+Extension.swift */; };
|
||||
C159E81D2B66A06B00FDFE9C /* OSColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */; };
|
||||
C159E89D2B69A2EF00FDFE9C /* OSColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */; };
|
||||
C1F26EA72B738B9900404083 /* NSView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F26EA62B738B9900404083 /* NSView+Extension.swift */; };
|
||||
C1F26EE92B76CBFC00404083 /* VibrantLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = C1F26EE82B76CBFC00404083 /* VibrantLayer.m */; };
|
||||
CFBB5FEA2D231E5000FD62EE /* QuickTerminalSpaceBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFBB5FE92D231E5000FD62EE /* QuickTerminalSpaceBehavior.swift */; };
|
||||
FC5218FA2D10FFCE004C93E0 /* zsh in Resources */ = {isa = PBXBuildFile; fileRef = FC5218F92D10FFC7004C93E0 /* zsh */; };
|
||||
FC9ABA9C2D0F53F80020D4C8 /* bash-completion in Resources */ = {isa = PBXBuildFile; fileRef = FC9ABA9B2D0F538D0020D4C8 /* bash-completion */; };
|
||||
/* End PBXBuildFile section */
|
||||
@@ -42,145 +170,144 @@
|
||||
3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GhosttyReleaseLocal.entitlements; sourceTree = "<group>"; };
|
||||
55154BDF2B33911F001622DC /* ghostty */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ghostty; path = "../zig-out/share/ghostty"; sourceTree = "<group>"; };
|
||||
552964E52B34A9B400030505 /* vim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vim; path = "../zig-out/share/vim"; sourceTree = "<group>"; };
|
||||
857F63802A5E64F200CA4815 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
|
||||
9351BE8E2D22937F003B3499 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = "../zig-out/share/nvim"; sourceTree = "<group>"; };
|
||||
A50297342DFA0F3300B4E924 /* Double+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Extension.swift"; sourceTree = "<group>"; };
|
||||
A505D21C2E1A2F9E0018808F /* FileHandle+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileHandle+Extension.swift"; sourceTree = "<group>"; };
|
||||
A505D21E2E1B6DDC0018808F /* NSWorkspace+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSWorkspace+Extension.swift"; sourceTree = "<group>"; };
|
||||
A511940E2E050590007258CC /* CloseTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloseTerminalIntent.swift; sourceTree = "<group>"; };
|
||||
A51194102E05A480007258CC /* QuickTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalIntent.swift; sourceTree = "<group>"; };
|
||||
A51194122E05D003007258CC /* Optional+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Optional+Extension.swift"; sourceTree = "<group>"; };
|
||||
A51194162E05D95E007258CC /* PermissionRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionRequest.swift; sourceTree = "<group>"; };
|
||||
A51194182E05DFBB007258CC /* IntentPermission.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentPermission.swift; sourceTree = "<group>"; };
|
||||
A514C8D52B54A16400493A16 /* Ghostty.Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Config.swift; sourceTree = "<group>"; };
|
||||
A51544FD2DFB1110009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitlebarTabsTahoeTerminalWindow.swift; sourceTree = "<group>"; };
|
||||
A51544FF2DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TerminalTabsTitlebarTahoe.xib; sourceTree = "<group>"; };
|
||||
A51B78462AF4B58B00F3EDB9 /* TitlebarTabsVenturaTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitlebarTabsVenturaTerminalWindow.swift; sourceTree = "<group>"; };
|
||||
A51BFC1D2B2FB5CE00E92F16 /* About.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = About.xib; sourceTree = "<group>"; };
|
||||
A51BFC1F2B2FB64F00E92F16 /* AboutController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutController.swift; sourceTree = "<group>"; };
|
||||
A51BFC212B2FB6B400E92F16 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
|
||||
A51BFC282B30F26D00E92F16 /* GhosttyDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GhosttyDebug.entitlements; sourceTree = "<group>"; };
|
||||
A51BFC2A2B30F6BE00E92F16 /* UpdateDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateDelegate.swift; sourceTree = "<group>"; };
|
||||
A5278A9A2AA05B2600CD3039 /* Ghostty.Input.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Input.swift; sourceTree = "<group>"; };
|
||||
A52FFF562CA90481000C6A5B /* QuickTerminalScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalScreen.swift; sourceTree = "<group>"; };
|
||||
A52FFF582CAA4FF1000C6A5B /* Fullscreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fullscreen.swift; sourceTree = "<group>"; };
|
||||
A52FFF5A2CAA54A8000C6A5B /* FullscreenMode+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FullscreenMode+Extension.swift"; sourceTree = "<group>"; };
|
||||
A52FFF5C2CAB4D05000C6A5B /* NSScreen+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSScreen+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5333E152B59DE8E008AEFF7 /* SurfaceView_UIKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurfaceView_UIKit.swift; sourceTree = "<group>"; };
|
||||
A5333E1B2B5A1CE3008AEFF7 /* CrossKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrossKit.swift; sourceTree = "<group>"; };
|
||||
A5333E212B5A2128008AEFF7 /* SurfaceView_AppKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurfaceView_AppKit.swift; sourceTree = "<group>"; };
|
||||
A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
|
||||
A53A297A2DB2E49400B6E02C /* CommandPalette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandPalette.swift; sourceTree = "<group>"; };
|
||||
A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EventModifiers+Extension.swift"; sourceTree = "<group>"; };
|
||||
A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyboardShortcut+Extension.swift"; sourceTree = "<group>"; };
|
||||
A53A29872DB69D2C00B6E02C /* TerminalCommandPalette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalCommandPalette.swift; sourceTree = "<group>"; };
|
||||
A53A6C022CCC1B7D00943E98 /* Ghostty.Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Action.swift; sourceTree = "<group>"; };
|
||||
A53D0C932B53B43700305CE6 /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = "<group>"; };
|
||||
A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.App.swift; sourceTree = "<group>"; };
|
||||
A546F1132D7B68D7003B11A0 /* locale */ = {isa = PBXFileReference; lastKnownFileType = folder; name = locale; path = "../zig-out/share/locale"; sourceTree = "<group>"; };
|
||||
A54B0CE82D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorizedGhosttyIconView.swift; sourceTree = "<group>"; };
|
||||
A54B0CEA2D0CFB4A00CBEFF8 /* NSImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSImage+Extension.swift"; sourceTree = "<group>"; };
|
||||
A54B0CEC2D0CFB7300CBEFF8 /* ColorizedGhosttyIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorizedGhosttyIcon.swift; sourceTree = "<group>"; };
|
||||
A54B0CEE2D0D2E2400CBEFF8 /* ColorizedGhosttyIconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorizedGhosttyIconImage.swift; sourceTree = "<group>"; };
|
||||
A54D786B2CA79788001B19B1 /* BaseTerminalController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTerminalController.swift; sourceTree = "<group>"; };
|
||||
A54F45F32E1F047A0046BD5C /* GhosttyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GhosttyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A553F4122E06EB1600257779 /* Ghostty.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; name = Ghostty.icon; path = ../images/Ghostty.icon; sourceTree = SOURCE_ROOT; };
|
||||
A5593FDE2DF8D57100B47B10 /* TerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalWindow.swift; sourceTree = "<group>"; };
|
||||
A5593FE02DF8D73400B47B10 /* HiddenTitlebarTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiddenTitlebarTerminalWindow.swift; sourceTree = "<group>"; };
|
||||
A5593FE22DF8D78600B47B10 /* TerminalHiddenTitlebar.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TerminalHiddenTitlebar.xib; sourceTree = "<group>"; };
|
||||
A5593FE42DF8DE3000B47B10 /* TerminalTabsTitlebarVentura.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TerminalTabsTitlebarVentura.xib; sourceTree = "<group>"; };
|
||||
A5593FE62DF927CC00B47B10 /* TransparentTitlebarTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransparentTitlebarTerminalWindow.swift; sourceTree = "<group>"; };
|
||||
A5593FE82DF927DF00B47B10 /* TerminalTransparentTitlebar.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TerminalTransparentTitlebar.xib; sourceTree = "<group>"; };
|
||||
A55B7BB729B6F53A0055DE60 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
||||
A55B7BBB29B6FC330055DE60 /* SurfaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurfaceView.swift; sourceTree = "<group>"; };
|
||||
A56B880A2A840447007A0E29 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
|
||||
A56D58852ACDDB4100508D2C /* Ghostty.Shell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Shell.swift; sourceTree = "<group>"; };
|
||||
A56D58882ACDE6CA00508D2C /* ServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceProvider.swift; sourceTree = "<group>"; };
|
||||
A571AB1C2A206FC600248498 /* Ghostty-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Ghostty-Info.plist"; sourceTree = "<group>"; };
|
||||
A57D79262C9C8798001D522E /* SecureInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureInput.swift; sourceTree = "<group>"; };
|
||||
A586167B2B7703CC009BDB1D /* fish */ = {isa = PBXFileReference; lastKnownFileType = folder; name = fish; path = "../zig-out/share/fish"; sourceTree = "<group>"; };
|
||||
A586365E2DEE6C2100E04A10 /* SplitTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitTree.swift; sourceTree = "<group>"; };
|
||||
A58636652DEF963F00E04A10 /* TerminalSplitTreeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalSplitTreeView.swift; sourceTree = "<group>"; };
|
||||
A586366A2DF0A98900E04A10 /* Array+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Extension.swift"; sourceTree = "<group>"; };
|
||||
A586366E2DF25D8300E04A10 /* Duration+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Duration+Extension.swift"; sourceTree = "<group>"; };
|
||||
A58636702DF298F700E04A10 /* ExpiringUndoManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpiringUndoManager.swift; sourceTree = "<group>"; };
|
||||
A58636722DF4813000E04A10 /* UndoManager+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UndoManager+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5874D982DAD751A00E83852 /* CGS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGS.swift; sourceTree = "<group>"; };
|
||||
A5874D9C2DAD785F00E83852 /* NSWindow+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSWindow+Extension.swift"; sourceTree = "<group>"; };
|
||||
A59444F629A2ED5200725BBA /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||
A59630962AEE163600D64628 /* HostingWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostingWindow.swift; sourceTree = "<group>"; };
|
||||
A59630992AEE1C6400D64628 /* Terminal.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Terminal.xib; sourceTree = "<group>"; };
|
||||
A596309B2AEE1C9E00D64628 /* TerminalController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalController.swift; sourceTree = "<group>"; };
|
||||
A596309D2AEE1D6C00D64628 /* TerminalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalView.swift; sourceTree = "<group>"; };
|
||||
A5985CD62C320C4500C57AD3 /* String+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5985CE52C33060F00C57AD3 /* man */ = {isa = PBXFileReference; lastKnownFileType = folder; name = man; path = "../zig-out/share/man"; sourceTree = "<group>"; };
|
||||
A599CDAF2CF103F20049FA26 /* NSAppearance+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAppearance+Extension.swift"; sourceTree = "<group>"; };
|
||||
A59FB5CE2AE0DB50009128F3 /* InspectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorView.swift; sourceTree = "<group>"; };
|
||||
A59FB5D02AE0DEA7009128F3 /* MetalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = "<group>"; };
|
||||
A5A1F8842A489D6800D1E8BC /* terminfo */ = {isa = PBXFileReference; lastKnownFileType = folder; name = terminfo; path = "../zig-out/share/terminfo"; sourceTree = "<group>"; };
|
||||
A5A2A3C92D4445E20033CF96 /* Dock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dock.swift; sourceTree = "<group>"; };
|
||||
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSApplication+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5A6F7292CC41B8700B232A5 /* AppInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInfo.swift; sourceTree = "<group>"; };
|
||||
A5AEB1642D5BE7BF00513529 /* LastWindowPosition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastWindowPosition.swift; sourceTree = "<group>"; };
|
||||
A5B30531299BEAAA0047F10C /* Ghostty.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ghostty.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A5B30538299BEAAB0047F10C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Ghostty.entitlements; sourceTree = "<group>"; };
|
||||
A5B4EA842DFE69140022C3A2 /* NSMenuItem+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSMenuItem+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5BB78B82DF9D8CE009AC3FA /* QuickTerminalSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalSize.swift; sourceTree = "<group>"; };
|
||||
A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardLayout.swift; sourceTree = "<group>"; };
|
||||
A5CA378D2D31D6C100931030 /* Weak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = "<group>"; };
|
||||
A5CBD0552C9E65A50017A1AE /* DraggableWindowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggableWindowView.swift; sourceTree = "<group>"; };
|
||||
A5CBD0572C9F30860017A1AE /* Cursor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cursor.swift; sourceTree = "<group>"; };
|
||||
A5CBD05B2CA0C5C70017A1AE /* QuickTerminal.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QuickTerminal.xib; sourceTree = "<group>"; };
|
||||
A5CBD05D2CA0C5E70017A1AE /* QuickTerminalController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalController.swift; sourceTree = "<group>"; };
|
||||
A5CBD05F2CA0C9080017A1AE /* QuickTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalWindow.swift; sourceTree = "<group>"; };
|
||||
A5CBD0632CA122E70017A1AE /* QuickTerminalPosition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalPosition.swift; sourceTree = "<group>"; };
|
||||
A5CBD06A2CA322320017A1AE /* GlobalEventTap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalEventTap.swift; sourceTree = "<group>"; };
|
||||
A5CC36122C9CD729004D6760 /* SecureInputOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureInputOverlay.swift; sourceTree = "<group>"; };
|
||||
A5CC36142C9CDA03004D6760 /* View+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5CDF1902AAF9A5800513312 /* ConfigurationErrors.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConfigurationErrors.xib; sourceTree = "<group>"; };
|
||||
A5CDF1922AAF9E0800513312 /* ConfigurationErrorsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationErrorsController.swift; sourceTree = "<group>"; };
|
||||
A5CDF1942AAFA19600513312 /* ConfigurationErrorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationErrorsView.swift; sourceTree = "<group>"; };
|
||||
A5CEAFDB29B8009000646FDA /* SplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.swift; sourceTree = "<group>"; };
|
||||
A5CEAFDD29B8058B00646FDA /* SplitView.Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.Divider.swift; sourceTree = "<group>"; };
|
||||
A5CEAFFE29C2410700646FDA /* Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Backport.swift; sourceTree = "<group>"; };
|
||||
A5CF66D32D289CEA00139794 /* NSEvent+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSEvent+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5CF66D62D29DDB100139794 /* Ghostty.Event.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Event.swift; sourceTree = "<group>"; };
|
||||
A5D0AF3A2B36A1DE00D21823 /* TerminalRestorable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalRestorable.swift; sourceTree = "<group>"; };
|
||||
A5D0AF3C2B37804400D21823 /* CodableBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableBridge.swift; sourceTree = "<group>"; };
|
||||
A5D4499D2B53AE7B000F5B83 /* Ghostty-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Ghostty-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = GhosttyKit.xcframework; sourceTree = "<group>"; };
|
||||
A5E112922AF73E6E00C6E0C2 /* ClipboardConfirmation.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ClipboardConfirmation.xib; sourceTree = "<group>"; };
|
||||
A5E112942AF73E8A00C6E0C2 /* ClipboardConfirmationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClipboardConfirmationController.swift; sourceTree = "<group>"; };
|
||||
A5E112962AF7401B00C6E0C2 /* ClipboardConfirmationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClipboardConfirmationView.swift; sourceTree = "<group>"; };
|
||||
A5E408292E022E9B0035FEAC /* TabGroupCloseCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabGroupCloseCoordinator.swift; sourceTree = "<group>"; };
|
||||
A5E4082D2E0237410035FEAC /* NewTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTerminalIntent.swift; sourceTree = "<group>"; };
|
||||
A5E4082F2E0271320035FEAC /* GhosttyIntentError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GhosttyIntentError.swift; sourceTree = "<group>"; };
|
||||
A5E408312E02FEDC0035FEAC /* TerminalEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalEntity.swift; sourceTree = "<group>"; };
|
||||
A5E408332E03200F0035FEAC /* GetTerminalDetailsIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetTerminalDetailsIntent.swift; sourceTree = "<group>"; };
|
||||
A5E408372E03C7D80035FEAC /* Ghostty.Surface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Surface.swift; sourceTree = "<group>"; };
|
||||
A5E408392E0449BB0035FEAC /* Ghostty.Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Command.swift; sourceTree = "<group>"; };
|
||||
A5E4083B2E044DB40035FEAC /* Ghostty.Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Error.swift; sourceTree = "<group>"; };
|
||||
A5E4083F2E04532A0035FEAC /* CommandEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandEntity.swift; sourceTree = "<group>"; };
|
||||
A5E408422E047D060035FEAC /* CommandPaletteIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandPaletteIntent.swift; sourceTree = "<group>"; };
|
||||
A5E408442E0483F80035FEAC /* KeybindIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeybindIntent.swift; sourceTree = "<group>"; };
|
||||
A5E408462E0485270035FEAC /* InputIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputIntent.swift; sourceTree = "<group>"; };
|
||||
A5F9A1F12E7C7301005AFACE /* SurfaceProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurfaceProgressBar.swift; sourceTree = "<group>"; };
|
||||
A5FEB2FF2ABB69450068369E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
AEE8B3442B9AA39600260C5E /* NSPasteboard+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSPasteboard+Extension.swift"; sourceTree = "<group>"; };
|
||||
C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OSColor+Extension.swift"; sourceTree = "<group>"; };
|
||||
C1F26EA62B738B9900404083 /* NSView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSView+Extension.swift"; sourceTree = "<group>"; };
|
||||
C1F26EE72B76CBFC00404083 /* VibrantLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VibrantLayer.h; sourceTree = "<group>"; };
|
||||
C1F26EE82B76CBFC00404083 /* VibrantLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VibrantLayer.m; sourceTree = "<group>"; };
|
||||
C1F26EEA2B76CC2400404083 /* ghostty-bridging-header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ghostty-bridging-header.h"; sourceTree = "<group>"; };
|
||||
CFBB5FE92D231E5000FD62EE /* QuickTerminalSpaceBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalSpaceBehavior.swift; sourceTree = "<group>"; };
|
||||
FC5218F92D10FFC7004C93E0 /* zsh */ = {isa = PBXFileReference; lastKnownFileType = folder; name = zsh; path = "../zig-out/share/zsh"; sourceTree = "<group>"; };
|
||||
FC9ABA9B2D0F538D0020D4C8 /* bash-completion */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "bash-completion"; path = "../zig-out/share/bash-completion"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
81F82CB02E8281F5001EDFA7 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
|
||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||
membershipExceptions = (
|
||||
App/macOS/AppDelegate.swift,
|
||||
App/macOS/main.swift,
|
||||
App/macOS/MainMenu.xib,
|
||||
Features/About/About.xib,
|
||||
Features/About/AboutController.swift,
|
||||
Features/About/AboutView.swift,
|
||||
"Features/App Intents/CloseTerminalIntent.swift",
|
||||
"Features/App Intents/CommandPaletteIntent.swift",
|
||||
"Features/App Intents/Entities/CommandEntity.swift",
|
||||
"Features/App Intents/Entities/TerminalEntity.swift",
|
||||
"Features/App Intents/FocusTerminalIntent.swift",
|
||||
"Features/App Intents/GetTerminalDetailsIntent.swift",
|
||||
"Features/App Intents/GhosttyIntentError.swift",
|
||||
"Features/App Intents/InputIntent.swift",
|
||||
"Features/App Intents/IntentPermission.swift",
|
||||
"Features/App Intents/KeybindIntent.swift",
|
||||
"Features/App Intents/NewTerminalIntent.swift",
|
||||
"Features/App Intents/QuickTerminalIntent.swift",
|
||||
Features/ClipboardConfirmation/ClipboardConfirmation.xib,
|
||||
Features/ClipboardConfirmation/ClipboardConfirmationController.swift,
|
||||
Features/ClipboardConfirmation/ClipboardConfirmationView.swift,
|
||||
"Features/Colorized Ghostty Icon/ColorizedGhosttyIcon.swift",
|
||||
"Features/Colorized Ghostty Icon/ColorizedGhosttyIconImage.swift",
|
||||
"Features/Colorized Ghostty Icon/ColorizedGhosttyIconView.swift",
|
||||
"Features/Command Palette/CommandPalette.swift",
|
||||
"Features/Command Palette/TerminalCommandPalette.swift",
|
||||
"Features/Global Keybinds/GlobalEventTap.swift",
|
||||
Features/QuickTerminal/QuickTerminal.xib,
|
||||
Features/QuickTerminal/QuickTerminalController.swift,
|
||||
Features/QuickTerminal/QuickTerminalPosition.swift,
|
||||
Features/QuickTerminal/QuickTerminalScreen.swift,
|
||||
Features/QuickTerminal/QuickTerminalSize.swift,
|
||||
Features/QuickTerminal/QuickTerminalSpaceBehavior.swift,
|
||||
Features/QuickTerminal/QuickTerminalWindow.swift,
|
||||
"Features/Secure Input/SecureInput.swift",
|
||||
"Features/Secure Input/SecureInputOverlay.swift",
|
||||
Features/Services/ServiceProvider.swift,
|
||||
Features/Settings/ConfigurationErrors.xib,
|
||||
Features/Settings/ConfigurationErrorsController.swift,
|
||||
Features/Settings/ConfigurationErrorsView.swift,
|
||||
Features/Settings/SettingsView.swift,
|
||||
Features/Splits/SplitTree.swift,
|
||||
Features/Splits/SplitView.Divider.swift,
|
||||
Features/Splits/SplitView.swift,
|
||||
Features/Splits/TerminalSplitTreeView.swift,
|
||||
Features/Terminal/BaseTerminalController.swift,
|
||||
Features/Terminal/ErrorView.swift,
|
||||
Features/Terminal/TerminalController.swift,
|
||||
Features/Terminal/TerminalRestorable.swift,
|
||||
Features/Terminal/TerminalView.swift,
|
||||
"Features/Terminal/Window Styles/HiddenTitlebarTerminalWindow.swift",
|
||||
"Features/Terminal/Window Styles/Terminal.xib",
|
||||
"Features/Terminal/Window Styles/TerminalHiddenTitlebar.xib",
|
||||
"Features/Terminal/Window Styles/TerminalTabsTitlebarTahoe.xib",
|
||||
"Features/Terminal/Window Styles/TerminalTabsTitlebarVentura.xib",
|
||||
"Features/Terminal/Window Styles/TerminalTransparentTitlebar.xib",
|
||||
"Features/Terminal/Window Styles/TerminalWindow.swift",
|
||||
"Features/Terminal/Window Styles/TitlebarTabsTahoeTerminalWindow.swift",
|
||||
"Features/Terminal/Window Styles/TitlebarTabsVenturaTerminalWindow.swift",
|
||||
"Features/Terminal/Window Styles/TransparentTitlebarTerminalWindow.swift",
|
||||
Features/Update/UpdateDelegate.swift,
|
||||
"Ghostty/FullscreenMode+Extension.swift",
|
||||
Ghostty/Ghostty.Command.swift,
|
||||
Ghostty/Ghostty.Error.swift,
|
||||
Ghostty/Ghostty.Event.swift,
|
||||
Ghostty/Ghostty.Input.swift,
|
||||
Ghostty/Ghostty.Surface.swift,
|
||||
Ghostty/InspectorView.swift,
|
||||
"Ghostty/NSEvent+Extension.swift",
|
||||
Ghostty/SurfaceView_AppKit.swift,
|
||||
Helpers/AppInfo.swift,
|
||||
Helpers/CodableBridge.swift,
|
||||
Helpers/Cursor.swift,
|
||||
Helpers/DraggableWindowView.swift,
|
||||
Helpers/ExpiringUndoManager.swift,
|
||||
"Helpers/Extensions/Double+Extension.swift",
|
||||
"Helpers/Extensions/EventModifiers+Extension.swift",
|
||||
"Helpers/Extensions/FileHandle+Extension.swift",
|
||||
"Helpers/Extensions/KeyboardShortcut+Extension.swift",
|
||||
"Helpers/Extensions/NSAppearance+Extension.swift",
|
||||
"Helpers/Extensions/NSApplication+Extension.swift",
|
||||
"Helpers/Extensions/NSImage+Extension.swift",
|
||||
"Helpers/Extensions/NSMenuItem+Extension.swift",
|
||||
"Helpers/Extensions/NSPasteboard+Extension.swift",
|
||||
"Helpers/Extensions/NSScreen+Extension.swift",
|
||||
"Helpers/Extensions/NSView+Extension.swift",
|
||||
"Helpers/Extensions/NSWindow+Extension.swift",
|
||||
"Helpers/Extensions/NSWorkspace+Extension.swift",
|
||||
"Helpers/Extensions/UndoManager+Extension.swift",
|
||||
"Helpers/Extensions/View+Extension.swift",
|
||||
Helpers/Fullscreen.swift,
|
||||
Helpers/HostingWindow.swift,
|
||||
Helpers/KeyboardLayout.swift,
|
||||
Helpers/LastWindowPosition.swift,
|
||||
Helpers/MetalView.swift,
|
||||
Helpers/PermissionRequest.swift,
|
||||
Helpers/Private/CGS.swift,
|
||||
Helpers/Private/Dock.swift,
|
||||
Helpers/TabGroupCloseCoordinator.swift,
|
||||
Helpers/VibrantLayer.m,
|
||||
Helpers/Weak.swift,
|
||||
);
|
||||
target = A5D4499C2B53AE7B000F5B83 /* Ghostty-iOS */;
|
||||
};
|
||||
81F82CB12E8281F9001EDFA7 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
|
||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||
membershipExceptions = (
|
||||
App/iOS/iOSApp.swift,
|
||||
Ghostty/SurfaceView_UIKit.swift,
|
||||
);
|
||||
target = A5B30530299BEAAA0047F10C /* Ghostty */;
|
||||
};
|
||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
81F82BC72E82815D001EDFA7 /* Sources */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (81F82CB12E8281F9001EDFA7 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, 81F82CB02E8281F5001EDFA7 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Sources; sourceTree = "<group>"; };
|
||||
A54F45F42E1F047A0046BD5C /* Tests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Tests; sourceTree = "<group>"; };
|
||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||
|
||||
@@ -213,6 +340,257 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
A51BFC1C2B2FB5AB00E92F16 /* About */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A51BFC1D2B2FB5CE00E92F16 /* About.xib */,
|
||||
A51BFC1F2B2FB64F00E92F16 /* AboutController.swift */,
|
||||
A51BFC212B2FB6B400E92F16 /* AboutView.swift */,
|
||||
);
|
||||
path = About;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A51BFC292B30F69F00E92F16 /* Update */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A51BFC2A2B30F6BE00E92F16 /* UpdateDelegate.swift */,
|
||||
);
|
||||
path = Update;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A53426362A7DC53000EBB7A2 /* Features */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5CBD0672CA2704E0017A1AE /* Global Keybinds */,
|
||||
A56D58872ACDE6BE00508D2C /* Services */,
|
||||
A59630982AEE1C4400D64628 /* Terminal */,
|
||||
A5CBD05A2CA0C5910017A1AE /* QuickTerminal */,
|
||||
A5E4082C2E0237270035FEAC /* App Intents */,
|
||||
A5E112912AF73E4D00C6E0C2 /* ClipboardConfirmation */,
|
||||
A57D79252C9C8782001D522E /* Secure Input */,
|
||||
A58636622DEF955100E04A10 /* Splits */,
|
||||
A53A29742DB2E04900B6E02C /* Command Palette */,
|
||||
A534263E2A7DCC5800EBB7A2 /* Settings */,
|
||||
A51BFC1C2B2FB5AB00E92F16 /* About */,
|
||||
A54B0CE72D0CEC9800CBEFF8 /* Colorized Ghostty Icon */,
|
||||
A51BFC292B30F69F00E92F16 /* Update */,
|
||||
);
|
||||
path = Features;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A534263D2A7DCBB000EBB7A2 /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A58636692DF0A98100E04A10 /* Extensions */,
|
||||
A5874D9B2DAD781100E83852 /* Private */,
|
||||
A5A6F7292CC41B8700B232A5 /* AppInfo.swift */,
|
||||
A5AEB1642D5BE7BF00513529 /* LastWindowPosition.swift */,
|
||||
A5CEAFFE29C2410700646FDA /* Backport.swift */,
|
||||
A5333E1B2B5A1CE3008AEFF7 /* CrossKit.swift */,
|
||||
A5CBD0572C9F30860017A1AE /* Cursor.swift */,
|
||||
A5D0AF3C2B37804400D21823 /* CodableBridge.swift */,
|
||||
A5CBD0552C9E65A50017A1AE /* DraggableWindowView.swift */,
|
||||
A58636702DF298F700E04A10 /* ExpiringUndoManager.swift */,
|
||||
A52FFF582CAA4FF1000C6A5B /* Fullscreen.swift */,
|
||||
A59630962AEE163600D64628 /* HostingWindow.swift */,
|
||||
A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */,
|
||||
A59FB5D02AE0DEA7009128F3 /* MetalView.swift */,
|
||||
A51194162E05D95E007258CC /* PermissionRequest.swift */,
|
||||
A5E408292E022E9B0035FEAC /* TabGroupCloseCoordinator.swift */,
|
||||
A5CA378D2D31D6C100931030 /* Weak.swift */,
|
||||
C1F26EE72B76CBFC00404083 /* VibrantLayer.h */,
|
||||
C1F26EE82B76CBFC00404083 /* VibrantLayer.m */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A534263E2A7DCC5800EBB7A2 /* Settings */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A59444F629A2ED5200725BBA /* SettingsView.swift */,
|
||||
A5CDF1902AAF9A5800513312 /* ConfigurationErrors.xib */,
|
||||
A5CDF1922AAF9E0800513312 /* ConfigurationErrorsController.swift */,
|
||||
A5CDF1942AAFA19600513312 /* ConfigurationErrorsView.swift */,
|
||||
);
|
||||
path = Settings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A53A29742DB2E04900B6E02C /* Command Palette */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A53A297A2DB2E49400B6E02C /* CommandPalette.swift */,
|
||||
A53A29872DB69D2C00B6E02C /* TerminalCommandPalette.swift */,
|
||||
);
|
||||
path = "Command Palette";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A53D0C912B53B41900305CE6 /* App */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A53D0C962B53B57D00305CE6 /* macOS */,
|
||||
A53D0C922B53B42000305CE6 /* iOS */,
|
||||
);
|
||||
path = App;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A53D0C922B53B42000305CE6 /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A53D0C932B53B43700305CE6 /* iOSApp.swift */,
|
||||
);
|
||||
path = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A53D0C962B53B57D00305CE6 /* macOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5FEB2FF2ABB69450068369E /* main.swift */,
|
||||
A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */,
|
||||
857F63802A5E64F200CA4815 /* MainMenu.xib */,
|
||||
C1F26EEA2B76CC2400404083 /* ghostty-bridging-header.h */,
|
||||
);
|
||||
path = macOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A54B0CE72D0CEC9800CBEFF8 /* Colorized Ghostty Icon */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A54B0CEC2D0CFB7300CBEFF8 /* ColorizedGhosttyIcon.swift */,
|
||||
A54B0CEE2D0D2E2400CBEFF8 /* ColorizedGhosttyIconImage.swift */,
|
||||
A54B0CE82D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift */,
|
||||
);
|
||||
path = "Colorized Ghostty Icon";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A54CD6ED299BEB14008C95BB /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A53D0C912B53B41900305CE6 /* App */,
|
||||
A53426362A7DC53000EBB7A2 /* Features */,
|
||||
A534263D2A7DCBB000EBB7A2 /* Helpers */,
|
||||
A55B7BB429B6F4410055DE60 /* Ghostty */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5593FDD2DF8D56000B47B10 /* Window Styles */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A59630992AEE1C6400D64628 /* Terminal.xib */,
|
||||
A5593FE22DF8D78600B47B10 /* TerminalHiddenTitlebar.xib */,
|
||||
A51544FF2DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib */,
|
||||
A5593FE42DF8DE3000B47B10 /* TerminalTabsTitlebarVentura.xib */,
|
||||
A5593FE82DF927DF00B47B10 /* TerminalTransparentTitlebar.xib */,
|
||||
A5593FDE2DF8D57100B47B10 /* TerminalWindow.swift */,
|
||||
A5593FE02DF8D73400B47B10 /* HiddenTitlebarTerminalWindow.swift */,
|
||||
A51B78462AF4B58B00F3EDB9 /* TitlebarTabsVenturaTerminalWindow.swift */,
|
||||
A51544FD2DFB1110009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift */,
|
||||
A5593FE62DF927CC00B47B10 /* TransparentTitlebarTerminalWindow.swift */,
|
||||
);
|
||||
path = "Window Styles";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A55B7BB429B6F4410055DE60 /* Ghostty */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A55B7BB729B6F53A0055DE60 /* Package.swift */,
|
||||
A5F9A1F12E7C7301005AFACE /* SurfaceProgressBar.swift */,
|
||||
A55B7BBB29B6FC330055DE60 /* SurfaceView.swift */,
|
||||
A5333E212B5A2128008AEFF7 /* SurfaceView_AppKit.swift */,
|
||||
A5333E152B59DE8E008AEFF7 /* SurfaceView_UIKit.swift */,
|
||||
A59FB5CE2AE0DB50009128F3 /* InspectorView.swift */,
|
||||
A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */,
|
||||
A5E408392E0449BB0035FEAC /* Ghostty.Command.swift */,
|
||||
A514C8D52B54A16400493A16 /* Ghostty.Config.swift */,
|
||||
A53A6C022CCC1B7D00943E98 /* Ghostty.Action.swift */,
|
||||
A5E4083B2E044DB40035FEAC /* Ghostty.Error.swift */,
|
||||
A5CF66D62D29DDB100139794 /* Ghostty.Event.swift */,
|
||||
A5278A9A2AA05B2600CD3039 /* Ghostty.Input.swift */,
|
||||
A56D58852ACDDB4100508D2C /* Ghostty.Shell.swift */,
|
||||
A5E408372E03C7D80035FEAC /* Ghostty.Surface.swift */,
|
||||
A52FFF5A2CAA54A8000C6A5B /* FullscreenMode+Extension.swift */,
|
||||
A5CF66D32D289CEA00139794 /* NSEvent+Extension.swift */,
|
||||
);
|
||||
path = Ghostty;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A56D58872ACDE6BE00508D2C /* Services */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A56D58882ACDE6CA00508D2C /* ServiceProvider.swift */,
|
||||
);
|
||||
path = Services;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A57D79252C9C8782001D522E /* Secure Input */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A57D79262C9C8798001D522E /* SecureInput.swift */,
|
||||
A5CC36122C9CD729004D6760 /* SecureInputOverlay.swift */,
|
||||
);
|
||||
path = "Secure Input";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A58636622DEF955100E04A10 /* Splits */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A586365E2DEE6C2100E04A10 /* SplitTree.swift */,
|
||||
A58636652DEF963F00E04A10 /* TerminalSplitTreeView.swift */,
|
||||
A5CEAFDB29B8009000646FDA /* SplitView.swift */,
|
||||
A5CEAFDD29B8058B00646FDA /* SplitView.Divider.swift */,
|
||||
);
|
||||
path = Splits;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A58636692DF0A98100E04A10 /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A586366A2DF0A98900E04A10 /* Array+Extension.swift */,
|
||||
A50297342DFA0F3300B4E924 /* Double+Extension.swift */,
|
||||
A586366E2DF25D8300E04A10 /* Duration+Extension.swift */,
|
||||
A505D21C2E1A2F9E0018808F /* FileHandle+Extension.swift */,
|
||||
A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */,
|
||||
A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */,
|
||||
A51194122E05D003007258CC /* Optional+Extension.swift */,
|
||||
C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */,
|
||||
A599CDAF2CF103F20049FA26 /* NSAppearance+Extension.swift */,
|
||||
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */,
|
||||
A54B0CEA2D0CFB4A00CBEFF8 /* NSImage+Extension.swift */,
|
||||
A5B4EA842DFE69140022C3A2 /* NSMenuItem+Extension.swift */,
|
||||
A52FFF5C2CAB4D05000C6A5B /* NSScreen+Extension.swift */,
|
||||
AEE8B3442B9AA39600260C5E /* NSPasteboard+Extension.swift */,
|
||||
C1F26EA62B738B9900404083 /* NSView+Extension.swift */,
|
||||
A5874D9C2DAD785F00E83852 /* NSWindow+Extension.swift */,
|
||||
A505D21E2E1B6DDC0018808F /* NSWorkspace+Extension.swift */,
|
||||
A5985CD62C320C4500C57AD3 /* String+Extension.swift */,
|
||||
A58636722DF4813000E04A10 /* UndoManager+Extension.swift */,
|
||||
A5CC36142C9CDA03004D6760 /* View+Extension.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5874D9B2DAD781100E83852 /* Private */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5874D982DAD751A00E83852 /* CGS.swift */,
|
||||
A5A2A3C92D4445E20033CF96 /* Dock.swift */,
|
||||
);
|
||||
path = Private;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A59630982AEE1C4400D64628 /* Terminal */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5593FDD2DF8D56000B47B10 /* Window Styles */,
|
||||
A596309B2AEE1C9E00D64628 /* TerminalController.swift */,
|
||||
A5D0AF3A2B36A1DE00D21823 /* TerminalRestorable.swift */,
|
||||
A596309D2AEE1D6C00D64628 /* TerminalView.swift */,
|
||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */,
|
||||
A54D786B2CA79788001B19B1 /* BaseTerminalController.swift */,
|
||||
);
|
||||
path = Terminal;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5A1F8862A489D7400D1E8BC /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -239,7 +617,7 @@
|
||||
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */,
|
||||
A51BFC282B30F26D00E92F16 /* GhosttyDebug.entitlements */,
|
||||
3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */,
|
||||
81F82BC72E82815D001EDFA7 /* Sources */,
|
||||
A54CD6ED299BEB14008C95BB /* Sources */,
|
||||
A54F45F42E1F047A0046BD5C /* Tests */,
|
||||
A5D495A3299BECBA00DD1313 /* Frameworks */,
|
||||
A5A1F8862A489D7400D1E8BC /* Resources */,
|
||||
@@ -257,6 +635,28 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5CBD05A2CA0C5910017A1AE /* QuickTerminal */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5CBD05B2CA0C5C70017A1AE /* QuickTerminal.xib */,
|
||||
A5CBD05D2CA0C5E70017A1AE /* QuickTerminalController.swift */,
|
||||
CFBB5FE92D231E5000FD62EE /* QuickTerminalSpaceBehavior.swift */,
|
||||
A5CBD0632CA122E70017A1AE /* QuickTerminalPosition.swift */,
|
||||
A52FFF562CA90481000C6A5B /* QuickTerminalScreen.swift */,
|
||||
A5BB78B82DF9D8CE009AC3FA /* QuickTerminalSize.swift */,
|
||||
A5CBD05F2CA0C9080017A1AE /* QuickTerminalWindow.swift */,
|
||||
);
|
||||
path = QuickTerminal;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5CBD0672CA2704E0017A1AE /* Global Keybinds */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5CBD06A2CA322320017A1AE /* GlobalEventTap.swift */,
|
||||
);
|
||||
path = "Global Keybinds";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5D495A3299BECBA00DD1313 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -266,6 +666,42 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5E112912AF73E4D00C6E0C2 /* ClipboardConfirmation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5E112922AF73E6E00C6E0C2 /* ClipboardConfirmation.xib */,
|
||||
A5E112942AF73E8A00C6E0C2 /* ClipboardConfirmationController.swift */,
|
||||
A5E112962AF7401B00C6E0C2 /* ClipboardConfirmationView.swift */,
|
||||
);
|
||||
path = ClipboardConfirmation;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5E4082C2E0237270035FEAC /* App Intents */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5E408412E0453370035FEAC /* Entities */,
|
||||
A511940E2E050590007258CC /* CloseTerminalIntent.swift */,
|
||||
A5E4082D2E0237410035FEAC /* NewTerminalIntent.swift */,
|
||||
A5E408332E03200F0035FEAC /* GetTerminalDetailsIntent.swift */,
|
||||
A51194102E05A480007258CC /* QuickTerminalIntent.swift */,
|
||||
A5E408422E047D060035FEAC /* CommandPaletteIntent.swift */,
|
||||
A5E408462E0485270035FEAC /* InputIntent.swift */,
|
||||
A5E408442E0483F80035FEAC /* KeybindIntent.swift */,
|
||||
A5E4082F2E0271320035FEAC /* GhosttyIntentError.swift */,
|
||||
A51194182E05DFBB007258CC /* IntentPermission.swift */,
|
||||
);
|
||||
path = "App Intents";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A5E408412E0453370035FEAC /* Entities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A5E408312E02FEDC0035FEAC /* TerminalEntity.swift */,
|
||||
A5E4083F2E04532A0035FEAC /* CommandEntity.swift */,
|
||||
);
|
||||
path = Entities;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -304,9 +740,6 @@
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
fileSystemSynchronizedGroups = (
|
||||
81F82BC72E82815D001EDFA7 /* Sources */,
|
||||
);
|
||||
name = Ghostty;
|
||||
packageProductDependencies = (
|
||||
A51BFC262B30F1B800E92F16 /* Sparkle */,
|
||||
@@ -327,9 +760,6 @@
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
fileSystemSynchronizedGroups = (
|
||||
81F82BC72E82815D001EDFA7 /* Sources */,
|
||||
);
|
||||
name = "Ghostty-iOS";
|
||||
productName = "Ghostty-iOS";
|
||||
productReference = A5D4499D2B53AE7B000F5B83 /* Ghostty-iOS.app */;
|
||||
@@ -395,9 +825,11 @@
|
||||
files = (
|
||||
FC9ABA9C2D0F53F80020D4C8 /* bash-completion in Resources */,
|
||||
A553F4142E06EB1600257779 /* Ghostty.icon in Resources */,
|
||||
A5593FE52DF8DE3000B47B10 /* TerminalTabsTitlebarVentura.xib in Resources */,
|
||||
29C15B1D2CDC3B2900520DD4 /* bat in Resources */,
|
||||
A586167C2B7703CC009BDB1D /* fish in Resources */,
|
||||
55154BE02B33911F001622DC /* ghostty in Resources */,
|
||||
A5593FE32DF8D78600B47B10 /* TerminalHiddenTitlebar.xib in Resources */,
|
||||
A546F1142D7B68D7003B11A0 /* locale in Resources */,
|
||||
A5985CE62C33060F00C57AD3 /* man in Resources */,
|
||||
9351BE8E3D22937F003B3499 /* nvim in Resources */,
|
||||
@@ -405,6 +837,14 @@
|
||||
552964E62B34A9B400030505 /* vim in Resources */,
|
||||
FC5218FA2D10FFCE004C93E0 /* zsh in Resources */,
|
||||
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */,
|
||||
A51BFC1E2B2FB5CE00E92F16 /* About.xib in Resources */,
|
||||
A5593FE92DF927DF00B47B10 /* TerminalTransparentTitlebar.xib in Resources */,
|
||||
A5E112932AF73E6E00C6E0C2 /* ClipboardConfirmation.xib in Resources */,
|
||||
A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */,
|
||||
857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */,
|
||||
A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */,
|
||||
A51545002DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib in Resources */,
|
||||
A5CBD05C2CA0C5C70017A1AE /* QuickTerminal.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -431,6 +871,113 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A5AEB1652D5BE7D000513529 /* LastWindowPosition.swift in Sources */,
|
||||
A5E408432E047D0B0035FEAC /* CommandPaletteIntent.swift in Sources */,
|
||||
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */,
|
||||
A54B0CEB2D0CFB4C00CBEFF8 /* NSImage+Extension.swift in Sources */,
|
||||
A5874D9D2DAD786100E83852 /* NSWindow+Extension.swift in Sources */,
|
||||
A54D786C2CA7978E001B19B1 /* BaseTerminalController.swift in Sources */,
|
||||
A58636732DF4813400E04A10 /* UndoManager+Extension.swift in Sources */,
|
||||
A505D21D2E1A2FA20018808F /* FileHandle+Extension.swift in Sources */,
|
||||
A59FB5CF2AE0DB50009128F3 /* InspectorView.swift in Sources */,
|
||||
CFBB5FEA2D231E5000FD62EE /* QuickTerminalSpaceBehavior.swift in Sources */,
|
||||
A54B0CE92D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift in Sources */,
|
||||
A5D0AF3D2B37804400D21823 /* CodableBridge.swift in Sources */,
|
||||
A51194132E05D006007258CC /* Optional+Extension.swift in Sources */,
|
||||
A5D0AF3B2B36A1DE00D21823 /* TerminalRestorable.swift in Sources */,
|
||||
C1F26EA72B738B9900404083 /* NSView+Extension.swift in Sources */,
|
||||
A586366F2DF25D8600E04A10 /* Duration+Extension.swift in Sources */,
|
||||
A5CF66D42D289CEE00139794 /* NSEvent+Extension.swift in Sources */,
|
||||
A5E408342E0320140035FEAC /* GetTerminalDetailsIntent.swift in Sources */,
|
||||
A5CBD0642CA122E70017A1AE /* QuickTerminalPosition.swift in Sources */,
|
||||
A596309C2AEE1C9E00D64628 /* TerminalController.swift in Sources */,
|
||||
A5E408322E02FEDF0035FEAC /* TerminalEntity.swift in Sources */,
|
||||
A5CC36152C9CDA06004D6760 /* View+Extension.swift in Sources */,
|
||||
A56D58892ACDE6CA00508D2C /* ServiceProvider.swift in Sources */,
|
||||
A5CBD0602CA0C90A0017A1AE /* QuickTerminalWindow.swift in Sources */,
|
||||
A5F9A1F22E7C7301005AFACE /* SurfaceProgressBar.swift in Sources */,
|
||||
A505D21F2E1B6DE00018808F /* NSWorkspace+Extension.swift in Sources */,
|
||||
A5CBD05E2CA0C5EC0017A1AE /* QuickTerminalController.swift in Sources */,
|
||||
A5CF66D72D29DDB500139794 /* Ghostty.Event.swift in Sources */,
|
||||
A511940F2E050595007258CC /* CloseTerminalIntent.swift in Sources */,
|
||||
A5E408382E03C7DA0035FEAC /* Ghostty.Surface.swift in Sources */,
|
||||
A5593FE72DF927D200B47B10 /* TransparentTitlebarTerminalWindow.swift in Sources */,
|
||||
A5A2A3CA2D4445E30033CF96 /* Dock.swift in Sources */,
|
||||
A586365F2DEE6C2300E04A10 /* SplitTree.swift in Sources */,
|
||||
A51BFC222B2FB6B400E92F16 /* AboutView.swift in Sources */,
|
||||
A5278A9B2AA05B2600CD3039 /* Ghostty.Input.swift in Sources */,
|
||||
A53A29812DB44A6100B6E02C /* KeyboardShortcut+Extension.swift in Sources */,
|
||||
A50297352DFA0F3400B4E924 /* Double+Extension.swift in Sources */,
|
||||
A5CBD0562C9E65B80017A1AE /* DraggableWindowView.swift in Sources */,
|
||||
A51194112E05A483007258CC /* QuickTerminalIntent.swift in Sources */,
|
||||
C1F26EE92B76CBFC00404083 /* VibrantLayer.m in Sources */,
|
||||
A5593FDF2DF8D57C00B47B10 /* TerminalWindow.swift in Sources */,
|
||||
A58636712DF298FB00E04A10 /* ExpiringUndoManager.swift in Sources */,
|
||||
A59630972AEE163600D64628 /* HostingWindow.swift in Sources */,
|
||||
A51BFC2B2B30F6BE00E92F16 /* UpdateDelegate.swift in Sources */,
|
||||
A5CBD06B2CA322430017A1AE /* GlobalEventTap.swift in Sources */,
|
||||
AEE8B3452B9AA39600260C5E /* NSPasteboard+Extension.swift in Sources */,
|
||||
A51194172E05D964007258CC /* PermissionRequest.swift in Sources */,
|
||||
A51194192E05DFC4007258CC /* IntentPermission.swift in Sources */,
|
||||
A52FFF5D2CAB4D08000C6A5B /* NSScreen+Extension.swift in Sources */,
|
||||
A53426352A7DA53D00EBB7A2 /* AppDelegate.swift in Sources */,
|
||||
A5CBD0582C9F30960017A1AE /* Cursor.swift in Sources */,
|
||||
A5A6F72A2CC41B8900B232A5 /* AppInfo.swift in Sources */,
|
||||
A52FFF5B2CAA54B1000C6A5B /* FullscreenMode+Extension.swift in Sources */,
|
||||
A5333E222B5A2128008AEFF7 /* SurfaceView_AppKit.swift in Sources */,
|
||||
A5CA378E2D31D6C300931030 /* Weak.swift in Sources */,
|
||||
A5CDF1952AAFA19600513312 /* ConfigurationErrorsView.swift in Sources */,
|
||||
A55B7BBC29B6FC330055DE60 /* SurfaceView.swift in Sources */,
|
||||
A5333E1C2B5A1CE3008AEFF7 /* CrossKit.swift in Sources */,
|
||||
A5B4EA852DFE691B0022C3A2 /* NSMenuItem+Extension.swift in Sources */,
|
||||
A5874D992DAD751B00E83852 /* CGS.swift in Sources */,
|
||||
A586366B2DF0A98C00E04A10 /* Array+Extension.swift in Sources */,
|
||||
A5E408472E04852B0035FEAC /* InputIntent.swift in Sources */,
|
||||
A51544FE2DFB111C009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift in Sources */,
|
||||
A59444F729A2ED5200725BBA /* SettingsView.swift in Sources */,
|
||||
A56D58862ACDDB4100508D2C /* Ghostty.Shell.swift in Sources */,
|
||||
A5985CD72C320C4500C57AD3 /* String+Extension.swift in Sources */,
|
||||
A5A2A3CC2D444ABB0033CF96 /* NSApplication+Extension.swift in Sources */,
|
||||
A5E408302E0271320035FEAC /* GhosttyIntentError.swift in Sources */,
|
||||
A5E4083A2E0449BD0035FEAC /* Ghostty.Command.swift in Sources */,
|
||||
A5E408452E0483FD0035FEAC /* KeybindIntent.swift in Sources */,
|
||||
A5FEB3002ABB69450068369E /* main.swift in Sources */,
|
||||
A53A297F2DB4480F00B6E02C /* EventModifiers+Extension.swift in Sources */,
|
||||
A5E4082E2E0237460035FEAC /* NewTerminalIntent.swift in Sources */,
|
||||
A53A297B2DB2E49700B6E02C /* CommandPalette.swift in Sources */,
|
||||
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */,
|
||||
A51B78472AF4B58B00F3EDB9 /* TitlebarTabsVenturaTerminalWindow.swift in Sources */,
|
||||
A51B78472AF4B58B00F3EDB9 /* TitlebarTabsVenturaTerminalWindow.swift in Sources */,
|
||||
A5BB78B92DF9D8CE009AC3FA /* QuickTerminalSize.swift in Sources */,
|
||||
A51B78472AF4B58B00F3EDB9 /* TitlebarTabsVenturaTerminalWindow.swift in Sources */,
|
||||
A5BB78B92DF9D8CE009AC3FA /* QuickTerminalSize.swift in Sources */,
|
||||
A57D79272C9C879B001D522E /* SecureInput.swift in Sources */,
|
||||
A5CEAFDC29B8009000646FDA /* SplitView.swift in Sources */,
|
||||
A5593FE12DF8D74000B47B10 /* HiddenTitlebarTerminalWindow.swift in Sources */,
|
||||
A5E4083C2E044DB50035FEAC /* Ghostty.Error.swift in Sources */,
|
||||
A5CDF1932AAF9E0800513312 /* ConfigurationErrorsController.swift in Sources */,
|
||||
A53A6C032CCC1B7F00943E98 /* Ghostty.Action.swift in Sources */,
|
||||
A54B0CED2D0CFB7700CBEFF8 /* ColorizedGhosttyIcon.swift in Sources */,
|
||||
A5CA378C2D2A4DEB00931030 /* KeyboardLayout.swift in Sources */,
|
||||
A54B0CEF2D0D2E2800CBEFF8 /* ColorizedGhosttyIconImage.swift in Sources */,
|
||||
A59FB5D12AE0DEA7009128F3 /* MetalView.swift in Sources */,
|
||||
A599CDB02CF103F60049FA26 /* NSAppearance+Extension.swift in Sources */,
|
||||
A52FFF572CA90484000C6A5B /* QuickTerminalScreen.swift in Sources */,
|
||||
A5CC36132C9CD72D004D6760 /* SecureInputOverlay.swift in Sources */,
|
||||
A5E408402E04532C0035FEAC /* CommandEntity.swift in Sources */,
|
||||
A5E4082A2E022E9E0035FEAC /* TabGroupCloseCoordinator.swift in Sources */,
|
||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */,
|
||||
A53A29882DB69D2F00B6E02C /* TerminalCommandPalette.swift in Sources */,
|
||||
A51BFC202B2FB64F00E92F16 /* AboutController.swift in Sources */,
|
||||
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */,
|
||||
A5E112952AF73E8A00C6E0C2 /* ClipboardConfirmationController.swift in Sources */,
|
||||
A596309E2AEE1D6C00D64628 /* TerminalView.swift in Sources */,
|
||||
A58636662DEF964100E04A10 /* TerminalSplitTreeView.swift in Sources */,
|
||||
A52FFF592CAA4FF3000C6A5B /* Fullscreen.swift in Sources */,
|
||||
C159E81D2B66A06B00FDFE9C /* OSColor+Extension.swift in Sources */,
|
||||
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */,
|
||||
A5E112972AF7401B00C6E0C2 /* ClipboardConfirmationView.swift in Sources */,
|
||||
A514C8D82B54DC6800493A16 /* Ghostty.App.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -438,6 +985,20 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A5CBD0592C9F37B10017A1AE /* Backport.swift in Sources */,
|
||||
A553F4062E05E93000257779 /* Optional+Extension.swift in Sources */,
|
||||
A53D0C942B53B43700305CE6 /* iOSApp.swift in Sources */,
|
||||
A514C8D72B54A16400493A16 /* Ghostty.Config.swift in Sources */,
|
||||
A5333E232B5A219A008AEFF7 /* SurfaceView.swift in Sources */,
|
||||
A5333E202B5A2111008AEFF7 /* SurfaceView_UIKit.swift in Sources */,
|
||||
A5333E1D2B5A1CE3008AEFF7 /* CrossKit.swift in Sources */,
|
||||
A5D689BE2E654D98002E2346 /* Ghostty.Action.swift in Sources */,
|
||||
A53D0C9C2B543F7B00305CE6 /* Package.swift in Sources */,
|
||||
A53D0C9B2B543F3B00305CE6 /* Ghostty.App.swift in Sources */,
|
||||
A5333E242B5A22D9008AEFF7 /* Ghostty.Shell.swift in Sources */,
|
||||
A5985CD82C320C4500C57AD3 /* String+Extension.swift in Sources */,
|
||||
A553F4072E05E93D00257779 /* Array+Extension.swift in Sources */,
|
||||
C159E89D2B69A2EF00FDFE9C /* OSColor+Extension.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@@ -1,35 +0,0 @@
|
||||
import AppKit
|
||||
import AppIntents
|
||||
import GhosttyKit
|
||||
|
||||
struct FocusTerminalIntent: AppIntent {
|
||||
static var title: LocalizedStringResource = "Focus Terminal"
|
||||
static var description = IntentDescription("Move focus to an existing terminal.")
|
||||
|
||||
@Parameter(
|
||||
title: "Terminal",
|
||||
description: "The terminal to focus.",
|
||||
)
|
||||
var terminal: TerminalEntity
|
||||
|
||||
@available(macOS 26.0, *)
|
||||
static var supportedModes: IntentModes = .background
|
||||
|
||||
@MainActor
|
||||
func perform() async throws -> some IntentResult {
|
||||
guard await requestIntentPermission() else {
|
||||
throw GhosttyIntentError.permissionDenied
|
||||
}
|
||||
|
||||
guard let surfaceView = terminal.surfaceView else {
|
||||
throw GhosttyIntentError.surfaceNotFound
|
||||
}
|
||||
|
||||
guard let controller = surfaceView.window?.windowController as? BaseTerminalController else {
|
||||
return .result()
|
||||
}
|
||||
|
||||
controller.focusSurface(surfaceView)
|
||||
return .result()
|
||||
}
|
||||
}
|
@@ -247,22 +247,6 @@ class QuickTerminalController: BaseTerminalController {
|
||||
|
||||
// MARK: Base Controller Overrides
|
||||
|
||||
override func focusSurface(_ view: Ghostty.SurfaceView) {
|
||||
if visible {
|
||||
// If we're visible, we just focus the surface as normal.
|
||||
super.focusSurface(view)
|
||||
return
|
||||
}
|
||||
// Check if target surface belongs to this quick terminal
|
||||
guard surfaceTree.contains(view) else { return }
|
||||
// Set the target surface as focused
|
||||
DispatchQueue.main.async {
|
||||
Ghostty.moveFocus(to: view)
|
||||
}
|
||||
// Animation completion handler will handle window/app activation
|
||||
animateIn()
|
||||
}
|
||||
|
||||
override func surfaceTreeDidChange(from: SplitTree<Ghostty.SurfaceView>, to: SplitTree<Ghostty.SurfaceView>) {
|
||||
super.surfaceTreeDidChange(from: from, to: to)
|
||||
|
||||
|
@@ -233,21 +233,6 @@ class BaseTerminalController: NSWindowController,
|
||||
return newView
|
||||
}
|
||||
|
||||
/// Move focus to a surface view.
|
||||
func focusSurface(_ view: Ghostty.SurfaceView) {
|
||||
// Check if target surface is in our tree
|
||||
guard surfaceTree.contains(view) else { return }
|
||||
|
||||
// Move focus to the target surface and activate the window/app
|
||||
DispatchQueue.main.async {
|
||||
Ghostty.moveFocus(to: view)
|
||||
view.window?.makeKeyAndOrderFront(nil)
|
||||
if !NSApp.isActive {
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Called when the surfaceTree variable changed.
|
||||
///
|
||||
/// Subclasses should call super first.
|
||||
|
@@ -79,7 +79,7 @@ elif [ "$1" != "--update" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
zon2nix "$BUILD_ZIG_ZON" --14 --nix "$WORK_DIR/build.zig.zon.nix" --txt "$WORK_DIR/build.zig.zon.txt" --json "$WORK_DIR/build.zig.zon.json" --flatpak "$WORK_DIR/zig-packages.json"
|
||||
zon2nix "$BUILD_ZIG_ZON" --nix "$WORK_DIR/build.zig.zon.nix" --txt "$WORK_DIR/build.zig.zon.txt" --json "$WORK_DIR/build.zig.zon.json" --flatpak "$WORK_DIR/zig-packages.json"
|
||||
alejandra --quiet "$WORK_DIR/build.zig.zon.nix"
|
||||
prettier --log-level warn --write "$WORK_DIR/build.zig.zon.json"
|
||||
prettier --log-level warn --write "$WORK_DIR/zig-packages.json"
|
||||
@@ -118,3 +118,4 @@ else
|
||||
echo -e "OK: flatpak/zig-packages.json updated."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
@@ -3,7 +3,6 @@
|
||||
lib,
|
||||
stdenv,
|
||||
bashInteractive,
|
||||
doxygen,
|
||||
nushell,
|
||||
appstream,
|
||||
flatpak-builder,
|
||||
@@ -90,7 +89,6 @@ in
|
||||
packages =
|
||||
[
|
||||
# For builds
|
||||
doxygen
|
||||
jq
|
||||
llvmPackages_latest.llvm
|
||||
minisign
|
||||
|
@@ -40,7 +40,7 @@
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "ghostty";
|
||||
version = "1.2.1";
|
||||
version = "1.2.0";
|
||||
|
||||
# We limit source like this to try and reduce the amount of rebuilds as possible
|
||||
# thus we only provide the source that is needed for the build
|
||||
|
@@ -11,7 +11,7 @@ pub fn build(b: *std.Build) !void {
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const imgui_ = b.lazyDependency("imgui", .{});
|
||||
const imgui = b.dependency("imgui", .{});
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "cimgui",
|
||||
.root_module = b.createModule(.{
|
||||
@@ -52,7 +52,7 @@ pub fn build(b: *std.Build) !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (imgui_) |imgui| lib.addIncludePath(imgui.path(""));
|
||||
lib.addIncludePath(imgui.path(""));
|
||||
module.addIncludePath(b.path("vendor"));
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
@@ -72,33 +72,32 @@ pub fn build(b: *std.Build) !void {
|
||||
});
|
||||
}
|
||||
|
||||
if (imgui_) |imgui| {
|
||||
lib.addCSourceFile(.{ .file = b.path("vendor/cimgui.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_draw.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_demo.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_widgets.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_tables.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("misc/freetype/imgui_freetype.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = b.path("vendor/cimgui.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_draw.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_demo.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_widgets.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_tables.cpp"), .flags = flags.items });
|
||||
lib.addCSourceFile(.{ .file = imgui.path("misc/freetype/imgui_freetype.cpp"), .flags = flags.items });
|
||||
|
||||
lib.addCSourceFile(.{
|
||||
.file = imgui.path("backends/imgui_impl_opengl3.cpp"),
|
||||
.flags = flags.items,
|
||||
});
|
||||
|
||||
if (target.result.os.tag.isDarwin()) {
|
||||
if (!target.query.isNative()) {
|
||||
try @import("apple_sdk").addPaths(b, lib);
|
||||
}
|
||||
lib.addCSourceFile(.{
|
||||
.file = imgui.path("backends/imgui_impl_opengl3.cpp"),
|
||||
.file = imgui.path("backends/imgui_impl_metal.mm"),
|
||||
.flags = flags.items,
|
||||
});
|
||||
|
||||
if (target.result.os.tag.isDarwin()) {
|
||||
if (!target.query.isNative()) {
|
||||
try @import("apple_sdk").addPaths(b, lib);
|
||||
}
|
||||
if (target.result.os.tag == .macos) {
|
||||
lib.addCSourceFile(.{
|
||||
.file = imgui.path("backends/imgui_impl_metal.mm"),
|
||||
.file = imgui.path("backends/imgui_impl_osx.mm"),
|
||||
.flags = flags.items,
|
||||
});
|
||||
if (target.result.os.tag == .macos) {
|
||||
lib.addCSourceFile(.{
|
||||
.file = imgui.path("backends/imgui_impl_osx.mm"),
|
||||
.flags = flags.items,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,6 @@
|
||||
// ocornut/imgui
|
||||
.url = "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
|
||||
.hash = "N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3",
|
||||
.lazy = true,
|
||||
},
|
||||
|
||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||
|
@@ -10,11 +10,11 @@ pub fn build(b: *std.Build) !void {
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const upstream = b.lazyDependency("glslang", .{});
|
||||
const upstream = b.dependency("glslang", .{});
|
||||
const lib = try buildGlslang(b, upstream, target, optimize);
|
||||
b.installArtifact(lib);
|
||||
|
||||
if (upstream) |v| module.addIncludePath(v.path(""));
|
||||
module.addIncludePath(upstream.path(""));
|
||||
module.addIncludePath(b.path("override"));
|
||||
|
||||
if (target.query.isNative()) {
|
||||
@@ -38,7 +38,7 @@ pub fn build(b: *std.Build) !void {
|
||||
|
||||
fn buildGlslang(
|
||||
b: *std.Build,
|
||||
upstream_: ?*std.Build.Dependency,
|
||||
upstream: *std.Build.Dependency,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
) !*std.Build.Step.Compile {
|
||||
@@ -52,7 +52,7 @@ fn buildGlslang(
|
||||
});
|
||||
lib.linkLibC();
|
||||
lib.linkLibCpp();
|
||||
if (upstream_) |upstream| lib.addIncludePath(upstream.path(""));
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
lib.addIncludePath(b.path("override"));
|
||||
if (target.result.os.tag.isDarwin()) {
|
||||
const apple_sdk = @import("apple_sdk");
|
||||
@@ -66,89 +66,87 @@ fn buildGlslang(
|
||||
"-fno-sanitize-trap=undefined",
|
||||
});
|
||||
|
||||
if (upstream_) |upstream| {
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
// GenericCodeGen
|
||||
"glslang/GenericCodeGen/CodeGen.cpp",
|
||||
"glslang/GenericCodeGen/Link.cpp",
|
||||
|
||||
// MachineIndependent
|
||||
//"MachineIndependent/glslang.y",
|
||||
"glslang/MachineIndependent/glslang_tab.cpp",
|
||||
"glslang/MachineIndependent/attribute.cpp",
|
||||
"glslang/MachineIndependent/Constant.cpp",
|
||||
"glslang/MachineIndependent/iomapper.cpp",
|
||||
"glslang/MachineIndependent/InfoSink.cpp",
|
||||
"glslang/MachineIndependent/Initialize.cpp",
|
||||
"glslang/MachineIndependent/IntermTraverse.cpp",
|
||||
"glslang/MachineIndependent/Intermediate.cpp",
|
||||
"glslang/MachineIndependent/ParseContextBase.cpp",
|
||||
"glslang/MachineIndependent/ParseHelper.cpp",
|
||||
"glslang/MachineIndependent/PoolAlloc.cpp",
|
||||
"glslang/MachineIndependent/RemoveTree.cpp",
|
||||
"glslang/MachineIndependent/Scan.cpp",
|
||||
"glslang/MachineIndependent/ShaderLang.cpp",
|
||||
"glslang/MachineIndependent/SpirvIntrinsics.cpp",
|
||||
"glslang/MachineIndependent/SymbolTable.cpp",
|
||||
"glslang/MachineIndependent/Versions.cpp",
|
||||
"glslang/MachineIndependent/intermOut.cpp",
|
||||
"glslang/MachineIndependent/limits.cpp",
|
||||
"glslang/MachineIndependent/linkValidate.cpp",
|
||||
"glslang/MachineIndependent/parseConst.cpp",
|
||||
"glslang/MachineIndependent/reflection.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/Pp.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpAtom.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpContext.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpScanner.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpTokens.cpp",
|
||||
"glslang/MachineIndependent/propagateNoContraction.cpp",
|
||||
|
||||
// C Interface
|
||||
"glslang/CInterface/glslang_c_interface.cpp",
|
||||
|
||||
// ResourceLimits
|
||||
"glslang/ResourceLimits/ResourceLimits.cpp",
|
||||
"glslang/ResourceLimits/resource_limits_c.cpp",
|
||||
|
||||
// SPIRV
|
||||
"SPIRV/GlslangToSpv.cpp",
|
||||
"SPIRV/InReadableOrder.cpp",
|
||||
"SPIRV/Logger.cpp",
|
||||
"SPIRV/SpvBuilder.cpp",
|
||||
"SPIRV/SpvPostProcess.cpp",
|
||||
"SPIRV/doc.cpp",
|
||||
"SPIRV/disassemble.cpp",
|
||||
"SPIRV/CInterface/spirv_c_interface.cpp",
|
||||
},
|
||||
});
|
||||
|
||||
if (target.result.os.tag != .windows) {
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
// GenericCodeGen
|
||||
"glslang/GenericCodeGen/CodeGen.cpp",
|
||||
"glslang/GenericCodeGen/Link.cpp",
|
||||
|
||||
// MachineIndependent
|
||||
//"MachineIndependent/glslang.y",
|
||||
"glslang/MachineIndependent/glslang_tab.cpp",
|
||||
"glslang/MachineIndependent/attribute.cpp",
|
||||
"glslang/MachineIndependent/Constant.cpp",
|
||||
"glslang/MachineIndependent/iomapper.cpp",
|
||||
"glslang/MachineIndependent/InfoSink.cpp",
|
||||
"glslang/MachineIndependent/Initialize.cpp",
|
||||
"glslang/MachineIndependent/IntermTraverse.cpp",
|
||||
"glslang/MachineIndependent/Intermediate.cpp",
|
||||
"glslang/MachineIndependent/ParseContextBase.cpp",
|
||||
"glslang/MachineIndependent/ParseHelper.cpp",
|
||||
"glslang/MachineIndependent/PoolAlloc.cpp",
|
||||
"glslang/MachineIndependent/RemoveTree.cpp",
|
||||
"glslang/MachineIndependent/Scan.cpp",
|
||||
"glslang/MachineIndependent/ShaderLang.cpp",
|
||||
"glslang/MachineIndependent/SpirvIntrinsics.cpp",
|
||||
"glslang/MachineIndependent/SymbolTable.cpp",
|
||||
"glslang/MachineIndependent/Versions.cpp",
|
||||
"glslang/MachineIndependent/intermOut.cpp",
|
||||
"glslang/MachineIndependent/limits.cpp",
|
||||
"glslang/MachineIndependent/linkValidate.cpp",
|
||||
"glslang/MachineIndependent/parseConst.cpp",
|
||||
"glslang/MachineIndependent/reflection.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/Pp.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpAtom.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpContext.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpScanner.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpTokens.cpp",
|
||||
"glslang/MachineIndependent/propagateNoContraction.cpp",
|
||||
|
||||
// C Interface
|
||||
"glslang/CInterface/glslang_c_interface.cpp",
|
||||
|
||||
// ResourceLimits
|
||||
"glslang/ResourceLimits/ResourceLimits.cpp",
|
||||
"glslang/ResourceLimits/resource_limits_c.cpp",
|
||||
|
||||
// SPIRV
|
||||
"SPIRV/GlslangToSpv.cpp",
|
||||
"SPIRV/InReadableOrder.cpp",
|
||||
"SPIRV/Logger.cpp",
|
||||
"SPIRV/SpvBuilder.cpp",
|
||||
"SPIRV/SpvPostProcess.cpp",
|
||||
"SPIRV/doc.cpp",
|
||||
"SPIRV/disassemble.cpp",
|
||||
"SPIRV/CInterface/spirv_c_interface.cpp",
|
||||
"glslang/OSDependent/Unix/ossource.cpp",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
"glslang/OSDependent/Windows/ossource.cpp",
|
||||
},
|
||||
});
|
||||
|
||||
if (target.result.os.tag != .windows) {
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
"glslang/OSDependent/Unix/ossource.cpp",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
"glslang/OSDependent/Windows/ossource.cpp",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path(""),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
}
|
||||
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path(""),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@
|
||||
.glslang = .{
|
||||
.url = "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
||||
.hash = "N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy",
|
||||
.lazy = true,
|
||||
},
|
||||
|
||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||
|
@@ -4,7 +4,7 @@ pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const upstream_ = b.lazyDependency("highway", .{});
|
||||
const upstream = b.dependency("highway", .{});
|
||||
|
||||
const module = b.addModule("highway", .{
|
||||
.root_source_file = b.path("main.zig"),
|
||||
@@ -21,10 +21,8 @@ pub fn build(b: *std.Build) !void {
|
||||
.linkage = .static,
|
||||
});
|
||||
lib.linkLibCpp();
|
||||
if (upstream_) |upstream| {
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
module.addIncludePath(upstream.path(""));
|
||||
}
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
module.addIncludePath(upstream.path(""));
|
||||
|
||||
if (target.result.os.tag.isDarwin()) {
|
||||
const apple_sdk = @import("apple_sdk");
|
||||
@@ -76,26 +74,24 @@ pub fn build(b: *std.Build) !void {
|
||||
}
|
||||
|
||||
lib.addCSourceFiles(.{ .flags = flags.items, .files = &.{"bridge.cpp"} });
|
||||
if (upstream_) |upstream| {
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
"hwy/abort.cc",
|
||||
"hwy/aligned_allocator.cc",
|
||||
"hwy/nanobenchmark.cc",
|
||||
"hwy/per_target.cc",
|
||||
"hwy/print.cc",
|
||||
"hwy/targets.cc",
|
||||
"hwy/timer.cc",
|
||||
},
|
||||
});
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path("hwy"),
|
||||
"hwy",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
}
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
"hwy/abort.cc",
|
||||
"hwy/aligned_allocator.cc",
|
||||
"hwy/nanobenchmark.cc",
|
||||
"hwy/per_target.cc",
|
||||
"hwy/print.cc",
|
||||
"hwy/targets.cc",
|
||||
"hwy/timer.cc",
|
||||
},
|
||||
});
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path("hwy"),
|
||||
"hwy",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
b.installArtifact(lib);
|
||||
|
||||
|
@@ -8,7 +8,6 @@
|
||||
.highway = .{
|
||||
.url = "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz",
|
||||
.hash = "N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE",
|
||||
.lazy = true,
|
||||
},
|
||||
|
||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||
|
@@ -4,7 +4,7 @@ pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const upstream_ = b.lazyDependency("libxml2", .{});
|
||||
const upstream = b.dependency("libxml2", .{});
|
||||
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "xml2",
|
||||
@@ -16,7 +16,7 @@ pub fn build(b: *std.Build) !void {
|
||||
});
|
||||
lib.linkLibC();
|
||||
|
||||
if (upstream_) |upstream| lib.addIncludePath(upstream.path("include"));
|
||||
lib.addIncludePath(upstream.path("include"));
|
||||
lib.addIncludePath(b.path("override/include"));
|
||||
if (target.result.os.tag == .windows) {
|
||||
lib.addIncludePath(b.path("override/config/win32"));
|
||||
@@ -97,23 +97,21 @@ pub fn build(b: *std.Build) !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (upstream_) |upstream| {
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.files = srcs,
|
||||
.flags = flags.items,
|
||||
});
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.files = srcs,
|
||||
.flags = flags.items,
|
||||
});
|
||||
|
||||
lib.installHeader(
|
||||
b.path("override/include/libxml/xmlversion.h"),
|
||||
"libxml/xmlversion.h",
|
||||
);
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path("include"),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
}
|
||||
lib.installHeader(
|
||||
b.path("override/include/libxml/xmlversion.h"),
|
||||
"libxml/xmlversion.h",
|
||||
);
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path("include"),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
b.installArtifact(lib);
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@
|
||||
.libxml2 = .{
|
||||
.url = "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
|
||||
.hash = "N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK",
|
||||
.lazy = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ const font_descriptor = @import("text/font_descriptor.zig");
|
||||
const font_manager = @import("text/font_manager.zig");
|
||||
const frame = @import("text/frame.zig");
|
||||
const framesetter = @import("text/framesetter.zig");
|
||||
const typesetter = @import("text/typesetter.zig");
|
||||
const line = @import("text/line.zig");
|
||||
const paragraph_style = @import("text/paragraph_style.zig");
|
||||
const run = @import("text/run.zig");
|
||||
@@ -24,7 +23,6 @@ pub const createFontDescriptorsFromData = font_manager.createFontDescriptorsFrom
|
||||
pub const createFontDescriptorFromData = font_manager.createFontDescriptorFromData;
|
||||
pub const Frame = frame.Frame;
|
||||
pub const Framesetter = framesetter.Framesetter;
|
||||
pub const Typesetter = typesetter.Typesetter;
|
||||
pub const Line = line.Line;
|
||||
pub const ParagraphStyle = paragraph_style.ParagraphStyle;
|
||||
pub const ParagraphStyleSetting = paragraph_style.ParagraphStyleSetting;
|
||||
|
@@ -15,13 +15,10 @@ pub const Run = opaque {
|
||||
return @intCast(c.CTRunGetGlyphCount(@ptrCast(self)));
|
||||
}
|
||||
|
||||
pub fn getGlyphsPtr(self: *Run) ?[]const graphics.Glyph {
|
||||
pub fn getGlyphsPtr(self: *Run) []const graphics.Glyph {
|
||||
const len = self.getGlyphCount();
|
||||
if (len == 0) return &.{};
|
||||
const ptr: [*c]const graphics.Glyph = @ptrCast(
|
||||
c.CTRunGetGlyphsPtr(@ptrCast(self)),
|
||||
);
|
||||
if (ptr == null) return null;
|
||||
const ptr = c.CTRunGetGlyphsPtr(@ptrCast(self)) orelse &.{};
|
||||
return ptr[0..len];
|
||||
}
|
||||
|
||||
@@ -37,13 +34,10 @@ pub const Run = opaque {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pub fn getPositionsPtr(self: *Run) ?[]const graphics.Point {
|
||||
pub fn getPositionsPtr(self: *Run) []const graphics.Point {
|
||||
const len = self.getGlyphCount();
|
||||
if (len == 0) return &.{};
|
||||
const ptr: [*c]const graphics.Point = @ptrCast(
|
||||
c.CTRunGetPositionsPtr(@ptrCast(self)),
|
||||
);
|
||||
if (ptr == null) return null;
|
||||
const ptr = c.CTRunGetPositionsPtr(@ptrCast(self)) orelse &.{};
|
||||
return ptr[0..len];
|
||||
}
|
||||
|
||||
@@ -59,13 +53,10 @@ pub const Run = opaque {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pub fn getAdvancesPtr(self: *Run) ?[]const graphics.Size {
|
||||
pub fn getAdvancesPtr(self: *Run) []const graphics.Size {
|
||||
const len = self.getGlyphCount();
|
||||
if (len == 0) return &.{};
|
||||
const ptr: [*c]const graphics.Size = @ptrCast(
|
||||
c.CTRunGetAdvancesPtr(@ptrCast(self)),
|
||||
);
|
||||
if (ptr == null) return null;
|
||||
const ptr = c.CTRunGetAdvancesPtr(@ptrCast(self)) orelse &.{};
|
||||
return ptr[0..len];
|
||||
}
|
||||
|
||||
@@ -81,13 +72,10 @@ pub const Run = opaque {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pub fn getStringIndicesPtr(self: *Run) ?[]const usize {
|
||||
pub fn getStringIndicesPtr(self: *Run) []const usize {
|
||||
const len = self.getGlyphCount();
|
||||
if (len == 0) return &.{};
|
||||
const ptr: [*c]const usize = @ptrCast(
|
||||
c.CTRunGetStringIndicesPtr(@ptrCast(self)),
|
||||
);
|
||||
if (ptr == null) return null;
|
||||
const ptr = c.CTRunGetStringIndicesPtr(@ptrCast(self)) orelse &.{};
|
||||
return ptr[0..len];
|
||||
}
|
||||
|
||||
@@ -102,16 +90,4 @@ pub const Run = opaque {
|
||||
);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pub fn getStatus(self: *Run) Status {
|
||||
return @bitCast(c.CTRunGetStatus(@ptrCast(self)));
|
||||
}
|
||||
};
|
||||
|
||||
/// https://developer.apple.com/documentation/coretext/ctrunstatus?language=objc
|
||||
pub const Status = packed struct(u32) {
|
||||
right_to_left: bool,
|
||||
non_monotonic: bool,
|
||||
has_non_identity_matrix: bool,
|
||||
_pad: u29 = 0,
|
||||
};
|
||||
|
@@ -1,36 +0,0 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const foundation = @import("../foundation.zig");
|
||||
const graphics = @import("../graphics.zig");
|
||||
const text = @import("../text.zig");
|
||||
const c = @import("c.zig").c;
|
||||
|
||||
pub const Typesetter = opaque {
|
||||
pub fn createWithAttributedStringAndOptions(
|
||||
str: *foundation.AttributedString,
|
||||
opts: *foundation.Dictionary,
|
||||
) Allocator.Error!*Typesetter {
|
||||
return @as(
|
||||
?*Typesetter,
|
||||
@ptrFromInt(@intFromPtr(c.CTTypesetterCreateWithAttributedStringAndOptions(
|
||||
@ptrCast(str),
|
||||
@ptrCast(opts),
|
||||
))),
|
||||
) orelse Allocator.Error.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn release(self: *Typesetter) void {
|
||||
foundation.CFRelease(self);
|
||||
}
|
||||
|
||||
pub fn createLine(
|
||||
self: *Typesetter,
|
||||
range: foundation.c.CFRange,
|
||||
) *text.Line {
|
||||
return @ptrFromInt(@intFromPtr(c.CTTypesetterCreateLine(
|
||||
@ptrCast(self),
|
||||
range,
|
||||
)));
|
||||
}
|
||||
};
|
@@ -4,19 +4,16 @@ pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const module = b.addModule("spirv_cross", .{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize });
|
||||
const upstream = b.dependency("spirv_cross", .{});
|
||||
|
||||
// For dynamic linking, we prefer dynamic linking and to search by
|
||||
// mode first. Mode first will search all paths for a dynamic library
|
||||
// before falling back to static.
|
||||
const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{
|
||||
.preferred_link_mode = .dynamic,
|
||||
.search_strategy = .mode_first,
|
||||
};
|
||||
const module = b.addModule("spirv_cross", .{ .root_source_file = b.path("main.zig") });
|
||||
module.addIncludePath(upstream.path(""));
|
||||
|
||||
const lib = try buildSpirvCross(b, upstream, target, optimize);
|
||||
b.installArtifact(lib);
|
||||
|
||||
var test_exe: ?*std.Build.Step.Compile = null;
|
||||
if (target.query.isNative()) {
|
||||
test_exe = b.addTest(.{
|
||||
const test_exe = b.addTest(.{
|
||||
.name = "test",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("main.zig"),
|
||||
@@ -24,28 +21,19 @@ pub fn build(b: *std.Build) !void {
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
const tests_run = b.addRunArtifact(test_exe.?);
|
||||
test_exe.linkLibrary(lib);
|
||||
const tests_run = b.addRunArtifact(test_exe);
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&tests_run.step);
|
||||
|
||||
// Uncomment this if we're debugging tests
|
||||
// b.installArtifact(test_exe.?);
|
||||
}
|
||||
if (b.systemIntegrationOption("spirv-cross", .{})) {
|
||||
module.linkSystemLibrary("spirv-cross-c-shared", dynamic_link_opts);
|
||||
if (test_exe) |exe| {
|
||||
exe.linkSystemLibrary2("spirv-cross-c-shared", dynamic_link_opts);
|
||||
}
|
||||
} else {
|
||||
const lib = try buildSpirvCross(b, module, target, optimize);
|
||||
b.installArtifact(lib);
|
||||
if (test_exe) |exe| exe.linkLibrary(lib);
|
||||
// b.installArtifact(test_exe);
|
||||
}
|
||||
}
|
||||
|
||||
fn buildSpirvCross(
|
||||
b: *std.Build,
|
||||
module: *std.Build.Module,
|
||||
upstream: *std.Build.Dependency,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
) !*std.Build.Step.Compile {
|
||||
@@ -74,36 +62,32 @@ fn buildSpirvCross(
|
||||
"-fno-sanitize-trap=undefined",
|
||||
});
|
||||
|
||||
if (b.lazyDependency("spirv_cross", .{})) |upstream| {
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
module.addIncludePath(upstream.path(""));
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
// Core
|
||||
"spirv_cross.cpp",
|
||||
"spirv_parser.cpp",
|
||||
"spirv_cross_parsed_ir.cpp",
|
||||
"spirv_cfg.cpp",
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
.files = &.{
|
||||
// Core
|
||||
"spirv_cross.cpp",
|
||||
"spirv_parser.cpp",
|
||||
"spirv_cross_parsed_ir.cpp",
|
||||
"spirv_cfg.cpp",
|
||||
|
||||
// C
|
||||
"spirv_cross_c.cpp",
|
||||
// C
|
||||
"spirv_cross_c.cpp",
|
||||
|
||||
// GLSL
|
||||
"spirv_glsl.cpp",
|
||||
// GLSL
|
||||
"spirv_glsl.cpp",
|
||||
|
||||
// MSL
|
||||
"spirv_msl.cpp",
|
||||
},
|
||||
});
|
||||
// MSL
|
||||
"spirv_msl.cpp",
|
||||
},
|
||||
});
|
||||
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path(""),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
}
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path(""),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@
|
||||
.spirv_cross = .{
|
||||
.url = "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz",
|
||||
.hash = "N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv",
|
||||
.lazy = true,
|
||||
},
|
||||
|
||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||
|
40
pkg/utf8proc/build.zig
Normal file
40
pkg/utf8proc/build.zig
Normal file
@@ -0,0 +1,40 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const module = b.addModule("utf8proc", .{ .root_source_file = .{ .path = "main.zig" } });
|
||||
|
||||
const upstream = b.dependency("utf8proc", .{});
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "utf8proc",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
.linkage = .static,
|
||||
});
|
||||
lib.linkLibC();
|
||||
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
module.addIncludePath(upstream.path(""));
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
try flags.append("-DUTF8PROC_EXPORTS");
|
||||
defer flags.deinit();
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.files = &.{"utf8proc.c"},
|
||||
.flags = flags.items,
|
||||
});
|
||||
|
||||
lib.installHeadersDirectoryOptions(.{
|
||||
.source_dir = upstream.path(""),
|
||||
.install_dir = .header,
|
||||
.install_subdir = "",
|
||||
.include_extensions = &.{".h"},
|
||||
});
|
||||
|
||||
b.installArtifact(lib);
|
||||
}
|
11
pkg/utf8proc/build.zig.zon
Normal file
11
pkg/utf8proc/build.zig.zon
Normal file
@@ -0,0 +1,11 @@
|
||||
.{
|
||||
.name = "utf8proc",
|
||||
.version = "2.8.0",
|
||||
.paths = .{""},
|
||||
.dependencies = .{
|
||||
.utf8proc = .{
|
||||
.url = "https://github.com/JuliaStrings/utf8proc/archive/refs/tags/v2.8.0.tar.gz",
|
||||
.hash = "1220056ce228a8c58f1fa66ab778f5c8965e62f720c1d30603c7d534cb7d8a605ad7",
|
||||
},
|
||||
},
|
||||
}
|
3
pkg/utf8proc/c.zig
Normal file
3
pkg/utf8proc/c.zig
Normal file
@@ -0,0 +1,3 @@
|
||||
pub const c = @cImport({
|
||||
@cInclude("utf8proc.h");
|
||||
});
|
20
pkg/utf8proc/main.zig
Normal file
20
pkg/utf8proc/main.zig
Normal file
@@ -0,0 +1,20 @@
|
||||
pub const c = @import("c.zig").c;
|
||||
|
||||
/// Given a codepoint, return a character width analogous to `wcwidth(codepoint)`,
|
||||
/// except that a width of 0 is returned for non-printable codepoints
|
||||
/// instead of -1 as in `wcwidth`.
|
||||
pub fn charwidth(codepoint: u21) u8 {
|
||||
return @intCast(c.utf8proc_charwidth(@intCast(codepoint)));
|
||||
}
|
||||
|
||||
/// Given a pair of consecutive codepoints, return whether a grapheme break is
|
||||
/// permitted between them (as defined by the extended grapheme clusters in UAX#29).
|
||||
pub fn graphemeBreakStateful(cp1: u21, cp2: u21, state: *i32) bool {
|
||||
return c.utf8proc_grapheme_break_stateful(
|
||||
@intCast(cp1),
|
||||
@intCast(cp2),
|
||||
state,
|
||||
);
|
||||
}
|
||||
|
||||
test {}
|
@@ -131,11 +131,12 @@ which should be filled in accordingly. You can then add your translations
|
||||
within the newly created translation file.
|
||||
|
||||
Afterwards, you need to update the list of known locales within Ghostty's
|
||||
build system. To do so, open `src/os/i18n_locales.zig` and find the list
|
||||
of locales after the comments, then add the full locale name into the list.
|
||||
build system. To do so, open `src/os/i18n.zig` and find the list
|
||||
of locales under the `locales` variable, then add the full locale name
|
||||
into the list.
|
||||
|
||||
The order matters, so make sure to place your locale in the correct position.
|
||||
Read the comments present in the file for more details on the order. If you're
|
||||
Read the comment above the variable for more details on the order. If you're
|
||||
unsure, place it at the end of the list.
|
||||
|
||||
```zig
|
||||
@@ -145,7 +146,7 @@ const locales = [_][]const u8{
|
||||
}
|
||||
```
|
||||
|
||||
You should then be able to run `zig build` and see your translations in action!
|
||||
You should then be able to run `zig build` and see your translations in action.
|
||||
|
||||
Before opening a pull request with the new translation file, you should also add
|
||||
your locale to the `CODEOWNERS` file. Find the `# Localization` section near the
|
||||
|
@@ -404,6 +404,91 @@ pub fn getData(self: Command, comptime DT: type) ?*DT {
|
||||
return if (self.data) |ptr| @ptrCast(@alignCast(ptr)) else null;
|
||||
}
|
||||
|
||||
/// Search for "cmd" in the PATH and return the absolute path. This will
|
||||
/// always allocate if there is a non-null result. The caller must free the
|
||||
/// resulting value.
|
||||
pub fn expandPath(alloc: Allocator, cmd: []const u8) !?[]u8 {
|
||||
// If the command already contains a slash, then we return it as-is
|
||||
// because it is assumed to be absolute or relative.
|
||||
if (std.mem.indexOfScalar(u8, cmd, '/') != null) {
|
||||
return try alloc.dupe(u8, cmd);
|
||||
}
|
||||
|
||||
const PATH = switch (builtin.os.tag) {
|
||||
.windows => blk: {
|
||||
const win_path = std.process.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("PATH")) orelse return null;
|
||||
const path = try std.unicode.utf16LeToUtf8Alloc(alloc, win_path);
|
||||
break :blk path;
|
||||
},
|
||||
else => std.posix.getenvZ("PATH") orelse return null,
|
||||
};
|
||||
defer if (builtin.os.tag == .windows) alloc.free(PATH);
|
||||
|
||||
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
var it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter);
|
||||
var seen_eacces = false;
|
||||
while (it.next()) |search_path| {
|
||||
// We need enough space in our path buffer to store this
|
||||
const path_len = search_path.len + cmd.len + 1;
|
||||
if (path_buf.len < path_len) return error.PathTooLong;
|
||||
|
||||
// Copy in the full path
|
||||
@memcpy(path_buf[0..search_path.len], search_path);
|
||||
path_buf[search_path.len] = std.fs.path.sep;
|
||||
@memcpy(path_buf[search_path.len + 1 ..][0..cmd.len], cmd);
|
||||
path_buf[path_len] = 0;
|
||||
const full_path = path_buf[0..path_len :0];
|
||||
|
||||
// Stat it
|
||||
const f = std.fs.cwd().openFile(
|
||||
full_path,
|
||||
.{},
|
||||
) catch |err| switch (err) {
|
||||
error.FileNotFound => continue,
|
||||
error.AccessDenied => {
|
||||
// Accumulate this and return it later so we can try other
|
||||
// paths that we have access to.
|
||||
seen_eacces = true;
|
||||
continue;
|
||||
},
|
||||
else => return err,
|
||||
};
|
||||
defer f.close();
|
||||
const stat = try f.stat();
|
||||
if (stat.kind != .directory and isExecutable(stat.mode)) {
|
||||
return try alloc.dupe(u8, full_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (seen_eacces) return error.AccessDenied;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
fn isExecutable(mode: std.fs.File.Mode) bool {
|
||||
if (builtin.os.tag == .windows) return true;
|
||||
return mode & 0o0111 != 0;
|
||||
}
|
||||
|
||||
// `uname -n` is the *nix equivalent of `hostname.exe` on Windows
|
||||
test "expandPath: hostname" {
|
||||
const executable = if (builtin.os.tag == .windows) "hostname.exe" else "uname";
|
||||
const path = (try expandPath(testing.allocator, executable)).?;
|
||||
defer testing.allocator.free(path);
|
||||
try testing.expect(path.len > executable.len);
|
||||
}
|
||||
|
||||
test "expandPath: does not exist" {
|
||||
const path = try expandPath(testing.allocator, "thisreallyprobablydoesntexist123");
|
||||
try testing.expect(path == null);
|
||||
}
|
||||
|
||||
test "expandPath: slash" {
|
||||
const path = (try expandPath(testing.allocator, "foo/env")).?;
|
||||
defer testing.allocator.free(path);
|
||||
try testing.expect(path.len == 7);
|
||||
}
|
||||
|
||||
// Copied from Zig. This is a publicly exported function but there is no
|
||||
// way to get it from the std package.
|
||||
fn createNullDelimitedEnvMap(arena: mem.Allocator, env_map: *const EnvMap) ![:null]?[*:0]u8 {
|
||||
|
@@ -23,7 +23,6 @@ pub const embedded = @import("apprt/embedded.zig");
|
||||
pub const surface = @import("apprt/surface.zig");
|
||||
|
||||
pub const Action = action.Action;
|
||||
pub const Runtime = @import("apprt/runtime.zig").Runtime;
|
||||
pub const Target = action.Target;
|
||||
|
||||
pub const ContentScale = structs.ContentScale;
|
||||
@@ -52,6 +51,30 @@ pub const runtime = switch (build_config.artifact) {
|
||||
pub const App = runtime.App;
|
||||
pub const Surface = runtime.Surface;
|
||||
|
||||
/// Runtime is the runtime to use for Ghostty. All runtimes do not provide
|
||||
/// equivalent feature sets.
|
||||
pub const Runtime = enum {
|
||||
/// Will not produce an executable at all when `zig build` is called.
|
||||
/// This is only useful if you're only interested in the lib only (macOS).
|
||||
none,
|
||||
|
||||
/// GTK4. Rich windowed application. This uses a full GObject-based
|
||||
/// approach to building the application.
|
||||
gtk,
|
||||
|
||||
pub fn default(target: std.Target) Runtime {
|
||||
return switch (target.os.tag) {
|
||||
// The Linux and FreeBSD default is GTK because it is a full
|
||||
// featured application.
|
||||
.linux, .freebsd => .gtk,
|
||||
// Otherwise, we do NONE so we don't create an exe and we create
|
||||
// libghostty. On macOS, Xcode is used to build the app that links
|
||||
// to libghostty.
|
||||
else => .none,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
test {
|
||||
_ = Runtime;
|
||||
_ = runtime;
|
||||
|
@@ -42,70 +42,6 @@ const GlobalShortcuts = @import("global_shortcuts.zig").GlobalShortcuts;
|
||||
|
||||
const log = std.log.scoped(.gtk_ghostty_application);
|
||||
|
||||
/// Function used to funnel GLib/GObject/GTK log messages into Zig's logging
|
||||
/// system rather than just getting dumped directly to stderr.
|
||||
fn glibLogWriterFunction(
|
||||
level: glib.LogLevelFlags,
|
||||
fields: [*]const glib.LogField,
|
||||
n_fields: usize,
|
||||
_: ?*anyopaque,
|
||||
) callconv(.c) glib.LogWriterOutput {
|
||||
const glib_log = std.log.scoped(.glib);
|
||||
|
||||
var message_: ?[]const u8 = null;
|
||||
var domain_: ?[]const u8 = null;
|
||||
for (0..n_fields) |i| {
|
||||
const field = fields[i];
|
||||
const k = std.mem.span(field.f_key orelse continue);
|
||||
const v: []const u8 = v: {
|
||||
if (field.f_length >= 0) {
|
||||
const v: [*]const u8 = @ptrCast(field.f_value orelse continue);
|
||||
break :v v[0..@intCast(field.f_length)];
|
||||
}
|
||||
const v: [*:0]const u8 = @ptrCast(field.f_value orelse continue);
|
||||
break :v std.mem.span(v);
|
||||
};
|
||||
if (std.mem.eql(u8, k, "MESSAGE")) {
|
||||
message_ = v;
|
||||
continue;
|
||||
}
|
||||
if (std.mem.eql(u8, k, "GLIB_DOMAIN")) {
|
||||
domain_ = v;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const message = message_ orelse return .unhandled;
|
||||
const domain = domain_ orelse "«unknown»";
|
||||
|
||||
if (level.level_error) {
|
||||
glib_log.err("ERROR: {s}: {s}", .{ domain, message });
|
||||
return .handled;
|
||||
}
|
||||
if (level.level_critical) {
|
||||
glib_log.err("CRITICAL: {s}: {s}", .{ domain, message });
|
||||
return .handled;
|
||||
}
|
||||
if (level.level_warning) {
|
||||
glib_log.warn("WARNING: {s}: {s}", .{ domain, message });
|
||||
return .handled;
|
||||
}
|
||||
if (level.level_message) {
|
||||
glib_log.info("MESSAGE: {s}: {s}", .{ domain, message });
|
||||
return .handled;
|
||||
}
|
||||
if (level.level_info) {
|
||||
glib_log.info("INFO: {s}: {s}", .{ domain, message });
|
||||
return .handled;
|
||||
}
|
||||
if (level.level_debug) {
|
||||
glib_log.debug("DEBUG: {s}: {s}", .{ domain, message });
|
||||
return .handled;
|
||||
}
|
||||
glib_log.debug("UNKNOWN: {s}: {s}", .{ domain, message });
|
||||
return .handled;
|
||||
}
|
||||
|
||||
/// The primary entrypoint for the Ghostty GTK application.
|
||||
///
|
||||
/// This requires a `ghostty.App` and `ghostty.Config` and takes
|
||||
@@ -241,10 +177,6 @@ pub const Application = extern struct {
|
||||
) Allocator.Error!*Self {
|
||||
const alloc = core_app.alloc;
|
||||
|
||||
// Capture GLib/GObject/GTK log messages and funnel them through Zig's
|
||||
// logging system rather than just getting dumped directly to stderr.
|
||||
_ = glib.logSetWriterFunc(glibLogWriterFunction, null, null);
|
||||
|
||||
// Log our GTK versions
|
||||
gtk_version.logVersion();
|
||||
adw_version.logVersion();
|
||||
|
@@ -51,13 +51,6 @@ pub const Surface = extern struct {
|
||||
pub const Tree = datastruct.SplitTree(Self);
|
||||
|
||||
pub const properties = struct {
|
||||
/// This property is set to true when the bell is ringing. Note that
|
||||
/// this property will only emit a changed signal when there is a
|
||||
/// full state change. If a bell is ringing and another bell event
|
||||
/// comes through, the change notification will NOT be emitted.
|
||||
///
|
||||
/// If you need to know every scenario the bell is triggered,
|
||||
/// listen to the `bell` signal instead.
|
||||
pub const @"bell-ringing" = struct {
|
||||
pub const name = "bell-ringing";
|
||||
const impl = gobject.ext.defineProperty(
|
||||
@@ -303,19 +296,6 @@ pub const Surface = extern struct {
|
||||
};
|
||||
|
||||
pub const signals = struct {
|
||||
/// Emitted whenever the bell event is received. Unlike the
|
||||
/// `bell-ringing` property, this is emitted every time the event
|
||||
/// is received and not just on state changes.
|
||||
pub const bell = struct {
|
||||
pub const name = "bell";
|
||||
pub const connect = impl.connect;
|
||||
const impl = gobject.ext.defineSignal(
|
||||
name,
|
||||
Self,
|
||||
&.{},
|
||||
void,
|
||||
);
|
||||
};
|
||||
/// Emitted whenever the surface would like to be closed for any
|
||||
/// reason.
|
||||
///
|
||||
@@ -1694,16 +1674,6 @@ pub const Surface = extern struct {
|
||||
}
|
||||
|
||||
pub fn setBellRinging(self: *Self, ringing: bool) void {
|
||||
// Prevent duplicate change notifications if the signals we emit
|
||||
// in this function cause this state to change again.
|
||||
self.as(gobject.Object).freezeNotify();
|
||||
defer self.as(gobject.Object).thawNotify();
|
||||
|
||||
// Logic around bell reaction happens on every event even if we're
|
||||
// already in the ringing state.
|
||||
if (ringing) self.ringBell();
|
||||
|
||||
// Property change only happens on actual state change
|
||||
const priv = self.private();
|
||||
if (priv.bell_ringing == ringing) return;
|
||||
priv.bell_ringing = ringing;
|
||||
@@ -1888,26 +1858,20 @@ pub const Surface = extern struct {
|
||||
self.as(gtk.Widget).setCursorFromName(name.ptr);
|
||||
}
|
||||
|
||||
/// Handle bell features that need to happen every time a BEL is received
|
||||
/// Currently this is audio and system but this could change in the future.
|
||||
fn ringBell(self: *Self) void {
|
||||
fn propBellRinging(
|
||||
self: *Self,
|
||||
_: *gobject.ParamSpec,
|
||||
_: ?*anyopaque,
|
||||
) callconv(.c) void {
|
||||
const priv = self.private();
|
||||
|
||||
// Emit the signal
|
||||
signals.bell.impl.emit(
|
||||
self,
|
||||
null,
|
||||
.{},
|
||||
null,
|
||||
);
|
||||
if (!priv.bell_ringing) return;
|
||||
|
||||
// Activate actions if they exist
|
||||
_ = self.as(gtk.Widget).activateAction("tab.ring-bell", null);
|
||||
_ = self.as(gtk.Widget).activateAction("win.ring-bell", null);
|
||||
|
||||
const config = if (priv.config) |c| c.get() else return;
|
||||
|
||||
// Do our sound
|
||||
const config = if (priv.config) |c| c.get() else return;
|
||||
if (config.@"bell-features".audio) audio: {
|
||||
const config_path = config.@"bell-audio-path" orelse break :audio;
|
||||
const path, const required = switch (config_path) {
|
||||
@@ -2895,6 +2859,7 @@ pub const Surface = extern struct {
|
||||
class.bindTemplateCallback("notify_mouse_hover_url", &propMouseHoverUrl);
|
||||
class.bindTemplateCallback("notify_mouse_hidden", &propMouseHidden);
|
||||
class.bindTemplateCallback("notify_mouse_shape", &propMouseShape);
|
||||
class.bindTemplateCallback("notify_bell_ringing", &propBellRinging);
|
||||
class.bindTemplateCallback("should_border_be_shown", &closureShouldBorderBeShown);
|
||||
class.bindTemplateCallback("should_unfocused_split_be_shown", &closureShouldUnfocusedSplitBeShown);
|
||||
|
||||
@@ -2919,7 +2884,6 @@ pub const Surface = extern struct {
|
||||
});
|
||||
|
||||
// Signals
|
||||
signals.bell.impl.register(.{});
|
||||
signals.@"close-request".impl.register(.{});
|
||||
signals.@"clipboard-read".impl.register(.{});
|
||||
signals.@"clipboard-write".impl.register(.{});
|
||||
|
@@ -169,6 +169,7 @@ template $GhosttySurface: Adw.Bin {
|
||||
"surface",
|
||||
]
|
||||
|
||||
notify::bell-ringing => $notify_bell_ringing();
|
||||
notify::config => $notify_config();
|
||||
notify::error => $notify_error();
|
||||
notify::mouse-hover-url => $notify_mouse_hover_url();
|
||||
|
@@ -1,29 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
/// Runtime is the runtime to use for Ghostty. All runtimes do not provide
|
||||
/// equivalent feature sets.
|
||||
pub const Runtime = enum {
|
||||
/// Will not produce an executable at all when `zig build` is called.
|
||||
/// This is only useful if you're only interested in the lib only (macOS).
|
||||
none,
|
||||
|
||||
/// GTK4. Rich windowed application. This uses a full GObject-based
|
||||
/// approach to building the application.
|
||||
gtk,
|
||||
|
||||
pub fn default(target: std.Target) Runtime {
|
||||
return switch (target.os.tag) {
|
||||
// The Linux and FreeBSD default is GTK because it is a full
|
||||
// featured application.
|
||||
.linux, .freebsd => .gtk,
|
||||
// Otherwise, we do NONE so we don't create an exe and we create
|
||||
// libghostty. On macOS, Xcode is used to build the app that links
|
||||
// to libghostty.
|
||||
else => .none,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
test {
|
||||
_ = Runtime;
|
||||
}
|
@@ -10,7 +10,6 @@ const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Benchmark = @import("Benchmark.zig");
|
||||
const options = @import("options.zig");
|
||||
const uucode = @import("uucode");
|
||||
const UTF8Decoder = @import("../terminal/UTF8Decoder.zig");
|
||||
const simd = @import("../simd/main.zig");
|
||||
const table = @import("../unicode/main.zig").table;
|
||||
@@ -48,9 +47,6 @@ pub const Mode = enum {
|
||||
|
||||
/// Test our lookup table implementation.
|
||||
table,
|
||||
|
||||
/// Using uucode, with custom `width` extension based on `wcwidth`.
|
||||
uucode,
|
||||
};
|
||||
|
||||
/// Create a new terminal stream handler for the given arguments.
|
||||
@@ -75,7 +71,6 @@ pub fn benchmark(self: *CodepointWidth) Benchmark {
|
||||
.wcwidth => stepWcwidth,
|
||||
.table => stepTable,
|
||||
.simd => stepSimd,
|
||||
.uucode => stepUucode,
|
||||
},
|
||||
.setupFn = setup,
|
||||
.teardownFn = teardown,
|
||||
@@ -185,35 +180,6 @@ fn stepSimd(ptr: *anyopaque) Benchmark.Error!void {
|
||||
}
|
||||
}
|
||||
|
||||
fn stepUucode(ptr: *anyopaque) Benchmark.Error!void {
|
||||
const self: *CodepointWidth = @ptrCast(@alignCast(ptr));
|
||||
|
||||
const f = self.data_f orelse return;
|
||||
var r = std.io.bufferedReader(f.reader());
|
||||
var d: UTF8Decoder = .{};
|
||||
var buf: [4096]u8 align(std.atomic.cache_line) = undefined;
|
||||
while (true) {
|
||||
const n = r.read(&buf) catch |err| {
|
||||
log.warn("error reading data file err={}", .{err});
|
||||
return error.BenchmarkFailed;
|
||||
};
|
||||
if (n == 0) break; // EOF reached
|
||||
|
||||
for (buf[0..n]) |c| {
|
||||
const cp_, const consumed = d.next(c);
|
||||
assert(consumed);
|
||||
if (cp_) |cp| {
|
||||
// This is the same trick we do in terminal.zig so we
|
||||
// keep it here.
|
||||
std.mem.doNotOptimizeAway(if (cp <= 0xFF)
|
||||
1
|
||||
else
|
||||
uucode.get(.width, @intCast(cp)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test CodepointWidth {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
@@ -8,7 +8,6 @@ const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Benchmark = @import("Benchmark.zig");
|
||||
const options = @import("options.zig");
|
||||
const uucode = @import("uucode");
|
||||
const UTF8Decoder = @import("../terminal/UTF8Decoder.zig");
|
||||
const unicode = @import("../unicode/main.zig");
|
||||
|
||||
@@ -39,9 +38,6 @@ pub const Mode = enum {
|
||||
|
||||
/// Ghostty's table-based approach.
|
||||
table,
|
||||
|
||||
/// uucode implementation
|
||||
uucode,
|
||||
};
|
||||
|
||||
/// Create a new terminal stream handler for the given arguments.
|
||||
@@ -64,7 +60,6 @@ pub fn benchmark(self: *GraphemeBreak) Benchmark {
|
||||
.stepFn = switch (self.opts.mode) {
|
||||
.noop => stepNoop,
|
||||
.table => stepTable,
|
||||
.uucode => stepUucode,
|
||||
},
|
||||
.setupFn = setup,
|
||||
.teardownFn = teardown,
|
||||
@@ -138,33 +133,6 @@ fn stepTable(ptr: *anyopaque) Benchmark.Error!void {
|
||||
}
|
||||
}
|
||||
|
||||
fn stepUucode(ptr: *anyopaque) Benchmark.Error!void {
|
||||
const self: *GraphemeBreak = @ptrCast(@alignCast(ptr));
|
||||
|
||||
const f = self.data_f orelse return;
|
||||
var r = std.io.bufferedReader(f.reader());
|
||||
var d: UTF8Decoder = .{};
|
||||
var state: uucode.grapheme.BreakState = .default;
|
||||
var cp1: u21 = 0;
|
||||
var buf: [4096]u8 align(std.atomic.cache_line) = undefined;
|
||||
while (true) {
|
||||
const n = r.read(&buf) catch |err| {
|
||||
log.warn("error reading data file err={}", .{err});
|
||||
return error.BenchmarkFailed;
|
||||
};
|
||||
if (n == 0) break; // EOF reached
|
||||
|
||||
for (buf[0..n]) |c| {
|
||||
const cp_, const consumed = d.next(c);
|
||||
assert(consumed);
|
||||
if (cp_) |cp2| {
|
||||
std.mem.doNotOptimizeAway(uucode.grapheme.isBreak(cp1, @intCast(cp2), &state));
|
||||
cp1 = cp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test GraphemeBreak {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
@@ -10,8 +10,7 @@ const Allocator = std.mem.Allocator;
|
||||
const Benchmark = @import("Benchmark.zig");
|
||||
const options = @import("options.zig");
|
||||
const UTF8Decoder = @import("../terminal/UTF8Decoder.zig");
|
||||
const uucode = @import("uucode");
|
||||
const symbols_table = @import("../unicode/symbols_table.zig").table;
|
||||
const symbols = @import("../unicode/symbols.zig");
|
||||
|
||||
const log = std.log.scoped(.@"is-symbol-bench");
|
||||
|
||||
@@ -22,7 +21,7 @@ data_f: ?std.fs.File = null,
|
||||
|
||||
pub const Options = struct {
|
||||
/// Which test to run.
|
||||
mode: Mode = .uucode,
|
||||
mode: Mode = .ziglyph,
|
||||
|
||||
/// The data to read as a filepath. If this is "-" then
|
||||
/// we will read stdin. If this is unset, then we will
|
||||
@@ -33,8 +32,8 @@ pub const Options = struct {
|
||||
};
|
||||
|
||||
pub const Mode = enum {
|
||||
/// uucode implementation
|
||||
uucode,
|
||||
/// "Naive" ziglyph implementation.
|
||||
ziglyph,
|
||||
|
||||
/// Ghostty's table-based approach.
|
||||
table,
|
||||
@@ -58,7 +57,7 @@ pub fn destroy(self: *IsSymbol, alloc: Allocator) void {
|
||||
pub fn benchmark(self: *IsSymbol) Benchmark {
|
||||
return .init(self, .{
|
||||
.stepFn = switch (self.opts.mode) {
|
||||
.uucode => stepUucode,
|
||||
.ziglyph => stepZiglyph,
|
||||
.table => stepTable,
|
||||
},
|
||||
.setupFn = setup,
|
||||
@@ -86,7 +85,7 @@ fn teardown(ptr: *anyopaque) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn stepUucode(ptr: *anyopaque) Benchmark.Error!void {
|
||||
fn stepZiglyph(ptr: *anyopaque) Benchmark.Error!void {
|
||||
const self: *IsSymbol = @ptrCast(@alignCast(ptr));
|
||||
|
||||
const f = self.data_f orelse return;
|
||||
@@ -104,7 +103,7 @@ fn stepUucode(ptr: *anyopaque) Benchmark.Error!void {
|
||||
const cp_, const consumed = d.next(c);
|
||||
assert(consumed);
|
||||
if (cp_) |cp| {
|
||||
std.mem.doNotOptimizeAway(uucode.get(.is_symbol, cp));
|
||||
std.mem.doNotOptimizeAway(symbols.isSymbol(cp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +127,7 @@ fn stepTable(ptr: *anyopaque) Benchmark.Error!void {
|
||||
const cp_, const consumed = d.next(c);
|
||||
assert(consumed);
|
||||
if (cp_) |cp| {
|
||||
std.mem.doNotOptimizeAway(symbols_table.get(cp));
|
||||
std.mem.doNotOptimizeAway(symbols.table.get(cp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ fn step(ptr: *anyopaque) Benchmark.Error!void {
|
||||
|
||||
var p: terminalpkg.Parser = .init();
|
||||
|
||||
var buf: [4096]u8 align(std.atomic.cache_line) = undefined;
|
||||
var buf: [4096]u8 = undefined;
|
||||
while (true) {
|
||||
const n = r.read(&buf) catch |err| {
|
||||
log.warn("error reading data file err={}", .{err});
|
||||
|
@@ -115,7 +115,7 @@ fn step(ptr: *anyopaque) Benchmark.Error!void {
|
||||
const f = self.data_f orelse return;
|
||||
var r = std.io.bufferedReader(f.reader());
|
||||
|
||||
var buf: [4096]u8 align(std.atomic.cache_line) = undefined;
|
||||
var buf: [4096]u8 = undefined;
|
||||
while (true) {
|
||||
const n = r.read(&buf) catch |err| {
|
||||
log.warn("error reading data file err={}", .{err});
|
||||
|
@@ -5,13 +5,12 @@ const Config = @This();
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const ApprtRuntime = @import("../apprt/runtime.zig").Runtime;
|
||||
const FontBackend = @import("../font/backend.zig").Backend;
|
||||
const RendererBackend = @import("../renderer/backend.zig").Backend;
|
||||
const TerminalBuildOptions = @import("../terminal/build_options.zig").Options;
|
||||
const XCFrameworkTarget = @import("xcframework.zig").Target;
|
||||
const apprt = @import("../apprt.zig");
|
||||
const font = @import("../font/main.zig");
|
||||
const rendererpkg = @import("../renderer.zig");
|
||||
const Command = @import("../Command.zig");
|
||||
const XCFramework = @import("GhosttyXCFramework.zig");
|
||||
const WasmTarget = @import("../os/wasm/target.zig").Target;
|
||||
const expandPath = @import("../os/path.zig").expand;
|
||||
|
||||
const gtk = @import("gtk.zig");
|
||||
const GitVersion = @import("GitVersion.zig");
|
||||
@@ -21,24 +20,23 @@ const GitVersion = @import("GitVersion.zig");
|
||||
/// TODO: When Zig 0.14 is released, derive this from build.zig.zon directly.
|
||||
/// Until then this MUST match build.zig.zon and should always be the
|
||||
/// _next_ version to release.
|
||||
const app_version: std.SemanticVersion = .{ .major = 1, .minor = 2, .patch = 1 };
|
||||
const app_version: std.SemanticVersion = .{ .major = 1, .minor = 2, .patch = 0 };
|
||||
|
||||
/// Standard build configuration options.
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
target: std.Build.ResolvedTarget,
|
||||
xcframework_target: XCFrameworkTarget = .universal,
|
||||
xcframework_target: XCFramework.Target = .universal,
|
||||
wasm_target: WasmTarget,
|
||||
|
||||
/// Comptime interfaces
|
||||
app_runtime: ApprtRuntime = .none,
|
||||
renderer: RendererBackend = .opengl,
|
||||
font_backend: FontBackend = .freetype,
|
||||
app_runtime: apprt.Runtime = .none,
|
||||
renderer: rendererpkg.Impl = .opengl,
|
||||
font_backend: font.Backend = .freetype,
|
||||
|
||||
/// Feature flags
|
||||
x11: bool = false,
|
||||
wayland: bool = false,
|
||||
sentry: bool = true,
|
||||
simd: bool = true,
|
||||
i18n: bool = true,
|
||||
wasm_shared: bool = true,
|
||||
|
||||
@@ -121,7 +119,7 @@ pub fn init(b: *std.Build) !Config {
|
||||
//---------------------------------------------------------------
|
||||
// Target-specific properties
|
||||
config.xcframework_target = b.option(
|
||||
XCFrameworkTarget,
|
||||
XCFramework.Target,
|
||||
"xcframework-target",
|
||||
"The target for the xcframework.",
|
||||
) orelse .universal;
|
||||
@@ -129,22 +127,22 @@ pub fn init(b: *std.Build) !Config {
|
||||
//---------------------------------------------------------------
|
||||
// Comptime Interfaces
|
||||
config.font_backend = b.option(
|
||||
FontBackend,
|
||||
font.Backend,
|
||||
"font-backend",
|
||||
"The font backend to use for discovery and rasterization.",
|
||||
) orelse FontBackend.default(target.result, wasm_target);
|
||||
) orelse font.Backend.default(target.result, wasm_target);
|
||||
|
||||
config.app_runtime = b.option(
|
||||
ApprtRuntime,
|
||||
apprt.Runtime,
|
||||
"app-runtime",
|
||||
"The app runtime to use. Not all values supported on all platforms.",
|
||||
) orelse ApprtRuntime.default(target.result);
|
||||
) orelse apprt.Runtime.default(target.result);
|
||||
|
||||
config.renderer = b.option(
|
||||
RendererBackend,
|
||||
rendererpkg.Impl,
|
||||
"renderer",
|
||||
"The app runtime to use. Not all values supported on all platforms.",
|
||||
) orelse RendererBackend.default(target.result, wasm_target);
|
||||
) orelse rendererpkg.Impl.default(target.result, wasm_target);
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Feature Flags
|
||||
@@ -175,12 +173,6 @@ pub fn init(b: *std.Build) !Config {
|
||||
}
|
||||
};
|
||||
|
||||
config.simd = b.option(
|
||||
bool,
|
||||
"simd",
|
||||
"Build with SIMD-accelerated code paths. Results in significant performance improvements.",
|
||||
) orelse true;
|
||||
|
||||
config.wayland = b.option(
|
||||
bool,
|
||||
"gtk-wayland",
|
||||
@@ -347,7 +339,7 @@ pub fn init(b: *std.Build) !Config {
|
||||
if (system_package) break :emit_docs true;
|
||||
|
||||
// We only default to true if we can find pandoc.
|
||||
const path = expandPath(b.allocator, "pandoc") catch
|
||||
const path = Command.expandPath(b.allocator, "pandoc") catch
|
||||
break :emit_docs false;
|
||||
defer if (path) |p| b.allocator.free(p);
|
||||
break :emit_docs path != null;
|
||||
@@ -461,11 +453,10 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void {
|
||||
step.addOption(bool, "x11", self.x11);
|
||||
step.addOption(bool, "wayland", self.wayland);
|
||||
step.addOption(bool, "sentry", self.sentry);
|
||||
step.addOption(bool, "simd", self.simd);
|
||||
step.addOption(bool, "i18n", self.i18n);
|
||||
step.addOption(ApprtRuntime, "app_runtime", self.app_runtime);
|
||||
step.addOption(FontBackend, "font_backend", self.font_backend);
|
||||
step.addOption(RendererBackend, "renderer", self.renderer);
|
||||
step.addOption(apprt.Runtime, "app_runtime", self.app_runtime);
|
||||
step.addOption(font.Backend, "font_backend", self.font_backend);
|
||||
step.addOption(rendererpkg.Impl, "renderer", self.renderer);
|
||||
step.addOption(ExeEntrypoint, "exe_entrypoint", self.exe_entrypoint);
|
||||
step.addOption(WasmTarget, "wasm_target", self.wasm_target);
|
||||
step.addOption(bool, "wasm_shared", self.wasm_shared);
|
||||
@@ -491,24 +482,6 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void {
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the build options for the terminal module. This assumes a
|
||||
/// Ghostty executable being built. Callers should modify this as needed.
|
||||
pub fn terminalOptions(self: *const Config) TerminalBuildOptions {
|
||||
return .{
|
||||
.artifact = .ghostty,
|
||||
.simd = self.simd,
|
||||
.oniguruma = true,
|
||||
.c_abi = false,
|
||||
.slow_runtime_safety = switch (self.optimize) {
|
||||
.Debug => true,
|
||||
.ReleaseSafe,
|
||||
.ReleaseSmall,
|
||||
.ReleaseFast,
|
||||
=> false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns a baseline CPU target retaining all the other CPU configs.
|
||||
pub fn baselineTarget(self: *const Config) std.Build.ResolvedTarget {
|
||||
// Set our cpu model as baseline. There may need to be other modifications
|
||||
@@ -538,9 +511,9 @@ pub fn fromOptions() Config {
|
||||
|
||||
.version = options.app_version,
|
||||
.flatpak = options.flatpak,
|
||||
.app_runtime = std.meta.stringToEnum(ApprtRuntime, @tagName(options.app_runtime)).?,
|
||||
.font_backend = std.meta.stringToEnum(FontBackend, @tagName(options.font_backend)).?,
|
||||
.renderer = std.meta.stringToEnum(RendererBackend, @tagName(options.renderer)).?,
|
||||
.app_runtime = std.meta.stringToEnum(apprt.Runtime, @tagName(options.app_runtime)).?,
|
||||
.font_backend = std.meta.stringToEnum(font.Backend, @tagName(options.font_backend)).?,
|
||||
.renderer = std.meta.stringToEnum(rendererpkg.Impl, @tagName(options.renderer)).?,
|
||||
.snap = options.snap,
|
||||
.exe_entrypoint = std.meta.stringToEnum(ExeEntrypoint, @tagName(options.exe_entrypoint)).?,
|
||||
.wasm_target = std.meta.stringToEnum(WasmTarget, @tagName(options.wasm_target)).?,
|
||||
|
@@ -3,7 +3,6 @@ const GhosttyDist = @This();
|
||||
const std = @import("std");
|
||||
const Config = @import("Config.zig");
|
||||
const SharedDeps = @import("SharedDeps.zig");
|
||||
const GhosttyFrameData = @import("GhosttyFrameData.zig");
|
||||
|
||||
/// The final source tarball.
|
||||
archive: std.Build.LazyPath,
|
||||
@@ -26,10 +25,6 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
||||
try resources.append(alloc, gtk.resources_c);
|
||||
try resources.append(alloc, gtk.resources_h);
|
||||
}
|
||||
{
|
||||
const framedata = GhosttyFrameData.distResources(b);
|
||||
try resources.append(alloc, framedata.framedata);
|
||||
}
|
||||
|
||||
// git archive to create the final tarball. "git archive" is the
|
||||
// easiest way I can find to create a tarball that ignores stuff
|
||||
|
@@ -5,25 +5,32 @@ const GhosttyFrameData = @This();
|
||||
const std = @import("std");
|
||||
const Config = @import("Config.zig");
|
||||
const SharedDeps = @import("SharedDeps.zig");
|
||||
const DistResource = @import("GhosttyDist.zig").Resource;
|
||||
|
||||
/// The exe.
|
||||
exe: *std.Build.Step.Compile,
|
||||
|
||||
/// The output path for the compressed framedata zig file
|
||||
output: std.Build.LazyPath,
|
||||
|
||||
pub fn init(b: *std.Build) !GhosttyFrameData {
|
||||
const dist = distResources(b);
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "framegen",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/build/framegen/main.zig"),
|
||||
.target = b.graph.host,
|
||||
.strip = false,
|
||||
.omit_frame_pointer = false,
|
||||
.unwind_tables = .sync,
|
||||
}),
|
||||
});
|
||||
|
||||
// Generate the Zig source file that embeds the compressed data
|
||||
const wf = b.addWriteFiles();
|
||||
_ = wf.addCopyFile(dist.framedata.path(b), "framedata.compressed");
|
||||
const zig_file = wf.add("framedata.zig",
|
||||
\\//! This file is auto-generated. Do not edit.
|
||||
\\
|
||||
\\pub const compressed = @embedFile("framedata.compressed");
|
||||
\\
|
||||
);
|
||||
const run = b.addRunArtifact(exe);
|
||||
|
||||
return .{ .output = zig_file };
|
||||
_ = run.addOutputFileArg("framedata.compressed");
|
||||
return .{
|
||||
.exe = exe,
|
||||
.output = run.captureStdOut(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Add the "framedata" import.
|
||||
@@ -33,43 +40,3 @@ pub fn addImport(self: *const GhosttyFrameData, step: *std.Build.Step.Compile) v
|
||||
.root_source_file = self.output,
|
||||
});
|
||||
}
|
||||
|
||||
/// Creates the framedata resources that can be prebuilt for our dist build.
|
||||
pub fn distResources(b: *std.Build) struct {
|
||||
framedata: DistResource,
|
||||
} {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "framegen",
|
||||
.target = b.graph.host,
|
||||
});
|
||||
exe.addCSourceFile(.{
|
||||
.file = b.path("src/build/framegen/main.c"),
|
||||
.flags = &.{},
|
||||
});
|
||||
exe.linkLibC();
|
||||
|
||||
if (b.systemIntegrationOption("zlib", .{})) {
|
||||
exe.linkSystemLibrary2("zlib", .{
|
||||
.preferred_link_mode = .dynamic,
|
||||
.search_strategy = .mode_first,
|
||||
});
|
||||
} else {
|
||||
if (b.lazyDependency("zlib", .{
|
||||
.target = b.graph.host,
|
||||
.optimize = .ReleaseFast,
|
||||
})) |zlib_dep| {
|
||||
exe.linkLibrary(zlib_dep.artifact("z"));
|
||||
}
|
||||
}
|
||||
|
||||
const run = b.addRunArtifact(exe);
|
||||
run.addDirectoryArg(b.path("src/build/framegen/frames"));
|
||||
const compressed_file = run.addOutputFileArg("framedata.compressed");
|
||||
|
||||
return .{
|
||||
.framedata = .{
|
||||
.dist = "src/build/framegen/framedata.compressed",
|
||||
.generated = compressed_file,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Config = @import("Config.zig");
|
||||
const gresource = @import("../apprt/gtk/build/gresource.zig");
|
||||
const locales = @import("../os/i18n_locales.zig").locales;
|
||||
const internal_os = @import("../os/main.zig");
|
||||
|
||||
const domain = "com.mitchellh.ghostty";
|
||||
|
||||
@@ -21,7 +21,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||
defer steps.deinit();
|
||||
|
||||
inline for (locales) |locale| {
|
||||
inline for (internal_os.i18n.locales) |locale| {
|
||||
// There is no encoding suffix in the LC_MESSAGES path on FreeBSD,
|
||||
// so we need to remove it from `locale` to have a correct destination string.
|
||||
// (/usr/local/share/locale/en_AU/LC_MESSAGES)
|
||||
@@ -155,7 +155,7 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step {
|
||||
"po/" ++ domain ++ ".pot",
|
||||
);
|
||||
|
||||
inline for (locales) |locale| {
|
||||
inline for (internal_os.i18n.locales) |locale| {
|
||||
const msgmerge = b.addSystemCommand(&.{ "msgmerge", "--quiet", "--no-fuzzy-matching" });
|
||||
msgmerge.addFileArg(b.path("po/" ++ locale ++ ".po"));
|
||||
msgmerge.addFileArg(xgettext.captureStdOut());
|
||||
|
@@ -1,88 +0,0 @@
|
||||
const GhosttyLibVt = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const RunStep = std.Build.Step.Run;
|
||||
const Config = @import("Config.zig");
|
||||
const GhosttyZig = @import("GhosttyZig.zig");
|
||||
const SharedDeps = @import("SharedDeps.zig");
|
||||
const LibtoolStep = @import("LibtoolStep.zig");
|
||||
const LipoStep = @import("LipoStep.zig");
|
||||
|
||||
/// The step that generates the file.
|
||||
step: *std.Build.Step,
|
||||
|
||||
/// The artifact result
|
||||
artifact: *std.Build.Step.InstallArtifact,
|
||||
|
||||
/// The final library file
|
||||
output: std.Build.LazyPath,
|
||||
dsym: ?std.Build.LazyPath,
|
||||
pkg_config: std.Build.LazyPath,
|
||||
|
||||
pub fn initShared(
|
||||
b: *std.Build,
|
||||
zig: *const GhosttyZig,
|
||||
) !GhosttyLibVt {
|
||||
const target = zig.vt.resolved_target.?;
|
||||
const lib = b.addSharedLibrary(.{
|
||||
.name = "ghostty-vt",
|
||||
.root_module = zig.vt_c,
|
||||
.version = std.SemanticVersion{ .major = 0, .minor = 1, .patch = 0 },
|
||||
});
|
||||
lib.installHeader(
|
||||
b.path("include/ghostty/vt.h"),
|
||||
"ghostty/vt.h",
|
||||
);
|
||||
|
||||
// Get our debug symbols
|
||||
const dsymutil: ?std.Build.LazyPath = dsymutil: {
|
||||
if (!target.result.os.tag.isDarwin()) {
|
||||
break :dsymutil null;
|
||||
}
|
||||
|
||||
const dsymutil = RunStep.create(b, "dsymutil");
|
||||
dsymutil.addArgs(&.{"dsymutil"});
|
||||
dsymutil.addFileArg(lib.getEmittedBin());
|
||||
dsymutil.addArgs(&.{"-o"});
|
||||
const output = dsymutil.addOutputFileArg("libghostty-vt.dSYM");
|
||||
break :dsymutil output;
|
||||
};
|
||||
|
||||
// pkg-config
|
||||
const pc: std.Build.LazyPath = pc: {
|
||||
const wf = b.addWriteFiles();
|
||||
break :pc wf.add("libghostty-vt.pc", b.fmt(
|
||||
\\prefix={s}
|
||||
\\includedir=${{prefix}}/include
|
||||
\\libdir=${{prefix}}/lib
|
||||
\\
|
||||
\\Name: libghostty-vt
|
||||
\\URL: https://github.com/ghostty-org/ghostty
|
||||
\\Description: Ghostty VT library
|
||||
\\Version: 0.1.0
|
||||
\\Cflags: -I${{includedir}}
|
||||
\\Libs: -L${{libdir}} -lghostty-vt
|
||||
, .{b.install_prefix}));
|
||||
};
|
||||
|
||||
return .{
|
||||
.step = &lib.step,
|
||||
.artifact = b.addInstallArtifact(lib, .{}),
|
||||
.output = lib.getEmittedBin(),
|
||||
.dsym = dsymutil,
|
||||
.pkg_config = pc,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn install(
|
||||
self: *const GhosttyLibVt,
|
||||
step: *std.Build.Step,
|
||||
) void {
|
||||
const b = step.owner;
|
||||
step.dependOn(&self.artifact.step);
|
||||
step.dependOn(&b.addInstallFileWithDir(
|
||||
self.pkg_config,
|
||||
.prefix,
|
||||
"share/pkgconfig/libghostty-vt.pc",
|
||||
).step);
|
||||
}
|
@@ -5,6 +5,9 @@ const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const buildpkg = @import("main.zig");
|
||||
const Config = @import("Config.zig");
|
||||
const config_vim = @import("../config/vim.zig");
|
||||
const config_sublime_syntax = @import("../config/sublime_syntax.zig");
|
||||
const terminfo = @import("../terminfo/main.zig");
|
||||
const RunStep = std.Build.Step.Run;
|
||||
|
||||
steps: []*std.Build.Step,
|
||||
@@ -13,19 +16,6 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||
errdefer steps.deinit();
|
||||
|
||||
// This is the exe used to generate some build data.
|
||||
const build_data_exe = b.addExecutable(.{
|
||||
.name = "ghostty-build-data",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main_build_data.zig"),
|
||||
.target = b.graph.host,
|
||||
.strip = false,
|
||||
.omit_frame_pointer = false,
|
||||
.unwind_tables = .sync,
|
||||
}),
|
||||
});
|
||||
build_data_exe.linkLibC();
|
||||
|
||||
// Terminfo
|
||||
terminfo: {
|
||||
const os_tag = cfg.target.result.os.tag;
|
||||
@@ -35,10 +25,13 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
"terminfo";
|
||||
|
||||
// Encode our terminfo
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+terminfo");
|
||||
const wf = b.addWriteFiles();
|
||||
const source = wf.addCopyFile(run.captureStdOut(), "ghostty.terminfo");
|
||||
var str = std.ArrayList(u8).init(b.allocator);
|
||||
defer str.deinit();
|
||||
try terminfo.ghostty.encode(str.writer());
|
||||
|
||||
// Write it
|
||||
var wf = b.addWriteFiles();
|
||||
const source = wf.add("ghostty.terminfo", str.items);
|
||||
|
||||
if (cfg.emit_terminfo) {
|
||||
const source_install = b.addInstallFile(
|
||||
@@ -137,10 +130,8 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
|
||||
// Fish shell completions
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+fish");
|
||||
const wf = b.addWriteFiles();
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "ghostty.fish");
|
||||
_ = wf.add("ghostty.fish", buildpkg.fish_completions);
|
||||
|
||||
const install_step = b.addInstallDirectory(.{
|
||||
.source_dir = wf.getDirectory(),
|
||||
@@ -152,10 +143,8 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
|
||||
// zsh shell completions
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+zsh");
|
||||
const wf = b.addWriteFiles();
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "_ghostty");
|
||||
_ = wf.add("_ghostty", buildpkg.zsh_completions);
|
||||
|
||||
const install_step = b.addInstallDirectory(.{
|
||||
.source_dir = wf.getDirectory(),
|
||||
@@ -167,10 +156,8 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
|
||||
// bash shell completions
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+bash");
|
||||
const wf = b.addWriteFiles();
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "ghostty.bash");
|
||||
_ = wf.add("ghostty.bash", buildpkg.bash_completions);
|
||||
|
||||
const install_step = b.addInstallDirectory(.{
|
||||
.source_dir = wf.getDirectory(),
|
||||
@@ -180,44 +167,39 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
try steps.append(&install_step.step);
|
||||
}
|
||||
|
||||
// Vim and Neovim plugin
|
||||
// Vim plugin
|
||||
{
|
||||
const wf = b.addWriteFiles();
|
||||
_ = wf.add("syntax/ghostty.vim", config_vim.syntax);
|
||||
_ = wf.add("ftdetect/ghostty.vim", config_vim.ftdetect);
|
||||
_ = wf.add("ftplugin/ghostty.vim", config_vim.ftplugin);
|
||||
_ = wf.add("compiler/ghostty.vim", config_vim.compiler);
|
||||
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+vim-syntax");
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "syntax/ghostty.vim");
|
||||
}
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+vim-ftdetect");
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "ftdetect/ghostty.vim");
|
||||
}
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+vim-ftplugin");
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "ftplugin/ghostty.vim");
|
||||
}
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+vim-compiler");
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "compiler/ghostty.vim");
|
||||
}
|
||||
|
||||
const vim_step = b.addInstallDirectory(.{
|
||||
const install_step = b.addInstallDirectory(.{
|
||||
.source_dir = wf.getDirectory(),
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/vim/vimfiles",
|
||||
});
|
||||
try steps.append(&vim_step.step);
|
||||
try steps.append(&install_step.step);
|
||||
}
|
||||
|
||||
const neovim_step = b.addInstallDirectory(.{
|
||||
// Neovim plugin
|
||||
// This is just a copy-paste of the Vim plugin, but using a Neovim subdir.
|
||||
// By default, Neovim doesn't look inside share/vim/vimfiles. Some distros
|
||||
// configure it to do that however. Fedora, does not as a counterexample.
|
||||
{
|
||||
const wf = b.addWriteFiles();
|
||||
_ = wf.add("syntax/ghostty.vim", config_vim.syntax);
|
||||
_ = wf.add("ftdetect/ghostty.vim", config_vim.ftdetect);
|
||||
_ = wf.add("ftplugin/ghostty.vim", config_vim.ftplugin);
|
||||
_ = wf.add("compiler/ghostty.vim", config_vim.compiler);
|
||||
|
||||
const install_step = b.addInstallDirectory(.{
|
||||
.source_dir = wf.getDirectory(),
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/nvim/site",
|
||||
});
|
||||
try steps.append(&neovim_step.step);
|
||||
try steps.append(&install_step.step);
|
||||
}
|
||||
|
||||
// Sublime syntax highlighting for bat cli tool
|
||||
@@ -227,10 +209,8 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
// the config file within the '~.config/bat' directory
|
||||
// (ex: --map-syntax "/Users/user/.config/ghostty/config:Ghostty Config").
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+sublime");
|
||||
const wf = b.addWriteFiles();
|
||||
_ = wf.addCopyFile(run.captureStdOut(), "ghostty.sublime-syntax");
|
||||
_ = wf.add("ghostty.sublime-syntax", config_sublime_syntax.syntax);
|
||||
|
||||
const install_step = b.addInstallDirectory(.{
|
||||
.source_dir = wf.getDirectory(),
|
||||
|
@@ -5,11 +5,12 @@ const Config = @import("Config.zig");
|
||||
const SharedDeps = @import("SharedDeps.zig");
|
||||
const GhosttyLib = @import("GhosttyLib.zig");
|
||||
const XCFrameworkStep = @import("XCFrameworkStep.zig");
|
||||
const Target = @import("xcframework.zig").Target;
|
||||
|
||||
xcframework: *XCFrameworkStep,
|
||||
target: Target,
|
||||
|
||||
pub const Target = enum { native, universal };
|
||||
|
||||
pub fn init(
|
||||
b: *std.Build,
|
||||
deps: *const SharedDeps,
|
||||
|
@@ -1,82 +0,0 @@
|
||||
//! GhosttyZig generates the Zig modules that Ghostty exports
|
||||
//! for downstream usage.
|
||||
const GhosttyZig = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const Config = @import("Config.zig");
|
||||
const SharedDeps = @import("SharedDeps.zig");
|
||||
const TerminalBuildOptions = @import("../terminal/build_options.zig").Options;
|
||||
|
||||
/// The `_c`-suffixed modules are built with the C ABI enabled.
|
||||
vt: *std.Build.Module,
|
||||
vt_c: *std.Build.Module,
|
||||
|
||||
pub fn init(
|
||||
b: *std.Build,
|
||||
cfg: *const Config,
|
||||
deps: *const SharedDeps,
|
||||
) !GhosttyZig {
|
||||
// Terminal module build options
|
||||
var vt_options = cfg.terminalOptions();
|
||||
vt_options.artifact = .lib;
|
||||
// We presently don't allow Oniguruma in our Zig module at all.
|
||||
// We should expose this as a build option in the future so we can
|
||||
// conditionally do this.
|
||||
vt_options.oniguruma = false;
|
||||
|
||||
return .{
|
||||
.vt = try initVt(
|
||||
"ghostty-vt",
|
||||
b,
|
||||
cfg,
|
||||
deps,
|
||||
vt_options,
|
||||
),
|
||||
|
||||
.vt_c = try initVt(
|
||||
"ghostty-vt-c",
|
||||
b,
|
||||
cfg,
|
||||
deps,
|
||||
options: {
|
||||
var dup = vt_options;
|
||||
dup.c_abi = true;
|
||||
break :options dup;
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn initVt(
|
||||
name: []const u8,
|
||||
b: *std.Build,
|
||||
cfg: *const Config,
|
||||
deps: *const SharedDeps,
|
||||
vt_options: TerminalBuildOptions,
|
||||
) !*std.Build.Module {
|
||||
// General build options
|
||||
const general_options = b.addOptions();
|
||||
try cfg.addOptions(general_options);
|
||||
|
||||
const vt = b.addModule(name, .{
|
||||
.root_source_file = b.path("src/lib_vt.zig"),
|
||||
.target = cfg.target,
|
||||
.optimize = cfg.optimize,
|
||||
|
||||
// SIMD require libc/libcpp (both) but otherwise we don't care.
|
||||
.link_libc = if (cfg.simd) true else null,
|
||||
.link_libcpp = if (cfg.simd) true else null,
|
||||
});
|
||||
vt.addOptions("build_options", general_options);
|
||||
vt_options.add(b, vt);
|
||||
|
||||
// We always need unicode tables
|
||||
deps.unicode_tables.addModuleImport(vt);
|
||||
|
||||
// If SIMD is enabled, add all our SIMD dependencies.
|
||||
if (cfg.simd) {
|
||||
try SharedDeps.addSimd(b, vt, null);
|
||||
}
|
||||
|
||||
return vt;
|
||||
}
|
@@ -31,14 +31,9 @@ pub fn init(b: *std.Build, cfg: *const Config) !HelpStrings {
|
||||
exe.root_module.addOptions("build_options", options);
|
||||
|
||||
const help_run = b.addRunArtifact(exe);
|
||||
|
||||
// Generated Zig files have to end with .zig
|
||||
const wf = b.addWriteFiles();
|
||||
const output = wf.addCopyFile(help_run.captureStdOut(), "helpgen.zig");
|
||||
|
||||
return .{
|
||||
.exe = exe,
|
||||
.output = output,
|
||||
.output = help_run.captureStdOut(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,6 @@
|
||||
const SharedDeps = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const Config = @import("Config.zig");
|
||||
const HelpStrings = @import("HelpStrings.zig");
|
||||
const MetallibStep = @import("MetallibStep.zig");
|
||||
@@ -17,26 +15,16 @@ help_strings: HelpStrings,
|
||||
metallib: ?*MetallibStep,
|
||||
unicode_tables: UnicodeTables,
|
||||
framedata: GhosttyFrameData,
|
||||
uucode_tables: std.Build.LazyPath,
|
||||
|
||||
/// Used to keep track of a list of file sources.
|
||||
pub const LazyPathList = std.ArrayList(std.Build.LazyPath);
|
||||
|
||||
pub fn init(b: *std.Build, cfg: *const Config) !SharedDeps {
|
||||
const uucode_tables = blk: {
|
||||
const uucode = b.dependency("uucode", .{
|
||||
.build_config_path = b.path("src/build/uucode_config.zig"),
|
||||
});
|
||||
|
||||
break :blk uucode.namedLazyPath("tables.zig");
|
||||
};
|
||||
|
||||
var result: SharedDeps = .{
|
||||
.config = cfg,
|
||||
.help_strings = try .init(b, cfg),
|
||||
.unicode_tables = try .init(b, uucode_tables),
|
||||
.unicode_tables = try .init(b),
|
||||
.framedata = try .init(b),
|
||||
.uucode_tables = uucode_tables,
|
||||
|
||||
// Setup by retarget
|
||||
.options = undefined,
|
||||
@@ -116,25 +104,9 @@ pub fn add(
|
||||
var static_libs = LazyPathList.init(b.allocator);
|
||||
errdefer static_libs.deinit();
|
||||
|
||||
// WARNING: This is a hack!
|
||||
// If we're cross-compiling to Darwin then we don't add any deps.
|
||||
// We don't support cross-compiling to Darwin but due to the way
|
||||
// lazy dependencies work with Zig, we call this function. So we just
|
||||
// bail. The build will fail but the build would've failed anyways.
|
||||
// And this lets other non-platform-specific targets like `lib-vt`
|
||||
// cross-compile properly.
|
||||
if (!builtin.target.os.tag.isDarwin() and
|
||||
self.config.target.result.os.tag.isDarwin())
|
||||
{
|
||||
return static_libs;
|
||||
}
|
||||
|
||||
// Every exe gets build options populated
|
||||
step.root_module.addOptions("build_options", self.options);
|
||||
|
||||
// Every exe needs the terminal options
|
||||
self.config.terminalOptions().add(b, step.root_module);
|
||||
|
||||
// Freetype
|
||||
_ = b.systemIntegrationOption("freetype", .{}); // Shows it in help
|
||||
if (self.config.font_backend.hasFreetype()) {
|
||||
@@ -285,7 +257,7 @@ pub fn add(
|
||||
spirv_cross_dep.module("spirv_cross"),
|
||||
);
|
||||
if (b.systemIntegrationOption("spirv-cross", .{})) {
|
||||
step.linkSystemLibrary2("spirv-cross-c-shared", dynamic_link_opts);
|
||||
step.linkSystemLibrary2("spirv-cross", dynamic_link_opts);
|
||||
} else {
|
||||
step.linkLibrary(spirv_cross_dep.artifact("spirv_cross"));
|
||||
try static_libs.append(
|
||||
@@ -294,6 +266,21 @@ pub fn add(
|
||||
}
|
||||
}
|
||||
|
||||
// Simdutf
|
||||
if (b.systemIntegrationOption("simdutf", .{})) {
|
||||
step.linkSystemLibrary2("simdutf", dynamic_link_opts);
|
||||
} else {
|
||||
if (b.lazyDependency("simdutf", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |simdutf_dep| {
|
||||
step.linkLibrary(simdutf_dep.artifact("simdutf"));
|
||||
try static_libs.append(
|
||||
simdutf_dep.artifact("simdutf").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Sentry
|
||||
if (self.config.sentry) {
|
||||
if (b.lazyDependency("sentry", .{
|
||||
@@ -322,13 +309,6 @@ pub fn add(
|
||||
}
|
||||
}
|
||||
|
||||
// Simd
|
||||
if (self.config.simd) try addSimd(
|
||||
b,
|
||||
step.root_module,
|
||||
&static_libs,
|
||||
);
|
||||
|
||||
// Wasm we do manually since it is such a different build.
|
||||
if (step.rootModuleTarget().cpu.arch == .wasm32) {
|
||||
if (b.lazyDependency("zig_js", .{
|
||||
@@ -363,8 +343,35 @@ pub fn add(
|
||||
step.addIncludePath(b.path("src/apprt/gtk"));
|
||||
}
|
||||
|
||||
// libcpp is required for various dependencies
|
||||
// C++ files
|
||||
step.linkLibCpp();
|
||||
step.addIncludePath(b.path("src"));
|
||||
{
|
||||
// From hwy/detect_targets.h
|
||||
const HWY_AVX3_SPR: c_int = 1 << 4;
|
||||
const HWY_AVX3_ZEN4: c_int = 1 << 6;
|
||||
const HWY_AVX3_DL: c_int = 1 << 7;
|
||||
const HWY_AVX3: c_int = 1 << 8;
|
||||
|
||||
// Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414
|
||||
// To workaround this we just disable AVX512 support completely.
|
||||
// The performance difference between AVX2 and AVX512 is not
|
||||
// significant for our use case and AVX512 is very rare on consumer
|
||||
// hardware anyways.
|
||||
const HWY_DISABLED_TARGETS: c_int = HWY_AVX3_SPR | HWY_AVX3_ZEN4 | HWY_AVX3_DL | HWY_AVX3;
|
||||
|
||||
step.addCSourceFiles(.{
|
||||
.files = &.{
|
||||
"src/simd/base64.cpp",
|
||||
"src/simd/codepoint_width.cpp",
|
||||
"src/simd/index_of.cpp",
|
||||
"src/simd/vt.cpp",
|
||||
},
|
||||
.flags = if (step.rootModuleTarget().cpu.arch == .x86_64) &.{
|
||||
b.fmt("-DHWY_DISABLED_TARGETS={}", .{HWY_DISABLED_TARGETS}),
|
||||
} else &.{},
|
||||
});
|
||||
}
|
||||
|
||||
// We always require the system SDK so that our system headers are available.
|
||||
// This makes things like `os/log.h` available for cross-compiling.
|
||||
@@ -403,13 +410,11 @@ pub fn add(
|
||||
})) |dep| {
|
||||
step.root_module.addImport("z2d", dep.module("z2d"));
|
||||
}
|
||||
if (b.lazyDependency("uucode", .{
|
||||
if (b.lazyDependency("ziglyph", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.tables_path = self.uucode_tables,
|
||||
.build_config_path = b.path("src/build/uucode_config.zig"),
|
||||
})) |dep| {
|
||||
step.root_module.addImport("uucode", dep.module("uucode"));
|
||||
step.root_module.addImport("ziglyph", dep.module("ziglyph"));
|
||||
}
|
||||
if (b.lazyDependency("zf", .{
|
||||
.target = target,
|
||||
@@ -476,43 +481,59 @@ pub fn add(
|
||||
try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin());
|
||||
}
|
||||
|
||||
// Highway
|
||||
if (b.lazyDependency("highway", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |highway_dep| {
|
||||
step.linkLibrary(highway_dep.artifact("highway"));
|
||||
try static_libs.append(highway_dep.artifact("highway").getEmittedBin());
|
||||
}
|
||||
|
||||
// utfcpp - This is used as a dependency on our hand-written C++ code
|
||||
if (b.lazyDependency("utfcpp", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |utfcpp_dep| {
|
||||
step.linkLibrary(utfcpp_dep.artifact("utfcpp"));
|
||||
try static_libs.append(utfcpp_dep.artifact("utfcpp").getEmittedBin());
|
||||
}
|
||||
|
||||
// Fonts
|
||||
{
|
||||
// JetBrains Mono
|
||||
if (b.lazyDependency("jetbrains_mono", .{})) |jb_mono| {
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_regular",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Regular.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_bold",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Bold.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_italic",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Italic.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_bold_italic",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-BoldItalic.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_variable",
|
||||
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono[wght].ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_variable_italic",
|
||||
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono-Italic[wght].ttf") },
|
||||
);
|
||||
}
|
||||
const jb_mono = b.dependency("jetbrains_mono", .{});
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_regular",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Regular.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_bold",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Bold.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_italic",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Italic.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_bold_italic",
|
||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-BoldItalic.ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_variable",
|
||||
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono[wght].ttf") },
|
||||
);
|
||||
step.root_module.addAnonymousImport(
|
||||
"jetbrains_mono_variable_italic",
|
||||
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono-Italic[wght].ttf") },
|
||||
);
|
||||
|
||||
// Symbols-only nerd font
|
||||
if (b.lazyDependency("nerd_fonts_symbols_only", .{})) |nf_symbols| {
|
||||
step.root_module.addAnonymousImport(
|
||||
"nerd_fonts_symbols_only",
|
||||
.{ .root_source_file = nf_symbols.path("SymbolsNerdFont-Regular.ttf") },
|
||||
);
|
||||
}
|
||||
const nf_symbols = b.dependency("nerd_fonts_symbols_only", .{});
|
||||
step.root_module.addAnonymousImport(
|
||||
"nerd_fonts_symbols_only",
|
||||
.{ .root_source_file = nf_symbols.path("SymbolsNerdFont-Regular.ttf") },
|
||||
);
|
||||
}
|
||||
|
||||
// If we're building an exe then we have additional dependencies.
|
||||
@@ -594,20 +615,17 @@ fn addGtkNg(
|
||||
"plasma_wayland_protocols",
|
||||
.{},
|
||||
);
|
||||
const zig_wayland_import_ = b.lazyImport(
|
||||
@import("../../build.zig"),
|
||||
"zig_wayland",
|
||||
);
|
||||
const zig_wayland_dep_ = b.lazyDependency("zig_wayland", .{});
|
||||
|
||||
// Unwrap or return, there are no more dependencies below.
|
||||
const wayland_dep = wayland_dep_ orelse break :wayland;
|
||||
const wayland_protocols_dep = wayland_protocols_dep_ orelse break :wayland;
|
||||
const plasma_wayland_protocols_dep = plasma_wayland_protocols_dep_ orelse break :wayland;
|
||||
const zig_wayland_import = zig_wayland_import_ orelse break :wayland;
|
||||
const zig_wayland_dep = zig_wayland_dep_ orelse break :wayland;
|
||||
|
||||
const Scanner = zig_wayland_import.Scanner;
|
||||
// Note that zig_wayland cannot be lazy because lazy dependencies
|
||||
// can't be imported since they don't exist and imports are
|
||||
// resolved at compile time of the build.
|
||||
const zig_wayland_dep = b.dependency("zig_wayland", .{});
|
||||
const Scanner = @import("zig_wayland").Scanner;
|
||||
const scanner = Scanner.create(zig_wayland_dep.builder, .{
|
||||
.wayland_xml = wayland_dep.path("protocol/wayland.xml"),
|
||||
.wayland_protocols = wayland_protocols_dep.path(""),
|
||||
@@ -677,79 +695,6 @@ fn addGtkNg(
|
||||
}
|
||||
}
|
||||
|
||||
/// Add only the dependencies required for `Config.simd` enbled. This also
|
||||
/// adds all the simd source files for compilation.
|
||||
pub fn addSimd(
|
||||
b: *std.Build,
|
||||
m: *std.Build.Module,
|
||||
static_libs: ?*LazyPathList,
|
||||
) !void {
|
||||
const target = m.resolved_target.?;
|
||||
const optimize = m.optimize.?;
|
||||
|
||||
// Simdutf
|
||||
if (b.systemIntegrationOption("simdutf", .{})) {
|
||||
m.linkSystemLibrary("simdutf", dynamic_link_opts);
|
||||
} else {
|
||||
if (b.lazyDependency("simdutf", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |simdutf_dep| {
|
||||
m.linkLibrary(simdutf_dep.artifact("simdutf"));
|
||||
if (static_libs) |v| try v.append(
|
||||
simdutf_dep.artifact("simdutf").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Highway
|
||||
if (b.lazyDependency("highway", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |highway_dep| {
|
||||
m.linkLibrary(highway_dep.artifact("highway"));
|
||||
if (static_libs) |v| try v.append(highway_dep.artifact("highway").getEmittedBin());
|
||||
}
|
||||
|
||||
// utfcpp - This is used as a dependency on our hand-written C++ code
|
||||
if (b.lazyDependency("utfcpp", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |utfcpp_dep| {
|
||||
m.linkLibrary(utfcpp_dep.artifact("utfcpp"));
|
||||
if (static_libs) |v| try v.append(utfcpp_dep.artifact("utfcpp").getEmittedBin());
|
||||
}
|
||||
|
||||
// SIMD C++ files
|
||||
m.addIncludePath(b.path("src"));
|
||||
{
|
||||
// From hwy/detect_targets.h
|
||||
const HWY_AVX3_SPR: c_int = 1 << 4;
|
||||
const HWY_AVX3_ZEN4: c_int = 1 << 6;
|
||||
const HWY_AVX3_DL: c_int = 1 << 7;
|
||||
const HWY_AVX3: c_int = 1 << 8;
|
||||
|
||||
// Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414
|
||||
// To workaround this we just disable AVX512 support completely.
|
||||
// The performance difference between AVX2 and AVX512 is not
|
||||
// significant for our use case and AVX512 is very rare on consumer
|
||||
// hardware anyways.
|
||||
const HWY_DISABLED_TARGETS: c_int = HWY_AVX3_SPR | HWY_AVX3_ZEN4 | HWY_AVX3_DL | HWY_AVX3;
|
||||
|
||||
m.addCSourceFiles(.{
|
||||
.files = &.{
|
||||
"src/simd/base64.cpp",
|
||||
"src/simd/codepoint_width.cpp",
|
||||
"src/simd/index_of.cpp",
|
||||
"src/simd/vt.cpp",
|
||||
},
|
||||
.flags = if (target.result.cpu.arch == .x86_64) &.{
|
||||
b.fmt("-DHWY_DISABLED_TARGETS={}", .{HWY_DISABLED_TARGETS}),
|
||||
} else &.{},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the resources that can be prebuilt for our dist build.
|
||||
pub fn gtkNgDistResources(
|
||||
b: *std.Build,
|
||||
|
@@ -11,11 +11,11 @@ symbols_exe: *std.Build.Step.Compile,
|
||||
props_output: std.Build.LazyPath,
|
||||
symbols_output: std.Build.LazyPath,
|
||||
|
||||
pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables {
|
||||
pub fn init(b: *std.Build) !UnicodeTables {
|
||||
const props_exe = b.addExecutable(.{
|
||||
.name = "props-unigen",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/unicode/props_uucode.zig"),
|
||||
.root_source_file = b.path("src/unicode/props.zig"),
|
||||
.target = b.graph.host,
|
||||
.strip = false,
|
||||
.omit_frame_pointer = false,
|
||||
@@ -26,7 +26,7 @@ pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables {
|
||||
const symbols_exe = b.addExecutable(.{
|
||||
.name = "symbols-unigen",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/unicode/symbols_uucode.zig"),
|
||||
.root_source_file = b.path("src/unicode/symbols.zig"),
|
||||
.target = b.graph.host,
|
||||
.strip = false,
|
||||
.omit_frame_pointer = false,
|
||||
@@ -34,48 +34,36 @@ pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables {
|
||||
}),
|
||||
});
|
||||
|
||||
if (b.lazyDependency("uucode", .{
|
||||
if (b.lazyDependency("ziglyph", .{
|
||||
.target = b.graph.host,
|
||||
.tables_path = uucode_tables,
|
||||
.build_config_path = b.path("src/build/uucode_config.zig"),
|
||||
})) |dep| {
|
||||
})) |ziglyph_dep| {
|
||||
inline for (&.{ props_exe, symbols_exe }) |exe| {
|
||||
exe.root_module.addImport("uucode", dep.module("uucode"));
|
||||
exe.root_module.addImport(
|
||||
"ziglyph",
|
||||
ziglyph_dep.module("ziglyph"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const props_run = b.addRunArtifact(props_exe);
|
||||
const symbols_run = b.addRunArtifact(symbols_exe);
|
||||
|
||||
// Generated Zig files have to end with .zig
|
||||
const wf = b.addWriteFiles();
|
||||
const props_output = wf.addCopyFile(props_run.captureStdOut(), "props.zig");
|
||||
const symbols_output = wf.addCopyFile(symbols_run.captureStdOut(), "symbols.zig");
|
||||
|
||||
return .{
|
||||
.props_exe = props_exe,
|
||||
.symbols_exe = symbols_exe,
|
||||
.props_output = props_output,
|
||||
.symbols_output = symbols_output,
|
||||
.props_output = props_run.captureStdOut(),
|
||||
.symbols_output = symbols_run.captureStdOut(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Add the "unicode_tables" import.
|
||||
pub fn addImport(self: *const UnicodeTables, step: *std.Build.Step.Compile) void {
|
||||
self.props_output.addStepDependencies(&step.step);
|
||||
self.symbols_output.addStepDependencies(&step.step);
|
||||
self.addModuleImport(step.root_module);
|
||||
}
|
||||
|
||||
/// Add the "unicode_tables" import to a module.
|
||||
pub fn addModuleImport(
|
||||
self: *const UnicodeTables,
|
||||
module: *std.Build.Module,
|
||||
) void {
|
||||
module.addAnonymousImport("unicode_tables", .{
|
||||
step.root_module.addAnonymousImport("unicode_tables", .{
|
||||
.root_source_file = self.props_output,
|
||||
});
|
||||
module.addAnonymousImport("symbols_tables", .{
|
||||
self.symbols_output.addStepDependencies(&step.step);
|
||||
step.root_module.addAnonymousImport("symbols_tables", .{
|
||||
.root_source_file = self.symbols_output,
|
||||
});
|
||||
}
|
||||
|
@@ -1,33 +0,0 @@
|
||||
#--------------------------------------------------------------------
|
||||
# Generate documentation with Doxygen
|
||||
#--------------------------------------------------------------------
|
||||
FROM ubuntu:24.04 AS builder
|
||||
|
||||
# Build argument for noindex header
|
||||
ARG ADD_NOINDEX_HEADER=false
|
||||
RUN apt-get update && apt-get install -y \
|
||||
doxygen \
|
||||
graphviz \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
WORKDIR /ghostty
|
||||
COPY include/ ./include/
|
||||
COPY Doxyfile ./
|
||||
RUN mkdir -p zig-out/share/ghostty/doc/libghostty
|
||||
RUN doxygen
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Host the static HTML
|
||||
#--------------------------------------------------------------------
|
||||
FROM nginx:alpine AS runtime
|
||||
|
||||
# Pass build arg to runtime stage
|
||||
ARG ADD_NOINDEX_HEADER=false
|
||||
ENV ADD_NOINDEX_HEADER=$ADD_NOINDEX_HEADER
|
||||
|
||||
# Copy documentation and entrypoint script
|
||||
COPY --from=builder /ghostty/zig-out/share/ghostty/doc/libghostty /usr/share/nginx/html
|
||||
COPY src/build/docker/lib-c-docs/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["/entrypoint.sh"]
|
@@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
if [ "$ADD_NOINDEX_HEADER" = "true" ]; then
|
||||
cat > /etc/nginx/conf.d/noindex.conf << 'EOF'
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
# Remove default server config
|
||||
rm -f /etc/nginx/conf.d/default.conf
|
||||
fi
|
||||
exec nginx -g "daemon off;"
|
@@ -1,4 +1,3 @@
|
||||
//! Fish completions.
|
||||
const std = @import("std");
|
||||
|
||||
const Config = @import("../config/Config.zig");
|
||||
@@ -6,23 +5,23 @@ const Action = @import("../cli.zig").ghostty.Action;
|
||||
|
||||
/// A fish completions configuration that contains all the available commands
|
||||
/// and options.
|
||||
pub const completions = comptimeGenerateCompletions();
|
||||
pub const completions = comptimeGenerateFishCompletions();
|
||||
|
||||
fn comptimeGenerateCompletions() []const u8 {
|
||||
fn comptimeGenerateFishCompletions() []const u8 {
|
||||
comptime {
|
||||
@setEvalBranchQuota(50000);
|
||||
var counter = std.io.countingWriter(std.io.null_writer);
|
||||
try writeCompletions(&counter.writer());
|
||||
try writeFishCompletions(&counter.writer());
|
||||
|
||||
var buf: [counter.bytes_written]u8 = undefined;
|
||||
var stream = std.io.fixedBufferStream(&buf);
|
||||
try writeCompletions(stream.writer());
|
||||
try writeFishCompletions(stream.writer());
|
||||
const final = buf;
|
||||
return final[0..stream.getWritten().len];
|
||||
}
|
||||
}
|
||||
|
||||
fn writeCompletions(writer: anytype) !void {
|
||||
fn writeFishCompletions(writer: anytype) !void {
|
||||
{
|
||||
try writer.writeAll("set -l commands \"");
|
||||
var count: usize = 0;
|
@@ -1,145 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#define SEPARATOR '\x01'
|
||||
#define CHUNK_SIZE 16384
|
||||
|
||||
static int filter_frames(const struct dirent *entry) {
|
||||
const char *name = entry->d_name;
|
||||
size_t len = strlen(name);
|
||||
return len > 4 && strcmp(name + len - 4, ".txt") == 0;
|
||||
}
|
||||
|
||||
static int compare_frames(const struct dirent **a, const struct dirent **b) {
|
||||
return strcmp((*a)->d_name, (*b)->d_name);
|
||||
}
|
||||
|
||||
static char *read_file(const char *path, size_t *out_size) {
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
char *buf = malloc(size);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(buf, 1, size, f) != (size_t)size) {
|
||||
fprintf(stderr, "Failed to read %s\n", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
*out_size = size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <frames_dir> <output_file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *frames_dir = argv[1];
|
||||
const char *output_file = argv[2];
|
||||
|
||||
struct dirent **namelist;
|
||||
int n = scandir(frames_dir, &namelist, filter_frames, compare_frames);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Failed to scan directory %s: %s\n", frames_dir, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
fprintf(stderr, "No frame files found in %s\n", frames_dir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t total_size = 0;
|
||||
char **frame_contents = calloc(n, sizeof(char*));
|
||||
size_t *frame_sizes = calloc(n, sizeof(size_t));
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
char path[4096];
|
||||
snprintf(path, sizeof(path), "%s/%s", frames_dir, namelist[i]->d_name);
|
||||
|
||||
frame_contents[i] = read_file(path, &frame_sizes[i]);
|
||||
if (!frame_contents[i]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
total_size += frame_sizes[i];
|
||||
if (i < n - 1) total_size++;
|
||||
}
|
||||
|
||||
char *joined = malloc(total_size);
|
||||
if (!joined) {
|
||||
fprintf(stderr, "Failed to allocate joined buffer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t offset = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
memcpy(joined + offset, frame_contents[i], frame_sizes[i]);
|
||||
offset += frame_sizes[i];
|
||||
if (i < n - 1) {
|
||||
joined[offset++] = SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
||||
uLongf compressed_size = compressBound(total_size);
|
||||
unsigned char *compressed = malloc(compressed_size);
|
||||
if (!compressed) {
|
||||
fprintf(stderr, "Failed to allocate compression buffer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
z_stream stream = {0};
|
||||
stream.next_in = (unsigned char*)joined;
|
||||
stream.avail_in = total_size;
|
||||
stream.next_out = compressed;
|
||||
stream.avail_out = compressed_size;
|
||||
|
||||
// Use -MAX_WBITS for raw DEFLATE (no zlib wrapper)
|
||||
int ret = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
|
||||
if (ret != Z_OK) {
|
||||
fprintf(stderr, "deflateInit2 failed: %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = deflate(&stream, Z_FINISH);
|
||||
if (ret != Z_STREAM_END) {
|
||||
fprintf(stderr, "deflate failed: %d\n", ret);
|
||||
deflateEnd(&stream);
|
||||
return 1;
|
||||
}
|
||||
|
||||
compressed_size = stream.total_out;
|
||||
deflateEnd(&stream);
|
||||
|
||||
FILE *out = fopen(output_file, "wb");
|
||||
if (!out) {
|
||||
fprintf(stderr, "Failed to create %s: %s\n", output_file, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fwrite(compressed, 1, compressed_size, out) != compressed_size) {
|
||||
fprintf(stderr, "Failed to write compressed data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
|
||||
return 0;
|
||||
}
|
271
src/build/framegen/main.zig
Normal file
271
src/build/framegen/main.zig
Normal file
@@ -0,0 +1,271 @@
|
||||
const std = @import("std");
|
||||
const fs = std.fs;
|
||||
|
||||
/// Generates a compressed file of all the ghostty frames
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
|
||||
var arg_iter = try std.process.argsWithAllocator(gpa.allocator());
|
||||
// Skip the exe name
|
||||
_ = arg_iter.skip();
|
||||
|
||||
const output_path = arg_iter.next() orelse return error.MissingOutputPath;
|
||||
|
||||
const out_dir_path = fs.path.dirname(output_path) orelse return error.InvalidOutputPath;
|
||||
const out_dir = try fs.cwd().openDir(out_dir_path, .{});
|
||||
|
||||
const compressed_file = try out_dir.createFile(fs.path.basename(output_path), .{});
|
||||
|
||||
// Join the frames with a null byte. We'll split on this later
|
||||
const all_frames = try std.mem.join(gpa.allocator(), "\x01", &frames);
|
||||
var fbs = std.io.fixedBufferStream(all_frames);
|
||||
|
||||
const reader = fbs.reader();
|
||||
try std.compress.flate.compress(reader, compressed_file.writer(), .{});
|
||||
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
|
||||
try stdout.print(
|
||||
\\//! This file is auto-generated. Do not edit.
|
||||
\\
|
||||
\\pub const compressed = @embedFile("{s}");
|
||||
, .{output_path});
|
||||
}
|
||||
|
||||
const frames = [_][]const u8{
|
||||
@embedFile("frames/frame_001.txt"),
|
||||
@embedFile("frames/frame_002.txt"),
|
||||
@embedFile("frames/frame_003.txt"),
|
||||
@embedFile("frames/frame_004.txt"),
|
||||
@embedFile("frames/frame_005.txt"),
|
||||
@embedFile("frames/frame_006.txt"),
|
||||
@embedFile("frames/frame_007.txt"),
|
||||
@embedFile("frames/frame_008.txt"),
|
||||
@embedFile("frames/frame_009.txt"),
|
||||
@embedFile("frames/frame_010.txt"),
|
||||
@embedFile("frames/frame_011.txt"),
|
||||
@embedFile("frames/frame_012.txt"),
|
||||
@embedFile("frames/frame_013.txt"),
|
||||
@embedFile("frames/frame_014.txt"),
|
||||
@embedFile("frames/frame_015.txt"),
|
||||
@embedFile("frames/frame_016.txt"),
|
||||
@embedFile("frames/frame_017.txt"),
|
||||
@embedFile("frames/frame_018.txt"),
|
||||
@embedFile("frames/frame_019.txt"),
|
||||
@embedFile("frames/frame_020.txt"),
|
||||
@embedFile("frames/frame_021.txt"),
|
||||
@embedFile("frames/frame_022.txt"),
|
||||
@embedFile("frames/frame_023.txt"),
|
||||
@embedFile("frames/frame_024.txt"),
|
||||
@embedFile("frames/frame_025.txt"),
|
||||
@embedFile("frames/frame_026.txt"),
|
||||
@embedFile("frames/frame_027.txt"),
|
||||
@embedFile("frames/frame_028.txt"),
|
||||
@embedFile("frames/frame_029.txt"),
|
||||
@embedFile("frames/frame_030.txt"),
|
||||
@embedFile("frames/frame_031.txt"),
|
||||
@embedFile("frames/frame_032.txt"),
|
||||
@embedFile("frames/frame_033.txt"),
|
||||
@embedFile("frames/frame_034.txt"),
|
||||
@embedFile("frames/frame_035.txt"),
|
||||
@embedFile("frames/frame_036.txt"),
|
||||
@embedFile("frames/frame_037.txt"),
|
||||
@embedFile("frames/frame_038.txt"),
|
||||
@embedFile("frames/frame_039.txt"),
|
||||
@embedFile("frames/frame_040.txt"),
|
||||
@embedFile("frames/frame_041.txt"),
|
||||
@embedFile("frames/frame_042.txt"),
|
||||
@embedFile("frames/frame_043.txt"),
|
||||
@embedFile("frames/frame_044.txt"),
|
||||
@embedFile("frames/frame_045.txt"),
|
||||
@embedFile("frames/frame_046.txt"),
|
||||
@embedFile("frames/frame_047.txt"),
|
||||
@embedFile("frames/frame_048.txt"),
|
||||
@embedFile("frames/frame_049.txt"),
|
||||
@embedFile("frames/frame_050.txt"),
|
||||
@embedFile("frames/frame_051.txt"),
|
||||
@embedFile("frames/frame_052.txt"),
|
||||
@embedFile("frames/frame_053.txt"),
|
||||
@embedFile("frames/frame_054.txt"),
|
||||
@embedFile("frames/frame_055.txt"),
|
||||
@embedFile("frames/frame_056.txt"),
|
||||
@embedFile("frames/frame_057.txt"),
|
||||
@embedFile("frames/frame_058.txt"),
|
||||
@embedFile("frames/frame_059.txt"),
|
||||
@embedFile("frames/frame_060.txt"),
|
||||
@embedFile("frames/frame_061.txt"),
|
||||
@embedFile("frames/frame_062.txt"),
|
||||
@embedFile("frames/frame_063.txt"),
|
||||
@embedFile("frames/frame_064.txt"),
|
||||
@embedFile("frames/frame_065.txt"),
|
||||
@embedFile("frames/frame_066.txt"),
|
||||
@embedFile("frames/frame_067.txt"),
|
||||
@embedFile("frames/frame_068.txt"),
|
||||
@embedFile("frames/frame_069.txt"),
|
||||
@embedFile("frames/frame_070.txt"),
|
||||
@embedFile("frames/frame_071.txt"),
|
||||
@embedFile("frames/frame_072.txt"),
|
||||
@embedFile("frames/frame_073.txt"),
|
||||
@embedFile("frames/frame_074.txt"),
|
||||
@embedFile("frames/frame_075.txt"),
|
||||
@embedFile("frames/frame_076.txt"),
|
||||
@embedFile("frames/frame_077.txt"),
|
||||
@embedFile("frames/frame_078.txt"),
|
||||
@embedFile("frames/frame_079.txt"),
|
||||
@embedFile("frames/frame_080.txt"),
|
||||
@embedFile("frames/frame_081.txt"),
|
||||
@embedFile("frames/frame_082.txt"),
|
||||
@embedFile("frames/frame_083.txt"),
|
||||
@embedFile("frames/frame_084.txt"),
|
||||
@embedFile("frames/frame_085.txt"),
|
||||
@embedFile("frames/frame_086.txt"),
|
||||
@embedFile("frames/frame_087.txt"),
|
||||
@embedFile("frames/frame_088.txt"),
|
||||
@embedFile("frames/frame_089.txt"),
|
||||
@embedFile("frames/frame_090.txt"),
|
||||
@embedFile("frames/frame_091.txt"),
|
||||
@embedFile("frames/frame_092.txt"),
|
||||
@embedFile("frames/frame_093.txt"),
|
||||
@embedFile("frames/frame_094.txt"),
|
||||
@embedFile("frames/frame_095.txt"),
|
||||
@embedFile("frames/frame_096.txt"),
|
||||
@embedFile("frames/frame_097.txt"),
|
||||
@embedFile("frames/frame_098.txt"),
|
||||
@embedFile("frames/frame_099.txt"),
|
||||
@embedFile("frames/frame_100.txt"),
|
||||
@embedFile("frames/frame_101.txt"),
|
||||
@embedFile("frames/frame_102.txt"),
|
||||
@embedFile("frames/frame_103.txt"),
|
||||
@embedFile("frames/frame_104.txt"),
|
||||
@embedFile("frames/frame_105.txt"),
|
||||
@embedFile("frames/frame_106.txt"),
|
||||
@embedFile("frames/frame_107.txt"),
|
||||
@embedFile("frames/frame_108.txt"),
|
||||
@embedFile("frames/frame_109.txt"),
|
||||
@embedFile("frames/frame_110.txt"),
|
||||
@embedFile("frames/frame_111.txt"),
|
||||
@embedFile("frames/frame_112.txt"),
|
||||
@embedFile("frames/frame_113.txt"),
|
||||
@embedFile("frames/frame_114.txt"),
|
||||
@embedFile("frames/frame_115.txt"),
|
||||
@embedFile("frames/frame_116.txt"),
|
||||
@embedFile("frames/frame_117.txt"),
|
||||
@embedFile("frames/frame_118.txt"),
|
||||
@embedFile("frames/frame_119.txt"),
|
||||
@embedFile("frames/frame_120.txt"),
|
||||
@embedFile("frames/frame_121.txt"),
|
||||
@embedFile("frames/frame_122.txt"),
|
||||
@embedFile("frames/frame_123.txt"),
|
||||
@embedFile("frames/frame_124.txt"),
|
||||
@embedFile("frames/frame_125.txt"),
|
||||
@embedFile("frames/frame_126.txt"),
|
||||
@embedFile("frames/frame_127.txt"),
|
||||
@embedFile("frames/frame_128.txt"),
|
||||
@embedFile("frames/frame_129.txt"),
|
||||
@embedFile("frames/frame_130.txt"),
|
||||
@embedFile("frames/frame_131.txt"),
|
||||
@embedFile("frames/frame_132.txt"),
|
||||
@embedFile("frames/frame_133.txt"),
|
||||
@embedFile("frames/frame_134.txt"),
|
||||
@embedFile("frames/frame_135.txt"),
|
||||
@embedFile("frames/frame_136.txt"),
|
||||
@embedFile("frames/frame_137.txt"),
|
||||
@embedFile("frames/frame_138.txt"),
|
||||
@embedFile("frames/frame_139.txt"),
|
||||
@embedFile("frames/frame_140.txt"),
|
||||
@embedFile("frames/frame_141.txt"),
|
||||
@embedFile("frames/frame_142.txt"),
|
||||
@embedFile("frames/frame_143.txt"),
|
||||
@embedFile("frames/frame_144.txt"),
|
||||
@embedFile("frames/frame_145.txt"),
|
||||
@embedFile("frames/frame_146.txt"),
|
||||
@embedFile("frames/frame_147.txt"),
|
||||
@embedFile("frames/frame_148.txt"),
|
||||
@embedFile("frames/frame_149.txt"),
|
||||
@embedFile("frames/frame_150.txt"),
|
||||
@embedFile("frames/frame_151.txt"),
|
||||
@embedFile("frames/frame_152.txt"),
|
||||
@embedFile("frames/frame_153.txt"),
|
||||
@embedFile("frames/frame_154.txt"),
|
||||
@embedFile("frames/frame_155.txt"),
|
||||
@embedFile("frames/frame_156.txt"),
|
||||
@embedFile("frames/frame_157.txt"),
|
||||
@embedFile("frames/frame_158.txt"),
|
||||
@embedFile("frames/frame_159.txt"),
|
||||
@embedFile("frames/frame_160.txt"),
|
||||
@embedFile("frames/frame_161.txt"),
|
||||
@embedFile("frames/frame_162.txt"),
|
||||
@embedFile("frames/frame_163.txt"),
|
||||
@embedFile("frames/frame_164.txt"),
|
||||
@embedFile("frames/frame_165.txt"),
|
||||
@embedFile("frames/frame_166.txt"),
|
||||
@embedFile("frames/frame_167.txt"),
|
||||
@embedFile("frames/frame_168.txt"),
|
||||
@embedFile("frames/frame_169.txt"),
|
||||
@embedFile("frames/frame_170.txt"),
|
||||
@embedFile("frames/frame_171.txt"),
|
||||
@embedFile("frames/frame_172.txt"),
|
||||
@embedFile("frames/frame_173.txt"),
|
||||
@embedFile("frames/frame_174.txt"),
|
||||
@embedFile("frames/frame_175.txt"),
|
||||
@embedFile("frames/frame_176.txt"),
|
||||
@embedFile("frames/frame_177.txt"),
|
||||
@embedFile("frames/frame_178.txt"),
|
||||
@embedFile("frames/frame_179.txt"),
|
||||
@embedFile("frames/frame_180.txt"),
|
||||
@embedFile("frames/frame_181.txt"),
|
||||
@embedFile("frames/frame_182.txt"),
|
||||
@embedFile("frames/frame_183.txt"),
|
||||
@embedFile("frames/frame_184.txt"),
|
||||
@embedFile("frames/frame_185.txt"),
|
||||
@embedFile("frames/frame_186.txt"),
|
||||
@embedFile("frames/frame_187.txt"),
|
||||
@embedFile("frames/frame_188.txt"),
|
||||
@embedFile("frames/frame_189.txt"),
|
||||
@embedFile("frames/frame_190.txt"),
|
||||
@embedFile("frames/frame_191.txt"),
|
||||
@embedFile("frames/frame_192.txt"),
|
||||
@embedFile("frames/frame_193.txt"),
|
||||
@embedFile("frames/frame_194.txt"),
|
||||
@embedFile("frames/frame_195.txt"),
|
||||
@embedFile("frames/frame_196.txt"),
|
||||
@embedFile("frames/frame_197.txt"),
|
||||
@embedFile("frames/frame_198.txt"),
|
||||
@embedFile("frames/frame_199.txt"),
|
||||
@embedFile("frames/frame_200.txt"),
|
||||
@embedFile("frames/frame_201.txt"),
|
||||
@embedFile("frames/frame_202.txt"),
|
||||
@embedFile("frames/frame_203.txt"),
|
||||
@embedFile("frames/frame_204.txt"),
|
||||
@embedFile("frames/frame_205.txt"),
|
||||
@embedFile("frames/frame_206.txt"),
|
||||
@embedFile("frames/frame_207.txt"),
|
||||
@embedFile("frames/frame_208.txt"),
|
||||
@embedFile("frames/frame_209.txt"),
|
||||
@embedFile("frames/frame_210.txt"),
|
||||
@embedFile("frames/frame_211.txt"),
|
||||
@embedFile("frames/frame_212.txt"),
|
||||
@embedFile("frames/frame_213.txt"),
|
||||
@embedFile("frames/frame_214.txt"),
|
||||
@embedFile("frames/frame_215.txt"),
|
||||
@embedFile("frames/frame_216.txt"),
|
||||
@embedFile("frames/frame_217.txt"),
|
||||
@embedFile("frames/frame_218.txt"),
|
||||
@embedFile("frames/frame_219.txt"),
|
||||
@embedFile("frames/frame_220.txt"),
|
||||
@embedFile("frames/frame_221.txt"),
|
||||
@embedFile("frames/frame_222.txt"),
|
||||
@embedFile("frames/frame_223.txt"),
|
||||
@embedFile("frames/frame_224.txt"),
|
||||
@embedFile("frames/frame_225.txt"),
|
||||
@embedFile("frames/frame_226.txt"),
|
||||
@embedFile("frames/frame_227.txt"),
|
||||
@embedFile("frames/frame_228.txt"),
|
||||
@embedFile("frames/frame_229.txt"),
|
||||
@embedFile("frames/frame_230.txt"),
|
||||
@embedFile("frames/frame_231.txt"),
|
||||
@embedFile("frames/frame_232.txt"),
|
||||
@embedFile("frames/frame_233.txt"),
|
||||
@embedFile("frames/frame_234.txt"),
|
||||
@embedFile("frames/frame_235.txt"),
|
||||
};
|
@@ -13,13 +13,11 @@ pub const GhosttyDocs = @import("GhosttyDocs.zig");
|
||||
pub const GhosttyExe = @import("GhosttyExe.zig");
|
||||
pub const GhosttyFrameData = @import("GhosttyFrameData.zig");
|
||||
pub const GhosttyLib = @import("GhosttyLib.zig");
|
||||
pub const GhosttyLibVt = @import("GhosttyLibVt.zig");
|
||||
pub const GhosttyResources = @import("GhosttyResources.zig");
|
||||
pub const GhosttyI18n = @import("GhosttyI18n.zig");
|
||||
pub const GhosttyXcodebuild = @import("GhosttyXcodebuild.zig");
|
||||
pub const GhosttyXCFramework = @import("GhosttyXCFramework.zig");
|
||||
pub const GhosttyWebdata = @import("GhosttyWebdata.zig");
|
||||
pub const GhosttyZig = @import("GhosttyZig.zig");
|
||||
pub const HelpStrings = @import("HelpStrings.zig");
|
||||
pub const SharedDeps = @import("SharedDeps.zig");
|
||||
pub const UnicodeTables = @import("UnicodeTables.zig");
|
||||
@@ -30,5 +28,10 @@ pub const LipoStep = @import("LipoStep.zig");
|
||||
pub const MetallibStep = @import("MetallibStep.zig");
|
||||
pub const XCFrameworkStep = @import("XCFrameworkStep.zig");
|
||||
|
||||
// Shell completions
|
||||
pub const fish_completions = @import("fish_completions.zig").completions;
|
||||
pub const zsh_completions = @import("zsh_completions.zig").completions;
|
||||
pub const bash_completions = @import("bash_completions.zig").completions;
|
||||
|
||||
// Helpers
|
||||
pub const requireZig = @import("zig.zig").requireZig;
|
||||
|
@@ -1,81 +0,0 @@
|
||||
const std = @import("std");
|
||||
const config = @import("config.zig");
|
||||
const config_x = @import("config.x.zig");
|
||||
const d = config.default;
|
||||
const wcwidth = config_x.wcwidth;
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
fn computeWidth(
|
||||
alloc: std.mem.Allocator,
|
||||
cp: u21,
|
||||
data: anytype,
|
||||
backing: anytype,
|
||||
tracking: anytype,
|
||||
) Allocator.Error!void {
|
||||
_ = alloc;
|
||||
_ = cp;
|
||||
_ = backing;
|
||||
_ = tracking;
|
||||
data.width = @intCast(@min(2, @max(0, data.wcwidth)));
|
||||
}
|
||||
|
||||
const width = config.Extension{
|
||||
.inputs = &.{"wcwidth"},
|
||||
.compute = &computeWidth,
|
||||
.fields = &.{
|
||||
.{ .name = "width", .type = u2 },
|
||||
},
|
||||
};
|
||||
|
||||
fn computeIsSymbol(
|
||||
alloc: Allocator,
|
||||
cp: u21,
|
||||
data: anytype,
|
||||
backing: anytype,
|
||||
tracking: anytype,
|
||||
) Allocator.Error!void {
|
||||
_ = alloc;
|
||||
_ = cp;
|
||||
_ = backing;
|
||||
_ = tracking;
|
||||
const block = data.block;
|
||||
data.is_symbol = data.general_category == .other_private_use or
|
||||
block == .dingbats or
|
||||
block == .emoticons or
|
||||
block == .miscellaneous_symbols or
|
||||
block == .enclosed_alphanumerics or
|
||||
block == .enclosed_alphanumeric_supplement or
|
||||
block == .miscellaneous_symbols_and_pictographs or
|
||||
block == .transport_and_map_symbols;
|
||||
}
|
||||
|
||||
const is_symbol = config.Extension{
|
||||
.inputs = &.{ "block", "general_category" },
|
||||
.compute = &computeIsSymbol,
|
||||
.fields = &.{
|
||||
.{ .name = "is_symbol", .type = bool },
|
||||
},
|
||||
};
|
||||
|
||||
pub const tables = [_]config.Table{
|
||||
.{
|
||||
.name = "runtime",
|
||||
.extensions = &.{},
|
||||
.fields = &.{
|
||||
d.field("is_emoji_presentation"),
|
||||
d.field("case_folding_full"),
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "buildtime",
|
||||
.extensions = &.{ wcwidth, width, is_symbol },
|
||||
.fields = &.{
|
||||
width.field("width"),
|
||||
d.field("grapheme_break"),
|
||||
is_symbol.field("is_symbol"),
|
||||
d.field("is_emoji_modifier"),
|
||||
d.field("is_emoji_modifier_base"),
|
||||
},
|
||||
},
|
||||
};
|
@@ -1,3 +0,0 @@
|
||||
/// Target for xcframework builds. This is a separate file so that
|
||||
/// our runtime code doesn't need to import build code.
|
||||
pub const Target = enum { native, universal };
|
@@ -41,7 +41,7 @@ pub const flatpak = options.flatpak;
|
||||
pub const snap = options.snap;
|
||||
pub const app_runtime: apprt.Runtime = config.app_runtime;
|
||||
pub const font_backend: font.Backend = config.font_backend;
|
||||
pub const renderer: rendererpkg.Backend = config.renderer;
|
||||
pub const renderer: rendererpkg.Impl = config.renderer;
|
||||
pub const i18n: bool = config.i18n;
|
||||
|
||||
/// The bundle ID for the app. This is used in many places and is currently
|
||||
|
@@ -49,4 +49,7 @@ pub const Wasm = if (!builtin.target.cpu.arch.isWasm()) struct {} else @import("
|
||||
|
||||
test {
|
||||
@import("std").testing.refAllDecls(@This());
|
||||
|
||||
// Vim syntax file, not used at runtime but we want to keep it tested.
|
||||
_ = @import("config/vim.zig");
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const global_state = &@import("../global.zig").state;
|
||||
const fontpkg = @import("../font/main.zig");
|
||||
const inputpkg = @import("../input.zig");
|
||||
const terminal = @import("../terminal/main.zig");
|
||||
const internal_os = @import("../os/main.zig");
|
||||
const cli = @import("../cli.zig");
|
||||
|
||||
@@ -38,16 +39,6 @@ const RepeatableStringMap = @import("RepeatableStringMap.zig");
|
||||
pub const Path = @import("path.zig").Path;
|
||||
pub const RepeatablePath = @import("path.zig").RepeatablePath;
|
||||
|
||||
// We do this instead of importing all of terminal/main.zig to
|
||||
// limit the dependency graph. This is important because some things
|
||||
// like the `ghostty-build-data` binary depend on the Config but don't
|
||||
// want to include all the other stuff.
|
||||
const terminal = struct {
|
||||
const CursorStyle = @import("../terminal/cursor.zig").Style;
|
||||
const color = @import("../terminal/color.zig");
|
||||
const x11_color = @import("../terminal/x11_color.zig");
|
||||
};
|
||||
|
||||
const log = std.log.scoped(.config);
|
||||
|
||||
/// Used on Unixes for some defaults.
|
||||
@@ -2359,11 +2350,6 @@ keybind: Keybinds = .{},
|
||||
/// cache manually using various arguments.
|
||||
/// (Available since: 1.2.0)
|
||||
///
|
||||
/// * `path` - Add Ghostty's binary directory to PATH. This ensures the `ghostty`
|
||||
/// command is available in the shell even if shell init scripts reset PATH.
|
||||
/// This is particularly useful on macOS where PATH is often overridden by
|
||||
/// system scripts. The directory is only added if not already present.
|
||||
///
|
||||
/// SSH features work independently and can be combined for optimal experience:
|
||||
/// when both `ssh-env` and `ssh-terminfo` are enabled, Ghostty will install its
|
||||
/// terminfo on remote hosts and use `xterm-ghostty` as TERM, falling back to
|
||||
@@ -2884,7 +2870,7 @@ keybind: Keybinds = .{},
|
||||
///
|
||||
/// Note: This configuration is required when `macos-icon` is set to
|
||||
/// `custom`
|
||||
@"macos-custom-icon": ?[:0]const u8 = null,
|
||||
@"macos-custom-icon": ?[]const u8 = null,
|
||||
|
||||
/// The material to use for the frame of the macOS app icon.
|
||||
///
|
||||
@@ -6999,7 +6985,6 @@ pub const ShellIntegrationFeatures = packed struct {
|
||||
title: bool = true,
|
||||
@"ssh-env": bool = false,
|
||||
@"ssh-terminfo": bool = false,
|
||||
path: bool = true,
|
||||
};
|
||||
|
||||
pub const RepeatableCommand = struct {
|
||||
|
@@ -6,11 +6,8 @@
|
||||
# {[path]s}
|
||||
#
|
||||
# The template does not set any default options, since Ghostty ships
|
||||
# with sensible defaults for all options.
|
||||
# Note that you should not paste the output of `ghostty +show-config
|
||||
# --default` into your config: some default options actually conflict with each other
|
||||
# when explicitly set in a configuration file. Instead, only set the
|
||||
# options you actually need.
|
||||
# with sensible defaults for all options. Users should only need to set
|
||||
# options that they want to change from the default.
|
||||
#
|
||||
# Run `ghostty +show-config --default --docs` to view a list of
|
||||
# all available config options and their default values.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const std = @import("std");
|
||||
const Config = @import("../config/Config.zig");
|
||||
const Config = @import("Config.zig");
|
||||
|
||||
const Template = struct {
|
||||
const header =
|
@@ -1,5 +1,5 @@
|
||||
const std = @import("std");
|
||||
const Config = @import("../config/Config.zig");
|
||||
const Config = @import("Config.zig");
|
||||
|
||||
/// This is the associated Vim file as named by the variable.
|
||||
pub const syntax = comptimeGenSyntax();
|
@@ -5,6 +5,7 @@
|
||||
const dir = @import("dir.zig");
|
||||
const sentry_envelope = @import("sentry_envelope.zig");
|
||||
|
||||
pub const minidump = @import("minidump.zig");
|
||||
pub const sentry = @import("sentry.zig");
|
||||
pub const Envelope = sentry_envelope.Envelope;
|
||||
pub const defaultDir = dir.defaultDir;
|
||||
|
7
src/crash/minidump.zig
Normal file
7
src/crash/minidump.zig
Normal file
@@ -0,0 +1,7 @@
|
||||
pub const reader = @import("minidump/reader.zig");
|
||||
pub const stream = @import("minidump/stream.zig");
|
||||
pub const Reader = reader.Reader;
|
||||
|
||||
test {
|
||||
@import("std").testing.refAllDecls(@This());
|
||||
}
|
59
src/crash/minidump/external.zig
Normal file
59
src/crash/minidump/external.zig
Normal file
@@ -0,0 +1,59 @@
|
||||
//! This file contains the external structs and constants for the minidump
|
||||
//! format. Most are from the Microsoft documentation on the minidump format:
|
||||
//! https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/
|
||||
//!
|
||||
//! Wherever possible, we also compare our definitions to other projects
|
||||
//! such as rust-minidump, libmdmp, breakpad, etc. to ensure we're doing
|
||||
//! the right thing.
|
||||
|
||||
/// "MDMP" in little-endian.
|
||||
pub const signature = 0x504D444D;
|
||||
|
||||
/// The version of the minidump format.
|
||||
pub const version = 0xA793;
|
||||
|
||||
/// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_header
|
||||
pub const Header = extern struct {
|
||||
signature: u32,
|
||||
version: packed struct(u32) { low: u16, high: u16 },
|
||||
stream_count: u32,
|
||||
stream_directory_rva: u32,
|
||||
checksum: u32,
|
||||
time_date_stamp: u32,
|
||||
flags: u64,
|
||||
};
|
||||
|
||||
/// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_directory
|
||||
pub const Directory = extern struct {
|
||||
stream_type: u32,
|
||||
location: LocationDescriptor,
|
||||
};
|
||||
|
||||
/// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_location_descriptor
|
||||
pub const LocationDescriptor = extern struct {
|
||||
data_size: u32,
|
||||
rva: u32,
|
||||
};
|
||||
|
||||
/// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_memory_descriptor
|
||||
pub const MemoryDescriptor = extern struct {
|
||||
start_of_memory_range: u64,
|
||||
memory: LocationDescriptor,
|
||||
};
|
||||
|
||||
/// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_thread_list
|
||||
pub const ThreadList = extern struct {
|
||||
number_of_threads: u32,
|
||||
threads: [1]Thread,
|
||||
};
|
||||
|
||||
/// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_thread
|
||||
pub const Thread = extern struct {
|
||||
thread_id: u32,
|
||||
suspend_count: u32,
|
||||
priority_class: u32,
|
||||
priority: u32,
|
||||
teb: u64,
|
||||
stack: MemoryDescriptor,
|
||||
thread_context: LocationDescriptor,
|
||||
};
|
242
src/crash/minidump/reader.zig
Normal file
242
src/crash/minidump/reader.zig
Normal file
@@ -0,0 +1,242 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const external = @import("external.zig");
|
||||
const stream = @import("stream.zig");
|
||||
const EncodedStream = stream.EncodedStream;
|
||||
|
||||
const log = std.log.scoped(.minidump_reader);
|
||||
|
||||
/// Possible minidump-specific errors that can occur when reading a minidump.
|
||||
/// This isn't the full error set since IO errors can also occur depending
|
||||
/// on the Source type.
|
||||
pub const ReadError = error{
|
||||
InvalidHeader,
|
||||
InvalidVersion,
|
||||
StreamSizeMismatch,
|
||||
};
|
||||
|
||||
/// Reader creates a new minidump reader for the given source type. The
|
||||
/// source must have both a "reader()" and "seekableStream()" function.
|
||||
///
|
||||
/// Given the format of a minidump file, we must keep the source open and
|
||||
/// continually access it because the format of the minidump is full of
|
||||
/// pointers and offsets that we must follow depending on the stream types.
|
||||
/// Also, since we're not aware of all stream types (in fact its impossible
|
||||
/// to be aware since custom stream types are allowed), its possible any stream
|
||||
/// type can define their own pointers and offsets. So, the source must always
|
||||
/// be available so callers can decode the streams as needed.
|
||||
pub fn Reader(comptime S: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
/// The source data.
|
||||
source: Source,
|
||||
|
||||
/// The endianness of the minidump file. This is detected by reading
|
||||
/// the byte order of the header.
|
||||
endian: std.builtin.Endian,
|
||||
|
||||
/// The number of streams within the minidump file. This is read from
|
||||
/// the header and stored here so we can quickly access them. Note
|
||||
/// the stream types require reading the source; this is an optimization
|
||||
/// to avoid any allocations on the reader and the caller can choose
|
||||
/// to store them if they want.
|
||||
stream_count: u32,
|
||||
stream_directory_rva: u32,
|
||||
|
||||
const SourceCallable = switch (@typeInfo(Source)) {
|
||||
.pointer => |v| v.child,
|
||||
.@"struct" => Source,
|
||||
else => @compileError("Source type must be a pointer or struct"),
|
||||
};
|
||||
|
||||
const SourceReader = @typeInfo(@TypeOf(SourceCallable.reader)).@"fn".return_type.?;
|
||||
const SourceSeeker = @typeInfo(@TypeOf(SourceCallable.seekableStream)).@"fn".return_type.?;
|
||||
|
||||
/// A limited reader for reading data from the source.
|
||||
pub const LimitedReader = std.io.LimitedReader(SourceReader);
|
||||
|
||||
/// The source type for the reader.
|
||||
pub const Source = S;
|
||||
|
||||
/// The stream types for reading
|
||||
pub const ThreadList = stream.thread_list.ThreadListReader(Self);
|
||||
|
||||
/// The reader type for stream reading. This has some other methods so
|
||||
/// you must still call reader() on the result to get the actual
|
||||
/// reader to read the data.
|
||||
pub const StreamReader = struct {
|
||||
source: Source,
|
||||
endian: std.builtin.Endian,
|
||||
directory: external.Directory,
|
||||
|
||||
/// Should not be accessed directly. This is setup whenever
|
||||
/// reader() is called.
|
||||
limit_reader: LimitedReader = undefined,
|
||||
|
||||
pub const Reader = LimitedReader.Reader;
|
||||
|
||||
/// Returns a Reader implementation that reads the bytes of the
|
||||
/// stream.
|
||||
///
|
||||
/// The reader is dependent on the state of Source so any
|
||||
/// state-changing operations on Source will invalidate the
|
||||
/// reader. For example, making another reader, reading another
|
||||
/// stream directory, closing the source, etc.
|
||||
pub fn reader(self: *StreamReader) LimitedReader.Reader {
|
||||
try self.source.seekableStream().seekTo(self.directory.location.rva);
|
||||
self.limit_reader = .{
|
||||
.inner_reader = self.source.reader(),
|
||||
.bytes_left = self.directory.location.data_size,
|
||||
};
|
||||
return self.limit_reader.reader();
|
||||
}
|
||||
|
||||
/// Seeks the source to the location of the directory.
|
||||
pub fn seekToPayload(self: *StreamReader) !void {
|
||||
try self.source.seekableStream().seekTo(self.directory.location.rva);
|
||||
}
|
||||
};
|
||||
|
||||
/// Iterator type to read over the streams in the minidump file.
|
||||
pub const StreamIterator = struct {
|
||||
reader: *const Self,
|
||||
i: u32 = 0,
|
||||
|
||||
pub fn next(self: *StreamIterator) !?StreamReader {
|
||||
if (self.i >= self.reader.stream_count) return null;
|
||||
const dir = try self.reader.directory(self.i);
|
||||
self.i += 1;
|
||||
return try self.reader.streamReader(dir);
|
||||
}
|
||||
};
|
||||
|
||||
/// Initialize a reader. The source must remain available for the entire
|
||||
/// lifetime of the reader. The reader does not take ownership of the
|
||||
/// source so if it has resources that need to be cleaned up, the caller
|
||||
/// must do so once the reader is no longer needed.
|
||||
pub fn init(source: Source) !Self {
|
||||
const header, const endian = try readHeader(Source, source);
|
||||
return .{
|
||||
.source = source,
|
||||
.endian = endian,
|
||||
.stream_count = header.stream_count,
|
||||
.stream_directory_rva = header.stream_directory_rva,
|
||||
};
|
||||
}
|
||||
|
||||
/// Return an iterator to read over the streams in the minidump file.
|
||||
/// This is very similar to using a simple for loop to stream_count
|
||||
/// and calling directory() on each index, but is more idiomatic
|
||||
/// Zig.
|
||||
pub fn streamIterator(self: *const Self) StreamIterator {
|
||||
return .{ .reader = self };
|
||||
}
|
||||
|
||||
/// Return a StreamReader for the given directory type. This streams
|
||||
/// from the underlying source so the returned reader is only valid
|
||||
/// as long as the source is unmodified (i.e. the source is not
|
||||
/// closed, the source seek position is not moved, etc.).
|
||||
pub fn streamReader(
|
||||
self: *const Self,
|
||||
dir: external.Directory,
|
||||
) SourceSeeker.SeekError!StreamReader {
|
||||
return .{
|
||||
.source = self.source,
|
||||
.endian = self.endian,
|
||||
.directory = dir,
|
||||
};
|
||||
}
|
||||
|
||||
/// Get the directory entry with the given index.
|
||||
///
|
||||
/// Asserts the index is valid (idx < stream_count).
|
||||
pub fn directory(self: *const Self, idx: usize) !external.Directory {
|
||||
assert(idx < self.stream_count);
|
||||
|
||||
// Seek to the directory.
|
||||
const offset: u32 = @intCast(@sizeOf(external.Directory) * idx);
|
||||
const rva: u32 = self.stream_directory_rva + offset;
|
||||
try self.source.seekableStream().seekTo(rva);
|
||||
|
||||
// Read the directory.
|
||||
return try self.source.reader().readStructEndian(
|
||||
external.Directory,
|
||||
self.endian,
|
||||
);
|
||||
}
|
||||
|
||||
/// Return a reader for the given location descriptor. This is only
|
||||
/// valid until the reader source is modified in some way.
|
||||
pub fn locationReader(
|
||||
self: *const Self,
|
||||
loc: external.LocationDescriptor,
|
||||
) !LimitedReader {
|
||||
try self.source.seekableStream().seekTo(loc.rva);
|
||||
return .{
|
||||
.inner_reader = self.source.reader(),
|
||||
.bytes_left = loc.data_size,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Reads the header for the minidump file and returns endianness of
|
||||
/// the file.
|
||||
fn readHeader(comptime T: type, source: T) !struct {
|
||||
external.Header,
|
||||
std.builtin.Endian,
|
||||
} {
|
||||
// Start by trying LE.
|
||||
var endian: std.builtin.Endian = .little;
|
||||
var header = try source.reader().readStructEndian(external.Header, endian);
|
||||
|
||||
// If the signature doesn't match, we assume its BE.
|
||||
if (header.signature != external.signature) {
|
||||
// Seek back to the start of the file so we can reread.
|
||||
try source.seekableStream().seekTo(0);
|
||||
|
||||
// Try BE, if the signature doesn't match, return an error.
|
||||
endian = .big;
|
||||
header = try source.reader().readStructEndian(external.Header, endian);
|
||||
if (header.signature != external.signature) return ReadError.InvalidHeader;
|
||||
}
|
||||
|
||||
// "The low-order word is MINIDUMP_VERSION. The high-order word is an
|
||||
// internal value that is implementation specific."
|
||||
if (header.version.low != external.version) return ReadError.InvalidVersion;
|
||||
|
||||
return .{ header, endian };
|
||||
}
|
||||
|
||||
// Uncomment to dump some debug information for a minidump file.
|
||||
test "minidump debug" {
|
||||
var fbs = std.io.fixedBufferStream(@embedFile("../testdata/macos.dmp"));
|
||||
const r = try Reader(*@TypeOf(fbs)).init(&fbs);
|
||||
var it = r.streamIterator();
|
||||
while (try it.next()) |s| {
|
||||
log.warn("directory i={} dir={}", .{ it.i - 1, s.directory });
|
||||
}
|
||||
}
|
||||
|
||||
test "minidump read" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var fbs = std.io.fixedBufferStream(@embedFile("../testdata/macos.dmp"));
|
||||
const r = try Reader(*@TypeOf(fbs)).init(&fbs);
|
||||
try testing.expectEqual(std.builtin.Endian.little, r.endian);
|
||||
try testing.expectEqual(7, r.stream_count);
|
||||
{
|
||||
const dir = try r.directory(0);
|
||||
try testing.expectEqual(3, dir.stream_type);
|
||||
try testing.expectEqual(584, dir.location.data_size);
|
||||
|
||||
var bytes = std.ArrayList(u8).init(alloc);
|
||||
defer bytes.deinit();
|
||||
var sr = try r.streamReader(dir);
|
||||
try sr.reader().readAllArrayList(&bytes, std.math.maxInt(usize));
|
||||
try testing.expectEqual(584, bytes.items.len);
|
||||
}
|
||||
}
|
30
src/crash/minidump/stream.zig
Normal file
30
src/crash/minidump/stream.zig
Normal file
@@ -0,0 +1,30 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const log = std.log.scoped(.minidump_stream);
|
||||
|
||||
/// The known stream types.
|
||||
pub const thread_list = @import("stream_threadlist.zig");
|
||||
|
||||
/// A stream within the minidump file. A stream can be either in an encoded
|
||||
/// form or decoded form. The encoded form are raw bytes and aren't validated
|
||||
/// until they're decoded. The decoded form is a structured form of the stream.
|
||||
///
|
||||
/// The decoded form is more ergonomic to work with but the encoded form is
|
||||
/// more efficient to read/write.
|
||||
pub const Stream = union(enum) {
|
||||
encoded: EncodedStream,
|
||||
};
|
||||
|
||||
/// An encoded stream value. It is "encoded" in the sense that it is raw bytes
|
||||
/// with a type associated. The raw bytes are not validated to be correct for
|
||||
/// the type.
|
||||
pub const EncodedStream = struct {
|
||||
type: u32,
|
||||
data: []const u8,
|
||||
};
|
||||
|
||||
test {
|
||||
@import("std").testing.refAllDecls(@This());
|
||||
}
|
117
src/crash/minidump/stream_threadlist.zig
Normal file
117
src/crash/minidump/stream_threadlist.zig
Normal file
@@ -0,0 +1,117 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const external = @import("external.zig");
|
||||
const readerpkg = @import("reader.zig");
|
||||
const Reader = readerpkg.Reader;
|
||||
const ReadError = readerpkg.ReadError;
|
||||
|
||||
const log = std.log.scoped(.minidump_stream);
|
||||
|
||||
/// This is the list of threads from the process.
|
||||
///
|
||||
/// This is the Reader implementation. You usually do not use this directly.
|
||||
/// Instead, use Reader(T).ThreadList which will get you the same thing.
|
||||
///
|
||||
/// ThreadList is stream type 0x3.
|
||||
/// StreamReader is the Reader(T).StreamReader type.
|
||||
pub fn ThreadListReader(comptime R: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
/// The number of threads in the list.
|
||||
count: u32,
|
||||
|
||||
/// The rva to the first thread in the list.
|
||||
rva: u32,
|
||||
|
||||
/// Source data and endianness so we can read.
|
||||
source: R.Source,
|
||||
endian: std.builtin.Endian,
|
||||
|
||||
pub fn init(r: *R.StreamReader) !Self {
|
||||
assert(r.directory.stream_type == 0x3);
|
||||
try r.seekToPayload();
|
||||
const reader = r.source.reader();
|
||||
|
||||
// Our count is always a u32 in the header.
|
||||
const count = try reader.readInt(u32, r.endian);
|
||||
|
||||
// Determine if we have padding in our header. It is possible
|
||||
// for there to be padding if the list header was written by
|
||||
// a 32-bit process but is being read on a 64-bit process.
|
||||
const padding = padding: {
|
||||
const maybe_size = @sizeOf(u32) + (@sizeOf(external.Thread) * count);
|
||||
switch (std.math.order(maybe_size, r.directory.location.data_size)) {
|
||||
// It should never be larger than what the directory says.
|
||||
.gt => return ReadError.StreamSizeMismatch,
|
||||
|
||||
// If the sizes match exactly we're good.
|
||||
.eq => break :padding 0,
|
||||
|
||||
.lt => {
|
||||
const padding = r.directory.location.data_size - maybe_size;
|
||||
if (padding != 4) return ReadError.StreamSizeMismatch;
|
||||
break :padding padding;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// Rva is the location of the first thread in the list.
|
||||
const rva = r.directory.location.rva + @as(u32, @sizeOf(u32)) + padding;
|
||||
|
||||
return .{
|
||||
.count = count,
|
||||
.rva = rva,
|
||||
.source = r.source,
|
||||
.endian = r.endian,
|
||||
};
|
||||
}
|
||||
|
||||
/// Get the thread entry for the given index.
|
||||
///
|
||||
/// Index is asserted to be less than count.
|
||||
pub fn thread(self: *const Self, i: usize) !external.Thread {
|
||||
assert(i < self.count);
|
||||
|
||||
// Seek to the thread
|
||||
const offset: u32 = @intCast(@sizeOf(external.Thread) * i);
|
||||
const rva: u32 = self.rva + offset;
|
||||
try self.source.seekableStream().seekTo(rva);
|
||||
|
||||
// Read the thread
|
||||
return try self.source.reader().readStructEndian(
|
||||
external.Thread,
|
||||
self.endian,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "minidump: threadlist" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var fbs = std.io.fixedBufferStream(@embedFile("../testdata/macos.dmp"));
|
||||
const R = Reader(*@TypeOf(fbs));
|
||||
const r = try R.init(&fbs);
|
||||
|
||||
// Get our thread list stream
|
||||
const dir = try r.directory(0);
|
||||
try testing.expectEqual(3, dir.stream_type);
|
||||
var sr = try r.streamReader(dir);
|
||||
|
||||
// Get our rich structure
|
||||
const v = try R.ThreadList.init(&sr);
|
||||
log.warn("threadlist count={} rva={}", .{ v.count, v.rva });
|
||||
|
||||
try testing.expectEqual(12, v.count);
|
||||
for (0..v.count) |i| {
|
||||
const t = try v.thread(i);
|
||||
log.warn("thread i={} thread={}", .{ i, t });
|
||||
|
||||
// Read our stack memory
|
||||
var stack_reader = try r.locationReader(t.stack.memory);
|
||||
const bytes = try stack_reader.reader().readAllAlloc(alloc, t.stack.memory.data_size);
|
||||
defer alloc.free(bytes);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user