mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-25 20:48:35 +00:00
Compare commits
188 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
230014a536 | ||
![]() |
f8fa812932 | ||
![]() |
dbbff53af7 | ||
![]() |
74419b2fcf | ||
![]() |
bff758f03b | ||
![]() |
fc0a37f9e0 | ||
![]() |
103e7abad5 | ||
![]() |
64800d94ba | ||
![]() |
232b1898fa | ||
![]() |
390f72accc | ||
![]() |
37372fa50b | ||
![]() |
37e238c2f6 | ||
![]() |
96e9053862 | ||
![]() |
48827b21d8 | ||
![]() |
513cdf667b | ||
![]() |
0944f051aa | ||
![]() |
4d165fbaaa | ||
![]() |
43089a01f1 | ||
![]() |
fba953feeb | ||
![]() |
e7a0198103 | ||
![]() |
2c78ad8889 | ||
![]() |
de013148d3 | ||
![]() |
e1429dabae | ||
![]() |
969fcfaec3 | ||
![]() |
315b54822a | ||
![]() |
5f3fd9742f | ||
![]() |
5265414a36 | ||
![]() |
32bf37e5e4 | ||
![]() |
def4969aff | ||
![]() |
3d04fbb451 | ||
![]() |
85345c31cf | ||
![]() |
35095fddda | ||
![]() |
b006101ddd | ||
![]() |
f97518cc10 | ||
![]() |
31af87e021 | ||
![]() |
2a24918eec | ||
![]() |
bd9bc5f1b9 | ||
![]() |
9072bab6b8 | ||
![]() |
f8472cb32b | ||
![]() |
0bbe39fb0a | ||
![]() |
52c0afcc93 | ||
![]() |
862e19cbab | ||
![]() |
a9c5a05e5b | ||
![]() |
aa52e11c34 | ||
![]() |
3eb646ea6b | ||
![]() |
131f4fb8b1 | ||
![]() |
a584163306 | ||
![]() |
e951dedc66 | ||
![]() |
36e09cdbe1 | ||
![]() |
f36ccc4866 | ||
![]() |
2aad450d2e | ||
![]() |
8cb52323e5 | ||
![]() |
c177716ac6 | ||
![]() |
8477b6a21a | ||
![]() |
530633b9e9 | ||
![]() |
5a29dd3ef5 | ||
![]() |
6893024c51 | ||
![]() |
8aa4373aaf | ||
![]() |
fd9014952f | ||
![]() |
9c92c3bb81 | ||
![]() |
dfda3ac280 | ||
![]() |
3e1ba35843 | ||
![]() |
14eb8aa4e4 | ||
![]() |
f42656b0ac | ||
![]() |
645520b502 | ||
![]() |
3e34009492 | ||
![]() |
64f26c14d3 | ||
![]() |
1758f962f6 | ||
![]() |
4f974f4278 | ||
![]() |
811f9f05d0 | ||
![]() |
1b46884e72 | ||
![]() |
a42193b997 | ||
![]() |
485b6b73bf | ||
![]() |
6c160844b9 | ||
![]() |
1de584f32c | ||
![]() |
e9c18ff6db | ||
![]() |
4e7f847d03 | ||
![]() |
fdcaeebb99 | ||
![]() |
a63864d8df | ||
![]() |
3a4f7b3d0f | ||
![]() |
bc95317ba4 | ||
![]() |
17498ce122 | ||
![]() |
09b37e3b24 | ||
![]() |
4ff74fdfae | ||
![]() |
1a189787ae | ||
![]() |
25aaca5a6f | ||
![]() |
1a6af17041 | ||
![]() |
b52553de24 | ||
![]() |
f6c1653dee | ||
![]() |
055a007926 | ||
![]() |
cf0557a093 | ||
![]() |
fcd0f88024 | ||
![]() |
3254bb41d5 | ||
![]() |
1c59ed5d60 | ||
![]() |
3d3551d1ed | ||
![]() |
10dc9353b7 | ||
![]() |
42fc42de2d | ||
![]() |
180cc31d87 | ||
![]() |
fa5a44e591 | ||
![]() |
cfcd11863e | ||
![]() |
52c2f02fa4 | ||
![]() |
6e1eb67d94 | ||
![]() |
511314e1a1 | ||
![]() |
a96b2abf7c | ||
![]() |
d4bc73a9d6 | ||
![]() |
bf1278deff | ||
![]() |
c277ef8d82 | ||
![]() |
6ee9a3767b | ||
![]() |
b34e22053d | ||
![]() |
f0e407de85 | ||
![]() |
fbaacc235b | ||
![]() |
f6e4a2888a | ||
![]() |
270891eee1 | ||
![]() |
7b8be344fc | ||
![]() |
bf3a607db6 | ||
![]() |
d55f3e5c41 | ||
![]() |
2de105e035 | ||
![]() |
944f206b76 | ||
![]() |
da2a3e2510 | ||
![]() |
9feaec9c9c | ||
![]() |
d65466362d | ||
![]() |
800fa99ff2 | ||
![]() |
bf047032b5 | ||
![]() |
999b605145 | ||
![]() |
4d761c96e5 | ||
![]() |
3ce1239460 | ||
![]() |
36ef1169f6 | ||
![]() |
66a2da13d4 | ||
![]() |
f60bdb0faa | ||
![]() |
55153937c6 | ||
![]() |
d27bc69f2e | ||
![]() |
1b6cda2b10 | ||
![]() |
950d3755ff | ||
![]() |
6143aa8ce0 | ||
![]() |
d30f1537ec | ||
![]() |
c42ed70758 | ||
![]() |
f375ec7c65 | ||
![]() |
122731c6e8 | ||
![]() |
38c0de3aa4 | ||
![]() |
6d40da1e1c | ||
![]() |
b9a5cad562 | ||
![]() |
6d2576abee | ||
![]() |
77b39c45a6 | ||
![]() |
d6e58ef1fc | ||
![]() |
7875efbcb8 | ||
![]() |
fe55d90ec5 | ||
![]() |
2ebef2650c | ||
![]() |
050188fc12 | ||
![]() |
ad92bf7ab5 | ||
![]() |
9b40e03c40 | ||
![]() |
da9334dce5 | ||
![]() |
4fa8b8f285 | ||
![]() |
834fe17abb | ||
![]() |
734d1a13b3 | ||
![]() |
92effb37db | ||
![]() |
38dcf0ab59 | ||
![]() |
773990ada3 | ||
![]() |
354b62d5ce | ||
![]() |
9f6991f9db | ||
![]() |
058d6808c1 | ||
![]() |
6ed00b1217 | ||
![]() |
a453681615 | ||
![]() |
a22a1771b5 | ||
![]() |
a3643f8f52 | ||
![]() |
cb0e60c3e5 | ||
![]() |
1efde5caba | ||
![]() |
6781fbda93 | ||
![]() |
55ac946fff | ||
![]() |
0f0a61c38d | ||
![]() |
4f47138ea3 | ||
![]() |
a098816709 | ||
![]() |
67992fde91 | ||
![]() |
abec922d91 | ||
![]() |
f7e622e8af | ||
![]() |
a32d4988f7 | ||
![]() |
b5b4b1be72 | ||
![]() |
07243789be | ||
![]() |
ed0d1b8371 | ||
![]() |
fd03a146ba | ||
![]() |
a92a237b80 | ||
![]() |
79f8ea07a1 | ||
![]() |
1397c76243 | ||
![]() |
0646cf8c1e | ||
![]() |
c6143a1539 | ||
![]() |
0e9d052e68 | ||
![]() |
ac9f3b88aa | ||
![]() |
8b00bd430d | ||
![]() |
1201bc27d2 |
2
.github/workflows/nix.yml
vendored
2
.github/workflows/nix.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- name: Setup Nix
|
- name: Setup Nix
|
||||||
uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
|
2
.github/workflows/release-tag.yml
vendored
2
.github/workflows/release-tag.yml
vendored
@@ -89,7 +89,7 @@ jobs:
|
|||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
|
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
|
||||||
|
5
.github/workflows/release-tip.yml
vendored
5
.github/workflows/release-tip.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
# Important so that build number generation works
|
# Important so that build number generation works
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -168,7 +168,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -579,7 +579,6 @@ jobs:
|
|||||||
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
|
# 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.
|
# validated by macOS even when an internet connection is not available.
|
||||||
echo "Attach staple"
|
echo "Attach staple"
|
||||||
xcrun stapler staple "Ghostty.dmg"
|
|
||||||
xcrun stapler staple "macos/build/Release/Ghostty.app"
|
xcrun stapler staple "macos/build/Release/Ghostty.app"
|
||||||
|
|
||||||
# Zip up the app
|
# Zip up the app
|
||||||
|
232
.github/workflows/test.yml
vendored
232
.github/workflows/test.yml
vendored
@@ -12,17 +12,22 @@ jobs:
|
|||||||
needs:
|
needs:
|
||||||
- build-bench
|
- build-bench
|
||||||
- build-dist
|
- build-dist
|
||||||
|
- build-examples
|
||||||
- build-flatpak
|
- build-flatpak
|
||||||
- build-freebsd
|
- build-freebsd
|
||||||
|
- build-libghostty-vt
|
||||||
- build-linux
|
- build-linux
|
||||||
- build-linux-libghostty
|
- build-linux-libghostty
|
||||||
- build-nix
|
- build-nix
|
||||||
- build-macos
|
- build-macos
|
||||||
- build-macos-matrix
|
- build-macos-matrix
|
||||||
|
- build-snap
|
||||||
- build-windows
|
- build-windows
|
||||||
- test
|
- test
|
||||||
|
- test-simd
|
||||||
- test-gtk
|
- test-gtk
|
||||||
- test-sentry-linux
|
- test-sentry-linux
|
||||||
|
- test-i18n
|
||||||
- test-macos
|
- test-macos
|
||||||
- pinact
|
- pinact
|
||||||
- prettier
|
- prettier
|
||||||
@@ -75,7 +80,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -86,6 +91,42 @@ jobs:
|
|||||||
- name: Build Benchmarks
|
- name: Build Benchmarks
|
||||||
run: nix develop -c zig build -Demit-bench
|
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@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
|
||||||
|
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:
|
build-flatpak:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -106,7 +147,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -118,7 +159,83 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
nix develop -c \
|
nix develop -c \
|
||||||
zig build \
|
zig build \
|
||||||
-Dflatpak=true
|
-Dflatpak
|
||||||
|
|
||||||
|
build-snap:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
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@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
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
|
with:
|
||||||
|
name: ghostty
|
||||||
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Build with Snap
|
||||||
|
run: |
|
||||||
|
nix develop -c \
|
||||||
|
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@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
|
||||||
|
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:
|
build-linux:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -142,7 +259,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -171,7 +288,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -204,7 +321,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -250,7 +367,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -275,7 +392,7 @@ jobs:
|
|||||||
trigger-snap:
|
trigger-snap:
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
runs-on: namespace-profile-ghostty-xsm
|
runs-on: namespace-profile-ghostty-xsm
|
||||||
needs: build-dist
|
needs: [build-dist, build-snap]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
@@ -462,7 +579,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -504,7 +621,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -529,6 +646,41 @@ jobs:
|
|||||||
-Dgtk-x11=${{ matrix.x11 }} \
|
-Dgtk-x11=${{ matrix.x11 }} \
|
||||||
-Dgtk-wayland=${{ matrix.wayland }}
|
-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@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
|
||||||
|
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:
|
test-sentry-linux:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -552,7 +704,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -593,6 +745,41 @@ jobs:
|
|||||||
- name: test
|
- name: test
|
||||||
run: nix develop -c zig build test --system ${{ steps.deps.outputs.deps }}
|
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@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
|
||||||
|
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:
|
zig-fmt:
|
||||||
if: github.repository == 'ghostty-org/ghostty'
|
if: github.repository == 'ghostty-org/ghostty'
|
||||||
runs-on: namespace-profile-ghostty-xsm
|
runs-on: namespace-profile-ghostty-xsm
|
||||||
@@ -608,7 +795,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -636,7 +823,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -663,7 +850,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -690,7 +877,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -717,7 +904,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -744,7 +931,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -778,7 +965,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -805,7 +992,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
/nix
|
/nix
|
||||||
/zig
|
/zig
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -842,7 +1029,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -857,6 +1044,7 @@ jobs:
|
|||||||
test-debian-13:
|
test-debian-13:
|
||||||
name: Test build on Debian 13
|
name: Test build on Debian 13
|
||||||
runs-on: namespace-profile-ghostty-sm
|
runs-on: namespace-profile-ghostty-sm
|
||||||
|
timeout-minutes: 10
|
||||||
needs: [test, build-dist]
|
needs: [test, build-dist]
|
||||||
steps:
|
steps:
|
||||||
- name: Install and configure Namespace CLI
|
- name: Install and configure Namespace CLI
|
||||||
@@ -929,7 +1117,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
- uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
@@ -964,7 +1152,7 @@ jobs:
|
|||||||
sudo systemctl start ssh
|
sudo systemctl start ssh
|
||||||
|
|
||||||
- name: Set up FreeBSD VM
|
- name: Set up FreeBSD VM
|
||||||
uses: vmactions/freebsd-vm@05856381fab64eeee9b038a0818f6cec649ca17a # v1.2.3
|
uses: vmactions/freebsd-vm@487ce35b96fae3e60d45b521735f5aa436ecfade # v1.2.4
|
||||||
with:
|
with:
|
||||||
release: ${{ matrix.release }}
|
release: ${{ matrix.release }}
|
||||||
copyback: false
|
copyback: false
|
||||||
|
2
.github/workflows/update-colorschemes.yml
vendored
2
.github/workflows/update-colorschemes.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
/zig
|
/zig
|
||||||
|
|
||||||
- name: Setup Nix
|
- name: Setup Nix
|
||||||
uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31.6.1
|
uses: cachix/install-nix-action@9280e7aca88deada44c930f1e2c78e21c3ae3edd # v31.7.0
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||||
|
@@ -184,6 +184,8 @@
|
|||||||
/po/ko_KR.UTF-8.po @ghostty-org/ko_KR
|
/po/ko_KR.UTF-8.po @ghostty-org/ko_KR
|
||||||
/po/he_IL.UTF-8.po @ghostty-org/he_IL
|
/po/he_IL.UTF-8.po @ghostty-org/he_IL
|
||||||
/po/it_IT.UTF-8.po @ghostty-org/it_IT
|
/po/it_IT.UTF-8.po @ghostty-org/it_IT
|
||||||
|
/po/zh_TW.UTF-8.po @ghostty-org/zh_TW
|
||||||
|
/po/hr_HR.UTF-8.po @ghostty-org/hr_HR
|
||||||
|
|
||||||
# Packaging - Snap
|
# Packaging - Snap
|
||||||
/snap/ @ghostty-org/snap
|
/snap/ @ghostty-org/snap
|
||||||
|
28
Doxyfile
Normal file
28
Doxyfile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# 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
|
62
build.zig
62
build.zig
@@ -8,22 +8,40 @@ comptime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
pub fn build(b: *std.Build) !void {
|
||||||
// This defines all the available build options (e.g. `-D`).
|
// This defines all the available build options (e.g. `-D`). If you
|
||||||
|
// 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 config = try buildpkg.Config.init(b);
|
||||||
const test_filter = b.option(
|
const test_filters = b.option(
|
||||||
[]const u8,
|
[][]const u8,
|
||||||
"test-filter",
|
"test-filter",
|
||||||
"Filter for test. Only applies to Zig tests.",
|
"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
|
// All our steps which we'll hook up later. The steps are shown
|
||||||
// up here just so that they are more self-documenting.
|
// 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_step = b.step("run", "Run the app");
|
||||||
const run_valgrind_step = b.step(
|
const run_valgrind_step = b.step(
|
||||||
"run-valgrind",
|
"run-valgrind",
|
||||||
"Run the app under valgrind",
|
"Run the app under valgrind",
|
||||||
);
|
);
|
||||||
const test_step = b.step("test", "Run tests");
|
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(
|
const test_valgrind_step = b.step(
|
||||||
"test-valgrind",
|
"test-valgrind",
|
||||||
"Run tests under valgrind",
|
"Run tests under valgrind",
|
||||||
@@ -37,10 +55,6 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const resources = try buildpkg.GhosttyResources.init(b, &config);
|
const resources = try buildpkg.GhosttyResources.init(b, &config);
|
||||||
const i18n = if (config.i18n) try buildpkg.GhosttyI18n.init(b, &config) else null;
|
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.
|
// Ghostty executable, the actual runnable Ghostty program.
|
||||||
const exe = try buildpkg.GhosttyExe.init(b, &config, &deps);
|
const exe = try buildpkg.GhosttyExe.init(b, &config, &deps);
|
||||||
|
|
||||||
@@ -73,7 +87,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
check_step.dependOn(dist.install_step);
|
check_step.dependOn(dist.install_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// libghostty
|
// libghostty (internal, big)
|
||||||
const libghostty_shared = try buildpkg.GhosttyLib.initShared(
|
const libghostty_shared = try buildpkg.GhosttyLib.initShared(
|
||||||
b,
|
b,
|
||||||
&deps,
|
&deps,
|
||||||
@@ -83,6 +97,17 @@ pub fn build(b: *std.Build) !void {
|
|||||||
&deps,
|
&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.
|
// Runtime "none" is libghostty, anything else is an executable.
|
||||||
if (config.app_runtime != .none) {
|
if (config.app_runtime != .none) {
|
||||||
if (config.emit_exe) {
|
if (config.emit_exe) {
|
||||||
@@ -185,7 +210,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
run_step.dependOn(&macos_app_native_only.open.step);
|
run_step.dependOn(&macos_app_native_only.open.step);
|
||||||
|
|
||||||
// If we have no test filters, install the tests too
|
// If we have no test filters, install the tests too
|
||||||
if (test_filter == null) {
|
if (test_filters.len == 0) {
|
||||||
macos_app_native_only.addTestStepDependencies(test_step);
|
macos_app_native_only.addTestStepDependencies(test_step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,11 +241,24 @@ pub fn build(b: *std.Build) !void {
|
|||||||
run_valgrind_step.dependOn(&run_cmd.step);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
{
|
{
|
||||||
|
// Full unit tests
|
||||||
const test_exe = b.addTest(.{
|
const test_exe = b.addTest(.{
|
||||||
.name = "ghostty-test",
|
.name = "ghostty-test",
|
||||||
.filters = if (test_filter) |v| &.{v} else &.{},
|
.filters = test_filters,
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = config.baselineTarget(),
|
.target = config.baselineTarget(),
|
||||||
@@ -230,7 +268,6 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.unwind_tables = .sync,
|
.unwind_tables = .sync,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (config.emit_test_exe) b.installArtifact(test_exe);
|
if (config.emit_test_exe) b.installArtifact(test_exe);
|
||||||
_ = try deps.add(test_exe);
|
_ = try deps.add(test_exe);
|
||||||
|
|
||||||
@@ -238,6 +275,9 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const test_run = b.addRunArtifact(test_exe);
|
const test_run = b.addRunArtifact(test_exe);
|
||||||
test_step.dependOn(&test_run.step);
|
test_step.dependOn(&test_run.step);
|
||||||
|
|
||||||
|
// Normal tests always test our libghostty modules
|
||||||
|
test_step.dependOn(test_lib_vt_step);
|
||||||
|
|
||||||
// Valgrind test running
|
// Valgrind test running
|
||||||
const valgrind_run = b.addSystemCommand(&.{
|
const valgrind_run = b.addSystemCommand(&.{
|
||||||
"valgrind",
|
"valgrind",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
.{
|
.{
|
||||||
.name = .ghostty,
|
.name = .ghostty,
|
||||||
.version = "1.2.0",
|
.version = "1.2.1",
|
||||||
.paths = .{""},
|
.paths = .{""},
|
||||||
.fingerprint = 0x64407a2a0b4147e5,
|
.fingerprint = 0x64407a2a0b4147e5,
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
@@ -45,6 +45,7 @@
|
|||||||
// codeberg ifreund/zig-wayland
|
// codeberg ifreund/zig-wayland
|
||||||
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
|
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
|
||||||
.hash = "wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
|
.hash = "wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.zf = .{
|
.zf = .{
|
||||||
// natecraddock/zf
|
// natecraddock/zf
|
||||||
@@ -55,8 +56,8 @@
|
|||||||
.gobject = .{
|
.gobject = .{
|
||||||
// https://github.com/jcollie/ghostty-gobject based on zig_gobject
|
// https://github.com/jcollie/ghostty-gobject based on zig_gobject
|
||||||
// Temporary until we generate them at build time automatically.
|
// Temporary until we generate them at build time automatically.
|
||||||
.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",
|
.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-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z",
|
.hash = "gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -103,17 +104,19 @@
|
|||||||
.jetbrains_mono = .{
|
.jetbrains_mono = .{
|
||||||
.url = "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz",
|
.url = "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz",
|
||||||
.hash = "N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x",
|
.hash = "N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.nerd_fonts_symbols_only = .{
|
.nerd_fonts_symbols_only = .{
|
||||||
.url = "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz",
|
.url = "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz",
|
||||||
.hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s",
|
.hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
.apple_sdk = .{ .path = "./pkg/apple-sdk" },
|
.apple_sdk = .{ .path = "./pkg/apple-sdk" },
|
||||||
.iterm2_themes = .{
|
.iterm2_themes = .{
|
||||||
.url = "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz",
|
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250916-134637-76894f0/ghostty-themes.tgz",
|
||||||
.hash = "N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B",
|
.hash = "N-V-__8AAGsjAwAxRB3Y9Akv_HeLfvJA-tIqW6ACnBhWosM3",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
12
build.zig.zon.json
generated
12
build.zig.zon.json
generated
@@ -24,10 +24,10 @@
|
|||||||
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
||||||
"hash": "sha256-FKLtu1Ccs+UamlPj9eQ12/WXFgS0uDPmPmB26MCpl7U="
|
"hash": "sha256-FKLtu1Ccs+UamlPj9eQ12/WXFgS0uDPmPmB26MCpl7U="
|
||||||
},
|
},
|
||||||
"gobject-0.3.0-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z": {
|
"gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV": {
|
||||||
"name": "gobject",
|
"name": "gobject",
|
||||||
"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",
|
"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-h6aKUerGlX2ATVEeoN03eWaqDqvUmKdedgpxrSoHvrY="
|
"hash": "sha256-SXiqGm81aUn6yq1wFXgNTAULdKOHS/Rzkp5OgNkkcXo="
|
||||||
},
|
},
|
||||||
"N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": {
|
"N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": {
|
||||||
"name": "gtk4_layer_shell",
|
"name": "gtk4_layer_shell",
|
||||||
@@ -49,10 +49,10 @@
|
|||||||
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
|
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
|
||||||
"hash": "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA="
|
"hash": "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA="
|
||||||
},
|
},
|
||||||
"N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B": {
|
"N-V-__8AAGsjAwAxRB3Y9Akv_HeLfvJA-tIqW6ACnBhWosM3": {
|
||||||
"name": "iterm2_themes",
|
"name": "iterm2_themes",
|
||||||
"url": "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz",
|
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250916-134637-76894f0/ghostty-themes.tgz",
|
||||||
"hash": "sha256-6rKNFpaUvSbvNZ0/+u0h4I/RRaV5V7xIPQ9y7eNVbCA="
|
"hash": "sha256-JPY9M50d/n6rGzWt0aQZIU7IBMWru2IAqe9Vu1x5CMw="
|
||||||
},
|
},
|
||||||
"N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x": {
|
"N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x": {
|
||||||
"name": "jetbrains_mono",
|
"name": "jetbrains_mono",
|
||||||
|
12
build.zig.zon.nix
generated
12
build.zig.zon.nix
generated
@@ -123,11 +123,11 @@ in
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name = "gobject-0.3.0-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z";
|
name = "gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV";
|
||||||
path = fetchZigArtifact {
|
path = fetchZigArtifact {
|
||||||
name = "gobject";
|
name = "gobject";
|
||||||
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";
|
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-h6aKUerGlX2ATVEeoN03eWaqDqvUmKdedgpxrSoHvrY=";
|
hash = "sha256-SXiqGm81aUn6yq1wFXgNTAULdKOHS/Rzkp5OgNkkcXo=";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -163,11 +163,11 @@ in
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name = "N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B";
|
name = "N-V-__8AAGsjAwAxRB3Y9Akv_HeLfvJA-tIqW6ACnBhWosM3";
|
||||||
path = fetchZigArtifact {
|
path = fetchZigArtifact {
|
||||||
name = "iterm2_themes";
|
name = "iterm2_themes";
|
||||||
url = "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz";
|
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250916-134637-76894f0/ghostty-themes.tgz";
|
||||||
hash = "sha256-6rKNFpaUvSbvNZ0/+u0h4I/RRaV5V7xIPQ9y7eNVbCA=";
|
hash = "sha256-JPY9M50d/n6rGzWt0aQZIU7IBMWru2IAqe9Vu1x5CMw=";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
4
build.zig.zon.txt
generated
4
build.zig.zon.txt
generated
@@ -8,7 +8,6 @@ https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918
|
|||||||
https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz
|
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/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz
|
||||||
https://deps.files.ghostty.org/gettext-0.24.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/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz
|
||||||
https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.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
|
https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz
|
||||||
@@ -28,7 +27,8 @@ https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d6
|
|||||||
https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.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/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz
|
||||||
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
|
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
|
||||||
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/ghostty-org/zig-gobject/releases/download/2025-09-20-20-1/ghostty-gobject-2025-09-20-20-1.tar.zst
|
||||||
|
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250916-134637-76894f0/ghostty-themes.tgz
|
||||||
https://github.com/mitchellh/libxev/archive/7f803181b158a10fec8619f793e3b4df515566cb.tar.gz
|
https://github.com/mitchellh/libxev/archive/7f803181b158a10fec8619f793e3b4df515566cb.tar.gz
|
||||||
https://github.com/mitchellh/zig-objc/archive/c9e917a4e15a983b672ca779c7985d738a2d517c.tar.gz
|
https://github.com/mitchellh/zig-objc/archive/c9e917a4e15a983b672ca779c7985d738a2d517c.tar.gz
|
||||||
https://github.com/natecraddock/zf/archive/7aacbe6d155d64d15937ca95ca6c014905eb531f.tar.gz
|
https://github.com/natecraddock/zf/archive/7aacbe6d155d64d15937ca95ca6c014905eb531f.tar.gz
|
||||||
|
189
example/app.ts
189
example/app.ts
@@ -1,189 +0,0 @@
|
|||||||
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);
|
|
||||||
});
|
|
17
example/c-vt/README.md
Normal file
17
example/c-vt/README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# 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
|
||||||
|
```
|
42
example/c-vt/build.zig
Normal file
42
example/c-vt/build.zig
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
|
||||||
|
const exe_mod = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
exe_mod.addCSourceFiles(.{
|
||||||
|
.root = b.path("src"),
|
||||||
|
.files = &.{"main.c"},
|
||||||
|
});
|
||||||
|
|
||||||
|
// You'll want to use a lazy dependency here so that ghostty is only
|
||||||
|
// downloaded if you actually need it.
|
||||||
|
if (b.lazyDependency("ghostty", .{
|
||||||
|
// Setting simd to false will force a pure static build that
|
||||||
|
// doesn't even require libc, but it has a significant performance
|
||||||
|
// penalty. If your embedding app requires libc anyway, you should
|
||||||
|
// always keep simd enabled.
|
||||||
|
// .simd = false,
|
||||||
|
})) |dep| {
|
||||||
|
exe_mod.linkLibrary(dep.artifact("ghostty-vt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exe
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "c_vt",
|
||||||
|
.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);
|
||||||
|
}
|
24
example/c-vt/build.zig.zon
Normal file
24
example/c-vt/build.zig.zon
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.{
|
||||||
|
.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",
|
||||||
|
},
|
||||||
|
}
|
11
example/c-vt/src/main.c
Normal file
11
example/c-vt/src/main.c
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <ghostty/vt.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
GhosttyOscParser parser;
|
||||||
|
if (ghostty_osc_new(NULL, &parser) != GHOSTTY_SUCCESS) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ghostty_osc_free(parser);
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -1,15 +0,0 @@
|
|||||||
<!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
4436
example/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
14
example/zig-vt/README.md
Normal file
14
example/zig-vt/README.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# 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
|
||||||
|
```
|
50
example/zig-vt/build.zig
Normal file
50
example/zig-vt/build.zig
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
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);
|
||||||
|
}
|
24
example/zig-vt/build.zig.zon
Normal file
24
example/zig-vt/build.zig.zon
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.{
|
||||||
|
.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",
|
||||||
|
},
|
||||||
|
}
|
26
example/zig-vt/src/main.zig
Normal file
26
example/zig-vt/src/main.zig
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755972213,
|
"lastModified": 1758360447,
|
||||||
"narHash": "sha256-VYK7aDAv8H1enXn1ECRHmGbeY6RqLnNwUJkOwloIsko=",
|
"narHash": "sha256-XDY3A83bclygHDtesRoaRTafUd80Q30D/Daf9KSG6bs=",
|
||||||
"rev": "73e96df7cff5783f45e21342a75a1540c4eddce4",
|
"rev": "8eaee110344796db060382e15d3af0a9fc396e0e",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://releases.nixos.org/nixos/unstable-small/nixos-25.11pre850642.73e96df7cff5/nixexprs.tar.xz"
|
"url": "https://releases.nixos.org/nixos/unstable/nixos-25.11pre864002.8eaee1103447/nixexprs.tar.xz"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://channels.nixos.org/nixos-unstable-small/nixexprs.tar.xz"
|
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
@@ -115,17 +115,17 @@
|
|||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1757167408,
|
"lastModified": 1758405547,
|
||||||
"narHash": "sha256-4XyJ6fmKd9wgJ7vHUQuULYy5ps2gUgkkDk/PrJb2OPY=",
|
"narHash": "sha256-WgaDgvIZMPvlZcZrpPMjkaalTBnGF2lTG+62znXctWM=",
|
||||||
"owner": "jcollie",
|
"owner": "jcollie",
|
||||||
"repo": "zon2nix",
|
"repo": "zon2nix",
|
||||||
"rev": "dc78177e2ad28d5a407c9e783ee781bd559d7dd5",
|
"rev": "bf983aa90ff169372b9fa8c02e57ea75e0b42245",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "jcollie",
|
"owner": "jcollie",
|
||||||
"repo": "zon2nix",
|
"repo": "zon2nix",
|
||||||
"rev": "dc78177e2ad28d5a407c9e783ee781bd559d7dd5",
|
"rev": "bf983aa90ff169372b9fa8c02e57ea75e0b42245",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
zon2nix = {
|
zon2nix = {
|
||||||
url = "github:jcollie/zon2nix?rev=dc78177e2ad28d5a407c9e783ee781bd559d7dd5";
|
url = "github:jcollie/zon2nix?rev=bf983aa90ff169372b9fa8c02e57ea75e0b42245";
|
||||||
inputs = {
|
inputs = {
|
||||||
# Don't override nixpkgs until Zig 0.15 is available in the Nix branch
|
# Don't override nixpkgs until Zig 0.15 is available in the Nix branch
|
||||||
# we are using for "normal" builds.
|
# we are using for "normal" builds.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
app-id: com.mitchellh.ghostty-debug
|
app-id: com.mitchellh.ghostty-debug
|
||||||
runtime: org.gnome.Platform
|
runtime: org.gnome.Platform
|
||||||
runtime-version: "48"
|
runtime-version: "49"
|
||||||
sdk: org.gnome.Sdk
|
sdk: org.gnome.Sdk
|
||||||
default-branch: tip
|
default-branch: tip
|
||||||
command: ghostty
|
command: ghostty
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
app-id: com.mitchellh.ghostty
|
app-id: com.mitchellh.ghostty
|
||||||
runtime: org.gnome.Platform
|
runtime: org.gnome.Platform
|
||||||
runtime-version: "48"
|
runtime-version: "49"
|
||||||
sdk: org.gnome.Sdk
|
sdk: org.gnome.Sdk
|
||||||
default-branch: tip
|
default-branch: tip
|
||||||
command: ghostty
|
command: ghostty
|
||||||
|
@@ -30,19 +30,6 @@ modules:
|
|||||||
contents: INPUT(libbz2.so)
|
contents: INPUT(libbz2.so)
|
||||||
dest-filename: libbzip2.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
|
- name: gtk4-layer-shell
|
||||||
buildsystem: meson
|
buildsystem: meson
|
||||||
sources:
|
sources:
|
||||||
|
@@ -31,9 +31,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"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",
|
"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-Skun7ET3nQAc0LzvO0NAvTiGGnmkF36cnmbeCAF6MB7Z",
|
"dest": "vendor/p/gobject-0.3.0-Skun7ET3nQCqJhDL0KnF_X7M4L7o7JePsJBbrYpEr7UV",
|
||||||
"sha256": "87a68a51eac6957d804d511ea0dd377966aa0eabd498a75e760a71ad2a07beb6"
|
"sha256": "4978aa1a6f356949facaad7015780d4c050b74a3874bf473929e4e80d924717a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
@@ -61,9 +61,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://deps.files.ghostty.org/ghostty-themes-20250915-162204-b1fe546.tgz",
|
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20250916-134637-76894f0/ghostty-themes.tgz",
|
||||||
"dest": "vendor/p/N-V-__8AANodAwDnyHwhlOv5cVRn2rx_dTvija-wy5YtTw1B",
|
"dest": "vendor/p/N-V-__8AAGsjAwAxRB3Y9Akv_HeLfvJA-tIqW6ACnBhWosM3",
|
||||||
"sha256": "eab28d169694bd26ef359d3ffaed21e08fd145a57957bc483d0f72ede3556c20"
|
"sha256": "24f63d339d1dfe7eab1b35add1a419214ec804c5abbb6200a9ef55bb5c7908cc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
|
221
include/ghostty/vt.h
Normal file
221
include/ghostty/vt.h
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
/**
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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.
|
||||||
|
*/
|
||||||
|
typedef struct GhosttyOscParser *GhosttyOscParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Allocator Interface
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GHOSTTY_VT_H */
|
@@ -10,146 +10,19 @@
|
|||||||
29C15B1D2CDC3B2900520DD4 /* bat in Resources */ = {isa = PBXBuildFile; fileRef = 29C15B1C2CDC3B2000520DD4 /* bat */; };
|
29C15B1D2CDC3B2900520DD4 /* bat in Resources */ = {isa = PBXBuildFile; fileRef = 29C15B1C2CDC3B2000520DD4 /* bat */; };
|
||||||
55154BE02B33911F001622DC /* ghostty in Resources */ = {isa = PBXBuildFile; fileRef = 55154BDF2B33911F001622DC /* ghostty */; };
|
55154BE02B33911F001622DC /* ghostty in Resources */ = {isa = PBXBuildFile; fileRef = 55154BDF2B33911F001622DC /* ghostty */; };
|
||||||
552964E62B34A9B400030505 /* vim in Resources */ = {isa = PBXBuildFile; fileRef = 552964E52B34A9B400030505 /* vim */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
A553F4132E06EB1600257779 /* Ghostty.icon in Resources */ = {isa = PBXBuildFile; fileRef = A553F4122E06EB1600257779 /* Ghostty.icon */; };
|
||||||
A553F4142E06EB1600257779 /* 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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
|
||||||
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 */; };
|
FC5218FA2D10FFCE004C93E0 /* zsh in Resources */ = {isa = PBXBuildFile; fileRef = FC5218F92D10FFC7004C93E0 /* zsh */; };
|
||||||
FC9ABA9C2D0F53F80020D4C8 /* bash-completion in Resources */ = {isa = PBXBuildFile; fileRef = FC9ABA9B2D0F538D0020D4C8 /* bash-completion */; };
|
FC9ABA9C2D0F53F80020D4C8 /* bash-completion in Resources */ = {isa = PBXBuildFile; fileRef = FC9ABA9B2D0F538D0020D4C8 /* bash-completion */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
@@ -169,143 +42,144 @@
|
|||||||
3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GhosttyReleaseLocal.entitlements; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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; };
|
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; };
|
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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; };
|
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>"; };
|
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>"; };
|
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; };
|
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>"; };
|
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>"; };
|
|
||||||
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>"; };
|
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>"; };
|
FC9ABA9B2D0F538D0020D4C8 /* bash-completion */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "bash-completion"; path = "../zig-out/share/bash-completion"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* 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/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 */
|
/* 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>"; };
|
A54F45F42E1F047A0046BD5C /* Tests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Tests; sourceTree = "<group>"; };
|
||||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
|
||||||
@@ -338,256 +212,6 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup 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 */,
|
|
||||||
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 */ = {
|
A5A1F8862A489D7400D1E8BC /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -614,7 +238,7 @@
|
|||||||
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */,
|
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */,
|
||||||
A51BFC282B30F26D00E92F16 /* GhosttyDebug.entitlements */,
|
A51BFC282B30F26D00E92F16 /* GhosttyDebug.entitlements */,
|
||||||
3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */,
|
3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */,
|
||||||
A54CD6ED299BEB14008C95BB /* Sources */,
|
81F82BC72E82815D001EDFA7 /* Sources */,
|
||||||
A54F45F42E1F047A0046BD5C /* Tests */,
|
A54F45F42E1F047A0046BD5C /* Tests */,
|
||||||
A5D495A3299BECBA00DD1313 /* Frameworks */,
|
A5D495A3299BECBA00DD1313 /* Frameworks */,
|
||||||
A5A1F8862A489D7400D1E8BC /* Resources */,
|
A5A1F8862A489D7400D1E8BC /* Resources */,
|
||||||
@@ -632,28 +256,6 @@
|
|||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
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 */ = {
|
A5D495A3299BECBA00DD1313 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -663,42 +265,6 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
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 */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
@@ -737,6 +303,9 @@
|
|||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
81F82BC72E82815D001EDFA7 /* Sources */,
|
||||||
|
);
|
||||||
name = Ghostty;
|
name = Ghostty;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
A51BFC262B30F1B800E92F16 /* Sparkle */,
|
A51BFC262B30F1B800E92F16 /* Sparkle */,
|
||||||
@@ -757,6 +326,9 @@
|
|||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
81F82BC72E82815D001EDFA7 /* Sources */,
|
||||||
|
);
|
||||||
name = "Ghostty-iOS";
|
name = "Ghostty-iOS";
|
||||||
productName = "Ghostty-iOS";
|
productName = "Ghostty-iOS";
|
||||||
productReference = A5D4499D2B53AE7B000F5B83 /* Ghostty-iOS.app */;
|
productReference = A5D4499D2B53AE7B000F5B83 /* Ghostty-iOS.app */;
|
||||||
@@ -822,11 +394,9 @@
|
|||||||
files = (
|
files = (
|
||||||
FC9ABA9C2D0F53F80020D4C8 /* bash-completion in Resources */,
|
FC9ABA9C2D0F53F80020D4C8 /* bash-completion in Resources */,
|
||||||
A553F4142E06EB1600257779 /* Ghostty.icon in Resources */,
|
A553F4142E06EB1600257779 /* Ghostty.icon in Resources */,
|
||||||
A5593FE52DF8DE3000B47B10 /* TerminalTabsTitlebarVentura.xib in Resources */,
|
|
||||||
29C15B1D2CDC3B2900520DD4 /* bat in Resources */,
|
29C15B1D2CDC3B2900520DD4 /* bat in Resources */,
|
||||||
A586167C2B7703CC009BDB1D /* fish in Resources */,
|
A586167C2B7703CC009BDB1D /* fish in Resources */,
|
||||||
55154BE02B33911F001622DC /* ghostty in Resources */,
|
55154BE02B33911F001622DC /* ghostty in Resources */,
|
||||||
A5593FE32DF8D78600B47B10 /* TerminalHiddenTitlebar.xib in Resources */,
|
|
||||||
A546F1142D7B68D7003B11A0 /* locale in Resources */,
|
A546F1142D7B68D7003B11A0 /* locale in Resources */,
|
||||||
A5985CE62C33060F00C57AD3 /* man in Resources */,
|
A5985CE62C33060F00C57AD3 /* man in Resources */,
|
||||||
9351BE8E3D22937F003B3499 /* nvim in Resources */,
|
9351BE8E3D22937F003B3499 /* nvim in Resources */,
|
||||||
@@ -834,14 +404,6 @@
|
|||||||
552964E62B34A9B400030505 /* vim in Resources */,
|
552964E62B34A9B400030505 /* vim in Resources */,
|
||||||
FC5218FA2D10FFCE004C93E0 /* zsh in Resources */,
|
FC5218FA2D10FFCE004C93E0 /* zsh in Resources */,
|
||||||
A5B30539299BEAAB0047F10C /* Assets.xcassets 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;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -868,112 +430,6 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
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 */,
|
|
||||||
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;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -981,20 +437,6 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
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;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@@ -860,6 +860,11 @@ class AppDelegate: NSObject,
|
|||||||
} else {
|
} else {
|
||||||
GlobalEventTap.shared.disable()
|
GlobalEventTap.shared.disable()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sync the appearance of our app with the theme specified in the config.
|
||||||
|
private func syncAppearance(config: Ghostty.Config) {
|
||||||
|
NSApplication.shared.appearance = .init(ghosttyConfig: config)
|
||||||
|
|
||||||
switch (config.macosIcon) {
|
switch (config.macosIcon) {
|
||||||
case .official:
|
case .official:
|
||||||
@@ -909,11 +914,6 @@ class AppDelegate: NSObject,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sync the appearance of our app with the theme specified in the config.
|
|
||||||
private func syncAppearance(config: Ghostty.Config) {
|
|
||||||
NSApplication.shared.appearance = .init(ghosttyConfig: config)
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - Restorable State
|
//MARK: - Restorable State
|
||||||
|
|
||||||
/// We support NSSecureCoding for restorable state. Required as of macOS Sonoma (14) but a good idea anyways.
|
/// We support NSSecureCoding for restorable state. Required as of macOS Sonoma (14) but a good idea anyways.
|
||||||
|
@@ -123,7 +123,8 @@ struct NewTerminalIntent: AppIntent {
|
|||||||
|
|
||||||
if let view = controller.newSplit(
|
if let view = controller.newSplit(
|
||||||
at: parent,
|
at: parent,
|
||||||
direction: location.splitDirection!
|
direction: location.splitDirection!,
|
||||||
|
baseConfig: config
|
||||||
) {
|
) {
|
||||||
return .result(value: TerminalEntity(view))
|
return .result(value: TerminalEntity(view))
|
||||||
}
|
}
|
||||||
|
@@ -21,13 +21,13 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
// The active space when the quick terminal was last shown.
|
// The active space when the quick terminal was last shown.
|
||||||
private var previousActiveSpace: CGSSpace? = nil
|
private var previousActiveSpace: CGSSpace? = nil
|
||||||
|
|
||||||
/// The window frame saved when the quick terminal's surface tree becomes empty.
|
/// The saved state when the quick terminal's surface tree becomes empty.
|
||||||
///
|
///
|
||||||
/// This preserves the user's window size and position when all terminal surfaces
|
/// This preserves the user's window size and position when all terminal surfaces
|
||||||
/// are closed (e.g., via the `exit` command). When a new surface is created,
|
/// are closed (e.g., via the `exit` command). When a new surface is created,
|
||||||
/// the window will be restored to this frame, preventing SwiftUI from resetting
|
/// the window will be restored to this frame, preventing SwiftUI from resetting
|
||||||
/// the window to its default minimum size.
|
/// the window to its default minimum size.
|
||||||
private var lastClosedFrame: NSRect? = nil
|
private var lastClosedFrames: NSMapTable<NSScreen, LastClosedState>
|
||||||
|
|
||||||
/// Non-nil if we have hidden dock state.
|
/// Non-nil if we have hidden dock state.
|
||||||
private var hiddenDock: HiddenDock? = nil
|
private var hiddenDock: HiddenDock? = nil
|
||||||
@@ -46,6 +46,10 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
self.position = position
|
self.position = position
|
||||||
self.derivedConfig = DerivedConfig(ghostty.config)
|
self.derivedConfig = DerivedConfig(ghostty.config)
|
||||||
|
|
||||||
|
// This is a weak to strong mapping, so that our keys being NSScreens
|
||||||
|
// can remove themselves when they disappear.
|
||||||
|
self.lastClosedFrames = .weakToStrongObjects()
|
||||||
|
|
||||||
// Important detail here: we initialize with an empty surface tree so
|
// Important detail here: we initialize with an empty surface tree so
|
||||||
// that we don't start a terminal process. This gets started when the
|
// that we don't start a terminal process. This gets started when the
|
||||||
// first terminal is shown in `animateIn`.
|
// first terminal is shown in `animateIn`.
|
||||||
@@ -360,8 +364,9 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
guard let screen = derivedConfig.quickTerminalScreen.screen else { return }
|
guard let screen = derivedConfig.quickTerminalScreen.screen else { return }
|
||||||
|
|
||||||
// Grab our last closed frame to use, and clear our state since we're animating in.
|
// Grab our last closed frame to use, and clear our state since we're animating in.
|
||||||
let lastClosedFrame = self.lastClosedFrame
|
// We only use the last closed frame if we're opening on the same screen.
|
||||||
self.lastClosedFrame = nil
|
let lastClosedFrame: NSRect? = lastClosedFrames.object(forKey: screen)?.frame
|
||||||
|
lastClosedFrames.removeObject(forKey: screen)
|
||||||
|
|
||||||
// Move our window off screen to the initial animation position.
|
// Move our window off screen to the initial animation position.
|
||||||
position.setInitial(
|
position.setInitial(
|
||||||
@@ -491,8 +496,8 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
// the user's preferred window size and position for when the quick
|
// the user's preferred window size and position for when the quick
|
||||||
// terminal is reactivated with a new surface. Without this, SwiftUI
|
// terminal is reactivated with a new surface. Without this, SwiftUI
|
||||||
// would reset the window to its minimum content size.
|
// would reset the window to its minimum content size.
|
||||||
if window.frame.width > 0 && window.frame.height > 0 {
|
if window.frame.width > 0 && window.frame.height > 0, let screen = window.screen {
|
||||||
lastClosedFrame = window.frame
|
lastClosedFrames.setObject(.init(frame: window.frame), forKey: screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we hid the dock then we unhide it.
|
// If we hid the dock then we unhide it.
|
||||||
@@ -715,6 +720,14 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
hidden = false
|
hidden = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class LastClosedState {
|
||||||
|
let frame: NSRect
|
||||||
|
|
||||||
|
init(frame: NSRect) {
|
||||||
|
self.frame = frame
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Notification.Name {
|
extension Notification.Name {
|
||||||
|
@@ -55,7 +55,10 @@ class ServiceProvider: NSObject {
|
|||||||
_ = TerminalController.newWindow(delegate.ghostty, withBaseConfig: config)
|
_ = TerminalController.newWindow(delegate.ghostty, withBaseConfig: config)
|
||||||
|
|
||||||
case .tab:
|
case .tab:
|
||||||
_ = TerminalController.newTab(delegate.ghostty, withBaseConfig: config)
|
_ = TerminalController.newTab(
|
||||||
|
delegate.ghostty,
|
||||||
|
from: TerminalController.preferredParent?.window,
|
||||||
|
withBaseConfig: config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -688,6 +688,8 @@ class BaseTerminalController: NSWindowController,
|
|||||||
surfaceTree.contains(titleSurface) {
|
surfaceTree.contains(titleSurface) {
|
||||||
// If we have a surface, we want to listen for title changes.
|
// If we have a surface, we want to listen for title changes.
|
||||||
titleSurface.$title
|
titleSurface.$title
|
||||||
|
.combineLatest(titleSurface.$bell)
|
||||||
|
.map { [weak self] in self?.computeTitle(title: $0, bell: $1) ?? "" }
|
||||||
.sink { [weak self] in self?.titleDidChange(to: $0) }
|
.sink { [weak self] in self?.titleDidChange(to: $0) }
|
||||||
.store(in: &focusedSurfaceCancellables)
|
.store(in: &focusedSurfaceCancellables)
|
||||||
} else {
|
} else {
|
||||||
@@ -696,7 +698,16 @@ class BaseTerminalController: NSWindowController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func titleDidChange(to: String) {
|
private func computeTitle(title: String, bell: Bool) -> String {
|
||||||
|
var result = title
|
||||||
|
if (bell && ghostty.config.bellFeatures.contains(.title)) {
|
||||||
|
result = "🔔 \(result)"
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private func titleDidChange(to: String) {
|
||||||
guard let window else { return }
|
guard let window else { return }
|
||||||
|
|
||||||
// Set the main window title
|
// Set the main window title
|
||||||
@@ -863,14 +874,6 @@ class BaseTerminalController: NSWindowController,
|
|||||||
// Everything beyond here is setting up the window
|
// Everything beyond here is setting up the window
|
||||||
guard let window else { return }
|
guard let window else { return }
|
||||||
|
|
||||||
// If there is a hardcoded title in the configuration, we set that
|
|
||||||
// immediately. Future `set_title` apprt actions will override this
|
|
||||||
// if necessary but this ensures our window loads with the proper
|
|
||||||
// title immediately rather than on another event loop tick (see #5934)
|
|
||||||
if let title = derivedConfig.title {
|
|
||||||
window.title = title
|
|
||||||
}
|
|
||||||
|
|
||||||
// We always initialize our fullscreen style to native if we can because
|
// We always initialize our fullscreen style to native if we can because
|
||||||
// initialization sets up some state (i.e. observers). If its set already
|
// initialization sets up some state (i.e. observers). If its set already
|
||||||
// somehow we don't do this.
|
// somehow we don't do this.
|
||||||
@@ -1072,20 +1075,17 @@ class BaseTerminalController: NSWindowController,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private struct DerivedConfig {
|
private struct DerivedConfig {
|
||||||
let title: String?
|
|
||||||
let macosTitlebarProxyIcon: Ghostty.MacOSTitlebarProxyIcon
|
let macosTitlebarProxyIcon: Ghostty.MacOSTitlebarProxyIcon
|
||||||
let windowStepResize: Bool
|
let windowStepResize: Bool
|
||||||
let focusFollowsMouse: Bool
|
let focusFollowsMouse: Bool
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
self.title = nil
|
|
||||||
self.macosTitlebarProxyIcon = .visible
|
self.macosTitlebarProxyIcon = .visible
|
||||||
self.windowStepResize = false
|
self.windowStepResize = false
|
||||||
self.focusFollowsMouse = false
|
self.focusFollowsMouse = false
|
||||||
}
|
}
|
||||||
|
|
||||||
init(_ config: Ghostty.Config) {
|
init(_ config: Ghostty.Config) {
|
||||||
self.title = config.title
|
|
||||||
self.macosTitlebarProxyIcon = config.macosTitlebarProxyIcon
|
self.macosTitlebarProxyIcon = config.macosTitlebarProxyIcon
|
||||||
self.windowStepResize = config.windowStepResize
|
self.windowStepResize = config.windowStepResize
|
||||||
self.focusFollowsMouse = config.focusFollowsMouse
|
self.focusFollowsMouse = config.focusFollowsMouse
|
||||||
|
@@ -184,9 +184,15 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr
|
|||||||
static var preferredParent: TerminalController? {
|
static var preferredParent: TerminalController? {
|
||||||
all.first {
|
all.first {
|
||||||
$0.window?.isMainWindow ?? false
|
$0.window?.isMainWindow ?? false
|
||||||
} ?? all.last
|
} ?? lastMain ?? all.last
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The last controller to be main. We use this when paired with "preferredParent"
|
||||||
|
// to find the preferred window to attach new tabs, perform actions, etc. We
|
||||||
|
// always prefer the main window but if there isn't any (because we're triggered
|
||||||
|
// by something like an App Intent) then we prefer the most previous main.
|
||||||
|
static private(set) weak var lastMain: TerminalController? = nil
|
||||||
|
|
||||||
/// The "new window" action.
|
/// The "new window" action.
|
||||||
static func newWindow(
|
static func newWindow(
|
||||||
_ ghostty: Ghostty.App,
|
_ ghostty: Ghostty.App,
|
||||||
@@ -1036,6 +1042,9 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr
|
|||||||
if let window {
|
if let window {
|
||||||
LastWindowPosition.shared.save(window)
|
LastWindowPosition.shared.save(window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remember our last main
|
||||||
|
Self.lastMain = self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the window will be encoded. We handle the data encoding here in the
|
// Called when the window will be encoded. We handle the data encoding here in the
|
||||||
|
@@ -50,6 +50,14 @@ class TerminalWindow: NSWindow {
|
|||||||
// Setup our initial config
|
// Setup our initial config
|
||||||
derivedConfig = .init(config)
|
derivedConfig = .init(config)
|
||||||
|
|
||||||
|
// If there is a hardcoded title in the configuration, we set that
|
||||||
|
// immediately. Future `set_title` apprt actions will override this
|
||||||
|
// if necessary but this ensures our window loads with the proper
|
||||||
|
// title immediately rather than on another event loop tick (see #5934)
|
||||||
|
if let title = derivedConfig.title {
|
||||||
|
self.title = title
|
||||||
|
}
|
||||||
|
|
||||||
// If window decorations are disabled, remove our title
|
// If window decorations are disabled, remove our title
|
||||||
if (!config.windowDecorations) { styleMask.remove(.titled) }
|
if (!config.windowDecorations) { styleMask.remove(.titled) }
|
||||||
|
|
||||||
@@ -408,11 +416,19 @@ class TerminalWindow: NSWindow {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Orient based on the top left of the primary monitor
|
// Convert top-left coordinates to bottom-left origin using our utility extension
|
||||||
let frame = screen.visibleFrame
|
let origin = screen.origin(
|
||||||
setFrameOrigin(.init(
|
fromTopLeftOffsetX: CGFloat(x),
|
||||||
x: frame.minX + CGFloat(x),
|
offsetY: CGFloat(y),
|
||||||
y: frame.maxY - (CGFloat(y) + frame.height)))
|
windowSize: frame.size)
|
||||||
|
|
||||||
|
// Clamp the origin to ensure the window stays fully visible on screen
|
||||||
|
var safeOrigin = origin
|
||||||
|
let vf = screen.visibleFrame
|
||||||
|
safeOrigin.x = min(max(safeOrigin.x, vf.minX), vf.maxX - frame.width)
|
||||||
|
safeOrigin.y = min(max(safeOrigin.y, vf.minY), vf.maxY - frame.height)
|
||||||
|
|
||||||
|
setFrameOrigin(safeOrigin)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func hideWindowButtons() {
|
private func hideWindowButtons() {
|
||||||
@@ -424,17 +440,20 @@ class TerminalWindow: NSWindow {
|
|||||||
// MARK: Config
|
// MARK: Config
|
||||||
|
|
||||||
struct DerivedConfig {
|
struct DerivedConfig {
|
||||||
|
let title: String?
|
||||||
let backgroundColor: NSColor
|
let backgroundColor: NSColor
|
||||||
let backgroundOpacity: Double
|
let backgroundOpacity: Double
|
||||||
let macosWindowButtons: Ghostty.MacOSWindowButtons
|
let macosWindowButtons: Ghostty.MacOSWindowButtons
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
self.title = nil
|
||||||
self.backgroundColor = NSColor.windowBackgroundColor
|
self.backgroundColor = NSColor.windowBackgroundColor
|
||||||
self.backgroundOpacity = 1
|
self.backgroundOpacity = 1
|
||||||
self.macosWindowButtons = .visible
|
self.macosWindowButtons = .visible
|
||||||
}
|
}
|
||||||
|
|
||||||
init(_ config: Ghostty.Config) {
|
init(_ config: Ghostty.Config) {
|
||||||
|
self.title = config.title
|
||||||
self.backgroundColor = NSColor(config.backgroundColor)
|
self.backgroundColor = NSColor(config.backgroundColor)
|
||||||
self.backgroundOpacity = config.backgroundOpacity
|
self.backgroundOpacity = config.backgroundOpacity
|
||||||
self.macosWindowButtons = config.macosWindowButtons
|
self.macosWindowButtons = config.macosWindowButtons
|
||||||
|
@@ -99,10 +99,13 @@ extension Ghostty.Action {
|
|||||||
|
|
||||||
let state: State
|
let state: State
|
||||||
let progress: UInt8?
|
let progress: UInt8?
|
||||||
|
}
|
||||||
init(c: ghostty_action_progress_report_s) {
|
}
|
||||||
self.state = State(c.state)
|
|
||||||
self.progress = c.progress >= 0 ? UInt8(c.progress) : nil
|
// Putting the initializer in an extension preserves the automatic one.
|
||||||
}
|
extension Ghostty.Action.ProgressReport {
|
||||||
|
init(c: ghostty_action_progress_report_s) {
|
||||||
|
self.state = State(c.state)
|
||||||
|
self.progress = c.progress >= 0 ? UInt8(c.progress) : nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -624,10 +624,15 @@ extension Ghostty {
|
|||||||
) -> Bool {
|
) -> Bool {
|
||||||
let action = Ghostty.Action.OpenURL(c: v)
|
let action = Ghostty.Action.OpenURL(c: v)
|
||||||
|
|
||||||
// Convert the URL string to a URL object
|
// If the URL doesn't have a valid scheme we assume its a file path. The URL
|
||||||
guard let url = URL(string: action.url) else {
|
// initializer will gladly take invalid URLs (e.g. plain file paths) and turn
|
||||||
Ghostty.logger.warning("invalid URL for open URL action: \(action.url)")
|
// them into schema-less URLs, but these won't open properly in text editors.
|
||||||
return false
|
// See: https://github.com/ghostty-org/ghostty/issues/8763
|
||||||
|
let url: URL
|
||||||
|
if let candidate = URL(string: action.url), candidate.scheme != nil {
|
||||||
|
url = candidate
|
||||||
|
} else {
|
||||||
|
url = URL(filePath: action.url)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch action.kind {
|
switch action.kind {
|
||||||
|
@@ -625,6 +625,7 @@ extension Ghostty.Config {
|
|||||||
static let audio = BellFeatures(rawValue: 1 << 1)
|
static let audio = BellFeatures(rawValue: 1 << 1)
|
||||||
static let attention = BellFeatures(rawValue: 1 << 2)
|
static let attention = BellFeatures(rawValue: 1 << 2)
|
||||||
static let title = BellFeatures(rawValue: 1 << 3)
|
static let title = BellFeatures(rawValue: 1 << 3)
|
||||||
|
static let border = BellFeatures(rawValue: 1 << 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MacDockDropBehavior: String {
|
enum MacDockDropBehavior: String {
|
||||||
|
113
macos/Sources/Ghostty/SurfaceProgressBar.swift
Normal file
113
macos/Sources/Ghostty/SurfaceProgressBar.swift
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
/// The progress bar to show a surface progress report. We implement this from scratch because the
|
||||||
|
/// standard ProgressView is broken on macOS 26 and this is simple anyways and gives us a ton of
|
||||||
|
/// control.
|
||||||
|
struct SurfaceProgressBar: View {
|
||||||
|
let report: Ghostty.Action.ProgressReport
|
||||||
|
|
||||||
|
private var color: Color {
|
||||||
|
switch report.state {
|
||||||
|
case .error: return .red
|
||||||
|
case .pause: return .orange
|
||||||
|
default: return .accentColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var progress: UInt8? {
|
||||||
|
// If we have an explicit progress use that.
|
||||||
|
if let v = report.progress { return v }
|
||||||
|
|
||||||
|
// Otherwise, if we're in the pause state, we act as if we're at 100%.
|
||||||
|
if report.state == .pause { return 100 }
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private var accessibilityLabel: String {
|
||||||
|
switch report.state {
|
||||||
|
case .error: return "Terminal progress - Error"
|
||||||
|
case .pause: return "Terminal progress - Paused"
|
||||||
|
case .indeterminate: return "Terminal progress - In progress"
|
||||||
|
default: return "Terminal progress"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var accessibilityValue: String {
|
||||||
|
if let progress {
|
||||||
|
return "\(progress) percent complete"
|
||||||
|
} else {
|
||||||
|
switch report.state {
|
||||||
|
case .error: return "Operation failed"
|
||||||
|
case .pause: return "Operation paused at completion"
|
||||||
|
case .indeterminate: return "Operation in progress"
|
||||||
|
default: return "Indeterminate progress"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
GeometryReader { geometry in
|
||||||
|
ZStack(alignment: .leading) {
|
||||||
|
if let progress {
|
||||||
|
// Determinate progress bar with specific percentage
|
||||||
|
Rectangle()
|
||||||
|
.fill(color)
|
||||||
|
.frame(
|
||||||
|
width: geometry.size.width * CGFloat(progress) / 100,
|
||||||
|
height: geometry.size.height
|
||||||
|
)
|
||||||
|
.animation(.easeInOut(duration: 0.2), value: progress)
|
||||||
|
} else {
|
||||||
|
// Indeterminate states without specific progress - all use bouncing animation
|
||||||
|
BouncingProgressBar(color: color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(height: 2)
|
||||||
|
.clipped()
|
||||||
|
.allowsHitTesting(false)
|
||||||
|
.accessibilityElement(children: .ignore)
|
||||||
|
.accessibilityAddTraits(.updatesFrequently)
|
||||||
|
.accessibilityLabel(accessibilityLabel)
|
||||||
|
.accessibilityValue(accessibilityValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bouncing progress bar for indeterminate states
|
||||||
|
private struct BouncingProgressBar: View {
|
||||||
|
let color: Color
|
||||||
|
@State private var position: CGFloat = 0
|
||||||
|
|
||||||
|
private let barWidthRatio: CGFloat = 0.25
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
GeometryReader { geometry in
|
||||||
|
ZStack(alignment: .leading) {
|
||||||
|
Rectangle()
|
||||||
|
.fill(color.opacity(0.3))
|
||||||
|
|
||||||
|
Rectangle()
|
||||||
|
.fill(color)
|
||||||
|
.frame(
|
||||||
|
width: geometry.size.width * barWidthRatio,
|
||||||
|
height: geometry.size.height
|
||||||
|
)
|
||||||
|
.offset(x: position * (geometry.size.width * (1 - barWidthRatio)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
withAnimation(
|
||||||
|
.easeInOut(duration: 1.2)
|
||||||
|
.repeatForever(autoreverses: true)
|
||||||
|
) {
|
||||||
|
position = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onDisappear {
|
||||||
|
position = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@@ -57,15 +57,6 @@ extension Ghostty {
|
|||||||
|
|
||||||
@EnvironmentObject private var ghostty: Ghostty.App
|
@EnvironmentObject private var ghostty: Ghostty.App
|
||||||
|
|
||||||
var title: String {
|
|
||||||
var result = surfaceView.title
|
|
||||||
if (surfaceView.bell && ghostty.config.bellFeatures.contains(.title)) {
|
|
||||||
result = "🔔 \(result)"
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
let center = NotificationCenter.default
|
let center = NotificationCenter.default
|
||||||
|
|
||||||
@@ -114,9 +105,15 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
.ghosttySurfaceView(surfaceView)
|
.ghosttySurfaceView(surfaceView)
|
||||||
|
|
||||||
// Progress report overlay
|
// Progress report
|
||||||
if let progressReport = surfaceView.progressReport {
|
if let progressReport = surfaceView.progressReport, progressReport.state != .remove {
|
||||||
ProgressReportOverlay(report: progressReport)
|
VStack(spacing: 0) {
|
||||||
|
SurfaceProgressBar(report: progressReport)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||||
|
.allowsHitTesting(false)
|
||||||
|
.transition(.opacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if canImport(AppKit)
|
#if canImport(AppKit)
|
||||||
@@ -202,6 +199,11 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Show bell border if enabled
|
||||||
|
if (ghostty.config.bellFeatures.contains(.border)) {
|
||||||
|
BellBorderOverlay(bell: surfaceView.bell)
|
||||||
|
}
|
||||||
|
|
||||||
// If our surface is not healthy, then we render an error view over it.
|
// If our surface is not healthy, then we render an error view over it.
|
||||||
if (!surfaceView.healthy) {
|
if (!surfaceView.healthy) {
|
||||||
Rectangle().fill(ghostty.config.backgroundColor)
|
Rectangle().fill(ghostty.config.backgroundColor)
|
||||||
@@ -272,48 +274,7 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Progress report overlay that shows a progress bar at the top of the terminal
|
|
||||||
struct ProgressReportOverlay: View {
|
|
||||||
let report: Action.ProgressReport
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var progressBar: some View {
|
|
||||||
if let progress = report.progress {
|
|
||||||
// Determinate progress bar
|
|
||||||
ProgressView(value: Double(progress), total: 100)
|
|
||||||
.progressViewStyle(.linear)
|
|
||||||
.tint(report.state == .error ? .red : report.state == .pause ? .orange : nil)
|
|
||||||
.animation(.easeInOut(duration: 0.2), value: progress)
|
|
||||||
} else {
|
|
||||||
// Indeterminate states
|
|
||||||
switch report.state {
|
|
||||||
case .indeterminate:
|
|
||||||
ProgressView()
|
|
||||||
.progressViewStyle(.linear)
|
|
||||||
case .error:
|
|
||||||
ProgressView()
|
|
||||||
.progressViewStyle(.linear)
|
|
||||||
.tint(.red)
|
|
||||||
case .pause:
|
|
||||||
Rectangle().fill(Color.orange)
|
|
||||||
default:
|
|
||||||
EmptyView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack(spacing: 0) {
|
|
||||||
progressBar
|
|
||||||
.scaleEffect(x: 1, y: 0.5, anchor: .center)
|
|
||||||
.frame(height: 2)
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
|
||||||
.allowsHitTesting(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the resize overlay that shows on top of a surface to show the current
|
// This is the resize overlay that shows on top of a surface to show the current
|
||||||
// size during a resize operation.
|
// size during a resize operation.
|
||||||
@@ -570,6 +531,22 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Visual overlay that shows a border around the edges when the bell rings with border feature enabled.
|
||||||
|
struct BellBorderOverlay: View {
|
||||||
|
let bell: Bool
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Rectangle()
|
||||||
|
.strokeBorder(
|
||||||
|
Color(red: 1.0, green: 0.8, blue: 0.0).opacity(0.5),
|
||||||
|
lineWidth: 3
|
||||||
|
)
|
||||||
|
.allowsHitTesting(false)
|
||||||
|
.opacity(bell ? 1.0 : 0.0)
|
||||||
|
.animation(.easeInOut(duration: 0.3), value: bell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if canImport(AppKit)
|
#if canImport(AppKit)
|
||||||
/// When changing the split state, or going full screen (native or non), the terminal view
|
/// When changing the split state, or going full screen (native or non), the terminal view
|
||||||
/// will lose focus. There has to be some nice SwiftUI-native way to fix this but I can't
|
/// will lose focus. There has to be some nice SwiftUI-native way to fix this but I can't
|
||||||
|
@@ -1815,18 +1815,39 @@ extension Ghostty.SurfaceView: NSServicesMenuRequestor {
|
|||||||
forSendType sendType: NSPasteboard.PasteboardType?,
|
forSendType sendType: NSPasteboard.PasteboardType?,
|
||||||
returnType: NSPasteboard.PasteboardType?
|
returnType: NSPasteboard.PasteboardType?
|
||||||
) -> Any? {
|
) -> Any? {
|
||||||
// Types that we accept sent to us
|
// This function confused me a bit so I'm going to add my own commentary on
|
||||||
let accepted: [NSPasteboard.PasteboardType] = [.string, .init("public.utf8-plain-text")]
|
// how this works. macOS sends this callback with the given send/return types and
|
||||||
|
// we must return the responder capable of handling the COMBINATION of those send
|
||||||
|
// and return types (or super up if we can't handle it).
|
||||||
|
//
|
||||||
|
// The "COMBINATION" bit is key: we might get sent a string (we can handle that)
|
||||||
|
// but get requested an image (we can't handle that at the time of writing this),
|
||||||
|
// so we must bubble up.
|
||||||
|
|
||||||
// We can always receive the accepted types
|
// Types we can receive
|
||||||
if (returnType == nil || accepted.contains(returnType!)) {
|
let receivable: [NSPasteboard.PasteboardType] = [.string, .init("public.utf8-plain-text")]
|
||||||
return self
|
|
||||||
}
|
// Types that we can send. Currently the same as receivable but I'm separating
|
||||||
|
// this out so we can modify this in the future.
|
||||||
|
let sendable: [NSPasteboard.PasteboardType] = receivable
|
||||||
|
|
||||||
|
// The sendable types that require a selection (currently all)
|
||||||
|
let sendableRequiresSelection = sendable
|
||||||
|
|
||||||
|
// If we expect no data to be sent/received we can obviously handle it (that's
|
||||||
|
// the nil check), otherwise it must conform to the types we support on both sides.
|
||||||
|
if (returnType == nil || receivable.contains(returnType!)) &&
|
||||||
|
(sendType == nil || sendable.contains(sendType!)) {
|
||||||
|
// If we're expected to send back a type that requires selection, then
|
||||||
|
// verify that we have a selection. We do this within this block because
|
||||||
|
// validateRequestor is called a LOT and we want to prevent unnecessary
|
||||||
|
// performance hits because `ghostty_surface_has_selection` isn't free.
|
||||||
|
if let sendType, sendableRequiresSelection.contains(sendType) {
|
||||||
|
if surface == nil || !ghostty_surface_has_selection(surface) {
|
||||||
|
return super.validRequestor(forSendType: sendType, returnType: returnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we have a selection we can send the accepted types too
|
|
||||||
if ((self.surface != nil && ghostty_surface_has_selection(self.surface)) &&
|
|
||||||
(sendType == nil || accepted.contains(sendType!))
|
|
||||||
) {
|
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,4 +41,20 @@ extension NSScreen {
|
|||||||
// know any other situation this is true.
|
// know any other situation this is true.
|
||||||
return safeAreaInsets.top > 0
|
return safeAreaInsets.top > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts top-left offset coordinates to bottom-left origin coordinates for window positioning.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - x: X offset from top-left corner
|
||||||
|
/// - y: Y offset from top-left corner
|
||||||
|
/// - windowSize: Size of the window to be positioned
|
||||||
|
/// - Returns: CGPoint suitable for setFrameOrigin that positions the window as requested
|
||||||
|
func origin(fromTopLeftOffsetX x: CGFloat, offsetY y: CGFloat, windowSize: CGSize) -> CGPoint {
|
||||||
|
let vf = visibleFrame
|
||||||
|
|
||||||
|
// Convert top-left coordinates to bottom-left origin
|
||||||
|
let originX = vf.minX + x
|
||||||
|
let originY = vf.maxY - y - windowSize.height
|
||||||
|
|
||||||
|
return CGPoint(x: originX, y: originY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
99
macos/Tests/NSScreenTests.swift
Normal file
99
macos/Tests/NSScreenTests.swift
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
//
|
||||||
|
// WindowPositionTests.swift
|
||||||
|
// GhosttyTests
|
||||||
|
//
|
||||||
|
// Tests for window positioning coordinate conversion functionality.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Testing
|
||||||
|
import AppKit
|
||||||
|
@testable import Ghostty
|
||||||
|
|
||||||
|
struct NSScreenExtensionTests {
|
||||||
|
/// Test positive coordinate conversion from top-left to bottom-left
|
||||||
|
@Test func testPositiveCoordinateConversion() async throws {
|
||||||
|
// Mock screen with 1000x800 visible frame starting at (0, 100)
|
||||||
|
let mockScreenFrame = NSRect(x: 0, y: 100, width: 1000, height: 800)
|
||||||
|
let mockScreen = MockNSScreen(visibleFrame: mockScreenFrame)
|
||||||
|
|
||||||
|
// Mock window size
|
||||||
|
let windowSize = CGSize(width: 400, height: 300)
|
||||||
|
|
||||||
|
// Test top-left positioning: x=15, y=15
|
||||||
|
let origin = mockScreen.origin(
|
||||||
|
fromTopLeftOffsetX: 15,
|
||||||
|
offsetY: 15,
|
||||||
|
windowSize: windowSize)
|
||||||
|
|
||||||
|
// Expected: x = 0 + 15 = 15, y = (100 + 800) - 15 - 300 = 585
|
||||||
|
#expect(origin.x == 15)
|
||||||
|
#expect(origin.y == 585)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test zero coordinates (exact top-left corner)
|
||||||
|
@Test func testZeroCoordinates() async throws {
|
||||||
|
let mockScreenFrame = NSRect(x: 0, y: 100, width: 1000, height: 800)
|
||||||
|
let mockScreen = MockNSScreen(visibleFrame: mockScreenFrame)
|
||||||
|
let windowSize = CGSize(width: 400, height: 300)
|
||||||
|
|
||||||
|
let origin = mockScreen.origin(
|
||||||
|
fromTopLeftOffsetX: 0,
|
||||||
|
offsetY: 0,
|
||||||
|
windowSize: windowSize)
|
||||||
|
|
||||||
|
// Expected: x = 0, y = (100 + 800) - 0 - 300 = 600
|
||||||
|
#expect(origin.x == 0)
|
||||||
|
#expect(origin.y == 600)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test with offset screen (not starting at origin)
|
||||||
|
@Test func testOffsetScreen() async throws {
|
||||||
|
// Secondary monitor at position (1440, 0) with 1920x1080 resolution
|
||||||
|
let mockScreenFrame = NSRect(x: 1440, y: 0, width: 1920, height: 1080)
|
||||||
|
let mockScreen = MockNSScreen(visibleFrame: mockScreenFrame)
|
||||||
|
let windowSize = CGSize(width: 600, height: 400)
|
||||||
|
|
||||||
|
let origin = mockScreen.origin(
|
||||||
|
fromTopLeftOffsetX: 100,
|
||||||
|
offsetY: 50,
|
||||||
|
windowSize: windowSize)
|
||||||
|
|
||||||
|
// Expected: x = 1440 + 100 = 1540, y = (0 + 1080) - 50 - 400 = 630
|
||||||
|
#expect(origin.x == 1540)
|
||||||
|
#expect(origin.y == 630)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test large coordinates
|
||||||
|
@Test func testLargeCoordinates() async throws {
|
||||||
|
let mockScreenFrame = NSRect(x: 0, y: 0, width: 1920, height: 1080)
|
||||||
|
let mockScreen = MockNSScreen(visibleFrame: mockScreenFrame)
|
||||||
|
let windowSize = CGSize(width: 400, height: 300)
|
||||||
|
|
||||||
|
let origin = mockScreen.origin(
|
||||||
|
fromTopLeftOffsetX: 500,
|
||||||
|
offsetY: 200,
|
||||||
|
windowSize: windowSize)
|
||||||
|
|
||||||
|
// Expected: x = 0 + 500 = 500, y = (0 + 1080) - 200 - 300 = 580
|
||||||
|
#expect(origin.x == 500)
|
||||||
|
#expect(origin.y == 580)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mock NSScreen class for testing coordinate conversion
|
||||||
|
private class MockNSScreen: NSScreen {
|
||||||
|
private let mockVisibleFrame: NSRect
|
||||||
|
|
||||||
|
init(visibleFrame: NSRect) {
|
||||||
|
self.mockVisibleFrame = visibleFrame
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override var visibleFrame: NSRect {
|
||||||
|
return mockVisibleFrame
|
||||||
|
}
|
||||||
|
}
|
@@ -79,7 +79,7 @@ elif [ "$1" != "--update" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
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"
|
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"
|
||||||
alejandra --quiet "$WORK_DIR/build.zig.zon.nix"
|
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/build.zig.zon.json"
|
||||||
prettier --log-level warn --write "$WORK_DIR/zig-packages.json"
|
prettier --log-level warn --write "$WORK_DIR/zig-packages.json"
|
||||||
@@ -118,4 +118,3 @@ else
|
|||||||
echo -e "OK: flatpak/zig-packages.json updated."
|
echo -e "OK: flatpak/zig-packages.json updated."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
lib,
|
lib,
|
||||||
stdenv,
|
stdenv,
|
||||||
bashInteractive,
|
bashInteractive,
|
||||||
|
doxygen,
|
||||||
nushell,
|
nushell,
|
||||||
appstream,
|
appstream,
|
||||||
flatpak-builder,
|
flatpak-builder,
|
||||||
@@ -89,6 +90,7 @@ in
|
|||||||
packages =
|
packages =
|
||||||
[
|
[
|
||||||
# For builds
|
# For builds
|
||||||
|
doxygen
|
||||||
jq
|
jq
|
||||||
llvmPackages_latest.llvm
|
llvmPackages_latest.llvm
|
||||||
minisign
|
minisign
|
||||||
|
@@ -40,7 +40,7 @@
|
|||||||
in
|
in
|
||||||
stdenv.mkDerivation (finalAttrs: {
|
stdenv.mkDerivation (finalAttrs: {
|
||||||
pname = "ghostty";
|
pname = "ghostty";
|
||||||
version = "1.2.0";
|
version = "1.2.1";
|
||||||
|
|
||||||
# We limit source like this to try and reduce the amount of rebuilds as possible
|
# 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
|
# 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,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
const imgui = b.dependency("imgui", .{});
|
const imgui_ = b.lazyDependency("imgui", .{});
|
||||||
const lib = b.addLibrary(.{
|
const lib = b.addLibrary(.{
|
||||||
.name = "cimgui",
|
.name = "cimgui",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
@@ -52,7 +52,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lib.addIncludePath(imgui.path(""));
|
if (imgui_) |imgui| lib.addIncludePath(imgui.path(""));
|
||||||
module.addIncludePath(b.path("vendor"));
|
module.addIncludePath(b.path("vendor"));
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||||
@@ -72,32 +72,33 @@ pub fn build(b: *std.Build) !void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
lib.addCSourceFile(.{ .file = b.path("vendor/cimgui.cpp"), .flags = flags.items });
|
if (imgui_) |imgui| {
|
||||||
lib.addCSourceFile(.{ .file = imgui.path("imgui.cpp"), .flags = flags.items });
|
lib.addCSourceFile(.{ .file = b.path("vendor/cimgui.cpp"), .flags = flags.items });
|
||||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_draw.cpp"), .flags = flags.items });
|
lib.addCSourceFile(.{ .file = imgui.path("imgui.cpp"), .flags = flags.items });
|
||||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_demo.cpp"), .flags = flags.items });
|
lib.addCSourceFile(.{ .file = imgui.path("imgui_draw.cpp"), .flags = flags.items });
|
||||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_widgets.cpp"), .flags = flags.items });
|
lib.addCSourceFile(.{ .file = imgui.path("imgui_demo.cpp"), .flags = flags.items });
|
||||||
lib.addCSourceFile(.{ .file = imgui.path("imgui_tables.cpp"), .flags = flags.items });
|
lib.addCSourceFile(.{ .file = imgui.path("imgui_widgets.cpp"), .flags = flags.items });
|
||||||
lib.addCSourceFile(.{ .file = imgui.path("misc/freetype/imgui_freetype.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(.{
|
lib.addCSourceFile(.{
|
||||||
.file = imgui.path("backends/imgui_impl_metal.mm"),
|
.file = imgui.path("backends/imgui_impl_opengl3.cpp"),
|
||||||
.flags = flags.items,
|
.flags = flags.items,
|
||||||
});
|
});
|
||||||
if (target.result.os.tag == .macos) {
|
|
||||||
|
if (target.result.os.tag.isDarwin()) {
|
||||||
|
if (!target.query.isNative()) {
|
||||||
|
try @import("apple_sdk").addPaths(b, lib);
|
||||||
|
}
|
||||||
lib.addCSourceFile(.{
|
lib.addCSourceFile(.{
|
||||||
.file = imgui.path("backends/imgui_impl_osx.mm"),
|
.file = imgui.path("backends/imgui_impl_metal.mm"),
|
||||||
.flags = flags.items,
|
.flags = flags.items,
|
||||||
});
|
});
|
||||||
|
if (target.result.os.tag == .macos) {
|
||||||
|
lib.addCSourceFile(.{
|
||||||
|
.file = imgui.path("backends/imgui_impl_osx.mm"),
|
||||||
|
.flags = flags.items,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
// ocornut/imgui
|
// ocornut/imgui
|
||||||
.url = "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
|
.url = "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
|
||||||
.hash = "N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3",
|
.hash = "N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||||
|
@@ -10,11 +10,11 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
const upstream = b.dependency("glslang", .{});
|
const upstream = b.lazyDependency("glslang", .{});
|
||||||
const lib = try buildGlslang(b, upstream, target, optimize);
|
const lib = try buildGlslang(b, upstream, target, optimize);
|
||||||
b.installArtifact(lib);
|
b.installArtifact(lib);
|
||||||
|
|
||||||
module.addIncludePath(upstream.path(""));
|
if (upstream) |v| module.addIncludePath(v.path(""));
|
||||||
module.addIncludePath(b.path("override"));
|
module.addIncludePath(b.path("override"));
|
||||||
|
|
||||||
if (target.query.isNative()) {
|
if (target.query.isNative()) {
|
||||||
@@ -38,7 +38,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
fn buildGlslang(
|
fn buildGlslang(
|
||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
upstream: *std.Build.Dependency,
|
upstream_: ?*std.Build.Dependency,
|
||||||
target: std.Build.ResolvedTarget,
|
target: std.Build.ResolvedTarget,
|
||||||
optimize: std.builtin.OptimizeMode,
|
optimize: std.builtin.OptimizeMode,
|
||||||
) !*std.Build.Step.Compile {
|
) !*std.Build.Step.Compile {
|
||||||
@@ -52,7 +52,7 @@ fn buildGlslang(
|
|||||||
});
|
});
|
||||||
lib.linkLibC();
|
lib.linkLibC();
|
||||||
lib.linkLibCpp();
|
lib.linkLibCpp();
|
||||||
lib.addIncludePath(upstream.path(""));
|
if (upstream_) |upstream| lib.addIncludePath(upstream.path(""));
|
||||||
lib.addIncludePath(b.path("override"));
|
lib.addIncludePath(b.path("override"));
|
||||||
if (target.result.os.tag.isDarwin()) {
|
if (target.result.os.tag.isDarwin()) {
|
||||||
const apple_sdk = @import("apple_sdk");
|
const apple_sdk = @import("apple_sdk");
|
||||||
@@ -66,87 +66,89 @@ fn buildGlslang(
|
|||||||
"-fno-sanitize-trap=undefined",
|
"-fno-sanitize-trap=undefined",
|
||||||
});
|
});
|
||||||
|
|
||||||
lib.addCSourceFiles(.{
|
if (upstream_) |upstream| {
|
||||||
.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(.{
|
lib.addCSourceFiles(.{
|
||||||
.root = upstream.path(""),
|
.root = upstream.path(""),
|
||||||
.flags = flags.items,
|
.flags = flags.items,
|
||||||
.files = &.{
|
.files = &.{
|
||||||
"glslang/OSDependent/Unix/ossource.cpp",
|
// GenericCodeGen
|
||||||
},
|
"glslang/GenericCodeGen/CodeGen.cpp",
|
||||||
});
|
"glslang/GenericCodeGen/Link.cpp",
|
||||||
} else {
|
|
||||||
lib.addCSourceFiles(.{
|
// MachineIndependent
|
||||||
.root = upstream.path(""),
|
//"MachineIndependent/glslang.y",
|
||||||
.flags = flags.items,
|
"glslang/MachineIndependent/glslang_tab.cpp",
|
||||||
.files = &.{
|
"glslang/MachineIndependent/attribute.cpp",
|
||||||
"glslang/OSDependent/Windows/ossource.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 = &.{
|
||||||
|
"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;
|
return lib;
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
.glslang = .{
|
.glslang = .{
|
||||||
.url = "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
.url = "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
||||||
.hash = "N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy",
|
.hash = "N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||||
|
@@ -4,7 +4,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const upstream = b.dependency("highway", .{});
|
const upstream_ = b.lazyDependency("highway", .{});
|
||||||
|
|
||||||
const module = b.addModule("highway", .{
|
const module = b.addModule("highway", .{
|
||||||
.root_source_file = b.path("main.zig"),
|
.root_source_file = b.path("main.zig"),
|
||||||
@@ -21,8 +21,10 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.linkage = .static,
|
.linkage = .static,
|
||||||
});
|
});
|
||||||
lib.linkLibCpp();
|
lib.linkLibCpp();
|
||||||
lib.addIncludePath(upstream.path(""));
|
if (upstream_) |upstream| {
|
||||||
module.addIncludePath(upstream.path(""));
|
lib.addIncludePath(upstream.path(""));
|
||||||
|
module.addIncludePath(upstream.path(""));
|
||||||
|
}
|
||||||
|
|
||||||
if (target.result.os.tag.isDarwin()) {
|
if (target.result.os.tag.isDarwin()) {
|
||||||
const apple_sdk = @import("apple_sdk");
|
const apple_sdk = @import("apple_sdk");
|
||||||
@@ -74,24 +76,26 @@ pub fn build(b: *std.Build) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lib.addCSourceFiles(.{ .flags = flags.items, .files = &.{"bridge.cpp"} });
|
lib.addCSourceFiles(.{ .flags = flags.items, .files = &.{"bridge.cpp"} });
|
||||||
lib.addCSourceFiles(.{
|
if (upstream_) |upstream| {
|
||||||
.root = upstream.path(""),
|
lib.addCSourceFiles(.{
|
||||||
.flags = flags.items,
|
.root = upstream.path(""),
|
||||||
.files = &.{
|
.flags = flags.items,
|
||||||
"hwy/abort.cc",
|
.files = &.{
|
||||||
"hwy/aligned_allocator.cc",
|
"hwy/abort.cc",
|
||||||
"hwy/nanobenchmark.cc",
|
"hwy/aligned_allocator.cc",
|
||||||
"hwy/per_target.cc",
|
"hwy/nanobenchmark.cc",
|
||||||
"hwy/print.cc",
|
"hwy/per_target.cc",
|
||||||
"hwy/targets.cc",
|
"hwy/print.cc",
|
||||||
"hwy/timer.cc",
|
"hwy/targets.cc",
|
||||||
},
|
"hwy/timer.cc",
|
||||||
});
|
},
|
||||||
lib.installHeadersDirectory(
|
});
|
||||||
upstream.path("hwy"),
|
lib.installHeadersDirectory(
|
||||||
"hwy",
|
upstream.path("hwy"),
|
||||||
.{ .include_extensions = &.{".h"} },
|
"hwy",
|
||||||
);
|
.{ .include_extensions = &.{".h"} },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
b.installArtifact(lib);
|
b.installArtifact(lib);
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
.highway = .{
|
.highway = .{
|
||||||
.url = "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz",
|
.url = "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz",
|
||||||
.hash = "N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE",
|
.hash = "N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||||
|
@@ -4,7 +4,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const upstream = b.dependency("libxml2", .{});
|
const upstream_ = b.lazyDependency("libxml2", .{});
|
||||||
|
|
||||||
const lib = b.addLibrary(.{
|
const lib = b.addLibrary(.{
|
||||||
.name = "xml2",
|
.name = "xml2",
|
||||||
@@ -16,7 +16,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
});
|
});
|
||||||
lib.linkLibC();
|
lib.linkLibC();
|
||||||
|
|
||||||
lib.addIncludePath(upstream.path("include"));
|
if (upstream_) |upstream| lib.addIncludePath(upstream.path("include"));
|
||||||
lib.addIncludePath(b.path("override/include"));
|
lib.addIncludePath(b.path("override/include"));
|
||||||
if (target.result.os.tag == .windows) {
|
if (target.result.os.tag == .windows) {
|
||||||
lib.addIncludePath(b.path("override/config/win32"));
|
lib.addIncludePath(b.path("override/config/win32"));
|
||||||
@@ -97,21 +97,23 @@ pub fn build(b: *std.Build) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lib.addCSourceFiles(.{
|
if (upstream_) |upstream| {
|
||||||
.root = upstream.path(""),
|
lib.addCSourceFiles(.{
|
||||||
.files = srcs,
|
.root = upstream.path(""),
|
||||||
.flags = flags.items,
|
.files = srcs,
|
||||||
});
|
.flags = flags.items,
|
||||||
|
});
|
||||||
|
|
||||||
lib.installHeader(
|
lib.installHeader(
|
||||||
b.path("override/include/libxml/xmlversion.h"),
|
b.path("override/include/libxml/xmlversion.h"),
|
||||||
"libxml/xmlversion.h",
|
"libxml/xmlversion.h",
|
||||||
);
|
);
|
||||||
lib.installHeadersDirectory(
|
lib.installHeadersDirectory(
|
||||||
upstream.path("include"),
|
upstream.path("include"),
|
||||||
"",
|
"",
|
||||||
.{ .include_extensions = &.{".h"} },
|
.{ .include_extensions = &.{".h"} },
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
b.installArtifact(lib);
|
b.installArtifact(lib);
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
.libxml2 = .{
|
.libxml2 = .{
|
||||||
.url = "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
|
.url = "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
|
||||||
.hash = "N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK",
|
.hash = "N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
43
pkg/opengl/Sampler.zig
Normal file
43
pkg/opengl/Sampler.zig
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
const Sampler = @This();
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
const errors = @import("errors.zig");
|
||||||
|
const glad = @import("glad.zig");
|
||||||
|
const Texture = @import("Texture.zig");
|
||||||
|
|
||||||
|
id: c.GLuint,
|
||||||
|
|
||||||
|
/// Create a single sampler.
|
||||||
|
pub fn create() errors.Error!Sampler {
|
||||||
|
var id: c.GLuint = undefined;
|
||||||
|
glad.context.GenSamplers.?(1, &id);
|
||||||
|
try errors.getError();
|
||||||
|
return .{ .id = id };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// glBindSampler
|
||||||
|
pub fn bind(v: Sampler, index: c_uint) !void {
|
||||||
|
glad.context.BindSampler.?(index, v.id);
|
||||||
|
try errors.getError();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parameter(
|
||||||
|
self: Sampler,
|
||||||
|
name: Texture.Parameter,
|
||||||
|
value: anytype,
|
||||||
|
) errors.Error!void {
|
||||||
|
switch (@TypeOf(value)) {
|
||||||
|
c.GLint => glad.context.SamplerParameteri.?(
|
||||||
|
self.id,
|
||||||
|
@intFromEnum(name),
|
||||||
|
value,
|
||||||
|
),
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
try errors.getError();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(v: Sampler) void {
|
||||||
|
glad.context.DeleteSamplers.?(1, &v.id);
|
||||||
|
}
|
@@ -18,6 +18,7 @@ pub const Buffer = @import("Buffer.zig");
|
|||||||
pub const Framebuffer = @import("Framebuffer.zig");
|
pub const Framebuffer = @import("Framebuffer.zig");
|
||||||
pub const Renderbuffer = @import("Renderbuffer.zig");
|
pub const Renderbuffer = @import("Renderbuffer.zig");
|
||||||
pub const Program = @import("Program.zig");
|
pub const Program = @import("Program.zig");
|
||||||
|
pub const Sampler = @import("Sampler.zig");
|
||||||
pub const Shader = @import("Shader.zig");
|
pub const Shader = @import("Shader.zig");
|
||||||
pub const Texture = @import("Texture.zig");
|
pub const Texture = @import("Texture.zig");
|
||||||
pub const VertexArray = @import("VertexArray.zig");
|
pub const VertexArray = @import("VertexArray.zig");
|
||||||
|
@@ -4,16 +4,19 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const upstream = b.dependency("spirv_cross", .{});
|
const module = b.addModule("spirv_cross", .{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize });
|
||||||
|
|
||||||
const module = b.addModule("spirv_cross", .{ .root_source_file = b.path("main.zig") });
|
// For dynamic linking, we prefer dynamic linking and to search by
|
||||||
module.addIncludePath(upstream.path(""));
|
// mode first. Mode first will search all paths for a dynamic library
|
||||||
|
// before falling back to static.
|
||||||
const lib = try buildSpirvCross(b, upstream, target, optimize);
|
const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{
|
||||||
b.installArtifact(lib);
|
.preferred_link_mode = .dynamic,
|
||||||
|
.search_strategy = .mode_first,
|
||||||
|
};
|
||||||
|
|
||||||
|
var test_exe: ?*std.Build.Step.Compile = null;
|
||||||
if (target.query.isNative()) {
|
if (target.query.isNative()) {
|
||||||
const test_exe = b.addTest(.{
|
test_exe = b.addTest(.{
|
||||||
.name = "test",
|
.name = "test",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("main.zig"),
|
.root_source_file = b.path("main.zig"),
|
||||||
@@ -21,19 +24,28 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
test_exe.linkLibrary(lib);
|
const tests_run = b.addRunArtifact(test_exe.?);
|
||||||
const tests_run = b.addRunArtifact(test_exe);
|
|
||||||
const test_step = b.step("test", "Run tests");
|
const test_step = b.step("test", "Run tests");
|
||||||
test_step.dependOn(&tests_run.step);
|
test_step.dependOn(&tests_run.step);
|
||||||
|
|
||||||
// Uncomment this if we're debugging tests
|
// Uncomment this if we're debugging tests
|
||||||
// b.installArtifact(test_exe);
|
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buildSpirvCross(
|
fn buildSpirvCross(
|
||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
upstream: *std.Build.Dependency,
|
module: *std.Build.Module,
|
||||||
target: std.Build.ResolvedTarget,
|
target: std.Build.ResolvedTarget,
|
||||||
optimize: std.builtin.OptimizeMode,
|
optimize: std.builtin.OptimizeMode,
|
||||||
) !*std.Build.Step.Compile {
|
) !*std.Build.Step.Compile {
|
||||||
@@ -62,32 +74,36 @@ fn buildSpirvCross(
|
|||||||
"-fno-sanitize-trap=undefined",
|
"-fno-sanitize-trap=undefined",
|
||||||
});
|
});
|
||||||
|
|
||||||
lib.addCSourceFiles(.{
|
if (b.lazyDependency("spirv_cross", .{})) |upstream| {
|
||||||
.root = upstream.path(""),
|
lib.addIncludePath(upstream.path(""));
|
||||||
.flags = flags.items,
|
module.addIncludePath(upstream.path(""));
|
||||||
.files = &.{
|
lib.addCSourceFiles(.{
|
||||||
// Core
|
.root = upstream.path(""),
|
||||||
"spirv_cross.cpp",
|
.flags = flags.items,
|
||||||
"spirv_parser.cpp",
|
.files = &.{
|
||||||
"spirv_cross_parsed_ir.cpp",
|
// Core
|
||||||
"spirv_cfg.cpp",
|
"spirv_cross.cpp",
|
||||||
|
"spirv_parser.cpp",
|
||||||
|
"spirv_cross_parsed_ir.cpp",
|
||||||
|
"spirv_cfg.cpp",
|
||||||
|
|
||||||
// C
|
// C
|
||||||
"spirv_cross_c.cpp",
|
"spirv_cross_c.cpp",
|
||||||
|
|
||||||
// GLSL
|
// GLSL
|
||||||
"spirv_glsl.cpp",
|
"spirv_glsl.cpp",
|
||||||
|
|
||||||
// MSL
|
// MSL
|
||||||
"spirv_msl.cpp",
|
"spirv_msl.cpp",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
lib.installHeadersDirectory(
|
lib.installHeadersDirectory(
|
||||||
upstream.path(""),
|
upstream.path(""),
|
||||||
"",
|
"",
|
||||||
.{ .include_extensions = &.{".h"} },
|
.{ .include_extensions = &.{".h"} },
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
.spirv_cross = .{
|
.spirv_cross = .{
|
||||||
.url = "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz",
|
.url = "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz",
|
||||||
.hash = "N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv",
|
.hash = "N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv",
|
||||||
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||||
|
@@ -1,40 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
.{
|
|
||||||
.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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
pub const c = @cImport({
|
|
||||||
@cInclude("utf8proc.h");
|
|
||||||
});
|
|
@@ -1,20 +0,0 @@
|
|||||||
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,12 +131,11 @@ which should be filled in accordingly. You can then add your translations
|
|||||||
within the newly created translation file.
|
within the newly created translation file.
|
||||||
|
|
||||||
Afterwards, you need to update the list of known locales within Ghostty's
|
Afterwards, you need to update the list of known locales within Ghostty's
|
||||||
build system. To do so, open `src/os/i18n.zig` and find the list
|
build system. To do so, open `src/os/i18n_locales.zig` and find the list
|
||||||
of locales under the `locales` variable, then add the full locale name
|
of locales after the comments, then add the full locale name into the list.
|
||||||
into the list.
|
|
||||||
|
|
||||||
The order matters, so make sure to place your locale in the correct position.
|
The order matters, so make sure to place your locale in the correct position.
|
||||||
Read the comment above the variable for more details on the order. If you're
|
Read the comments present in the file for more details on the order. If you're
|
||||||
unsure, place it at the end of the list.
|
unsure, place it at the end of the list.
|
||||||
|
|
||||||
```zig
|
```zig
|
||||||
@@ -146,7 +145,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
|
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
|
your locale to the `CODEOWNERS` file. Find the `# Localization` section near the
|
||||||
|
321
po/hr_HR.UTF-8.po
Normal file
321
po/hr_HR.UTF-8.po
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
# Croatian translations for com.mitchellh.ghostty package
|
||||||
|
# Hrvatski prijevod za paket com.mitchellh.ghostty.
|
||||||
|
# Copyright (C) 2025 "Mitchell Hashimoto, Ghostty contributors"
|
||||||
|
# This file is distributed under the same license as the com.mitchellh.ghostty package.
|
||||||
|
# Filip <filipm7@protonmail.com>, 2025.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: com.mitchellh.ghostty\n"
|
||||||
|
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
|
||||||
|
"POT-Creation-Date: 2025-07-22 17:18+0000\n"
|
||||||
|
"PO-Revision-Date: 2025-09-16 17:47+0200\n"
|
||||||
|
"Last-Translator: Filip7 <filipm7@protonmail.com>\n"
|
||||||
|
"Language-Team: Croatian <lokalizacija@linux.hr>\n"
|
||||||
|
"Language: hr\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||||
|
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:5
|
||||||
|
msgid "Change Terminal Title"
|
||||||
|
msgstr "Promijeni naslov terminala"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:6
|
||||||
|
msgid "Leave blank to restore the default title."
|
||||||
|
msgstr "Ostavi prazno za povratak zadanog naslova."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:9
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:10 src/apprt/gtk/ui/1.2/ccw-paste.blp:10
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:44
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Otkaži"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:10
|
||||||
|
msgid "OK"
|
||||||
|
msgstr "OK"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:5
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:5
|
||||||
|
msgid "Configuration Errors"
|
||||||
|
msgstr "Greške u postavkama"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:6
|
||||||
|
msgid ""
|
||||||
|
"One or more configuration errors were found. Please review the errors below, "
|
||||||
|
"and either reload your configuration or ignore these errors."
|
||||||
|
msgstr ""
|
||||||
|
"Pronađene su jedna ili više grešaka u postavkama. Pregledaj niže navedene greške"
|
||||||
|
"te ponovno učitaj postavke ili zanemari ove greške."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:9
|
||||||
|
msgid "Ignore"
|
||||||
|
msgstr "Zanemari"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:97
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:100
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:10
|
||||||
|
msgid "Reload Configuration"
|
||||||
|
msgstr "Ponovno učitaj postavke"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
|
||||||
|
msgid "Split Up"
|
||||||
|
msgstr "Podijeli gore"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
|
||||||
|
msgid "Split Down"
|
||||||
|
msgstr "Podijeli dolje"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
|
||||||
|
msgid "Split Left"
|
||||||
|
msgstr "Podijeli lijevo"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
|
||||||
|
msgid "Split Right"
|
||||||
|
msgstr "Podijeli desno"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/command-palette.blp:16
|
||||||
|
msgid "Execute a command…"
|
||||||
|
msgstr "Izvrši naredbu…"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
|
||||||
|
msgid "Copy"
|
||||||
|
msgstr "Kopiraj"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:11 src/apprt/gtk/ui/1.2/ccw-paste.blp:11
|
||||||
|
msgid "Paste"
|
||||||
|
msgstr "Zalijepi"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:18
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:73
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Očisti"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:23
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:78
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Resetiraj"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:30
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:42
|
||||||
|
msgid "Split"
|
||||||
|
msgstr "Podijeli"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:33
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:45
|
||||||
|
msgid "Change Title…"
|
||||||
|
msgstr "Promijeni naslov…"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
|
||||||
|
msgid "Tab"
|
||||||
|
msgstr "Kartica"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
|
||||||
|
#: src/apprt/gtk/Window.zig:265
|
||||||
|
msgid "New Tab"
|
||||||
|
msgstr "Nova kartica"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:67
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:35
|
||||||
|
msgid "Close Tab"
|
||||||
|
msgstr "Zatvori karticu"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:73
|
||||||
|
msgid "Window"
|
||||||
|
msgstr "Prozor"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:76
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:18
|
||||||
|
msgid "New Window"
|
||||||
|
msgstr "Novi prozor"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:81
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:23
|
||||||
|
msgid "Close Window"
|
||||||
|
msgstr "Zatvori prozor"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:89
|
||||||
|
msgid "Config"
|
||||||
|
msgstr "Postavke"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:92
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:95
|
||||||
|
msgid "Open Configuration"
|
||||||
|
msgstr "Otvori postavke"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:85
|
||||||
|
msgid "Command Palette"
|
||||||
|
msgstr "Paleta naredbi"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:90
|
||||||
|
msgid "Terminal Inspector"
|
||||||
|
msgstr "Inspektor terminala"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:107
|
||||||
|
#: src/apprt/gtk/Window.zig:1038
|
||||||
|
msgid "About Ghostty"
|
||||||
|
msgstr "O Ghosttyju"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:112
|
||||||
|
msgid "Quit"
|
||||||
|
msgstr "Izađi"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:6
|
||||||
|
msgid "Authorize Clipboard Access"
|
||||||
|
msgstr "Dopusti pristup međuspremniku"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:7
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:7
|
||||||
|
msgid ""
|
||||||
|
"An application is attempting to read from the clipboard. The current "
|
||||||
|
"clipboard contents are shown below."
|
||||||
|
msgstr ""
|
||||||
|
"Program pokušava pročitati vrijednost međuspremnika. Trenutna"
|
||||||
|
"vrijednost međuspremnika je prikazana niže."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:10
|
||||||
|
msgid "Deny"
|
||||||
|
msgstr "Odbij"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:11
|
||||||
|
msgid "Allow"
|
||||||
|
msgstr "Dopusti"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:81
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:77
|
||||||
|
msgid "Remember choice for this split"
|
||||||
|
msgstr "Zapamti izbor za ovu podjelu"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:82
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:78
|
||||||
|
msgid "Reload configuration to show this prompt again"
|
||||||
|
msgstr "Ponovno učitaj postavke za prikaz ovog upita"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:7
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:7
|
||||||
|
msgid ""
|
||||||
|
"An application is attempting to write to the clipboard. The current "
|
||||||
|
"clipboard contents are shown below."
|
||||||
|
msgstr ""
|
||||||
|
"Aplikacija pokušava pisati u međuspremnik. Trenutačna vrijednost "
|
||||||
|
"međuspremnika prikazana je niže."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:6 src/apprt/gtk/ui/1.2/ccw-paste.blp:6
|
||||||
|
msgid "Warning: Potentially Unsafe Paste"
|
||||||
|
msgstr "Upozorenje: Potencijalno opasno lijepljenje"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:7 src/apprt/gtk/ui/1.2/ccw-paste.blp:7
|
||||||
|
msgid ""
|
||||||
|
"Pasting this text into the terminal may be dangerous as it looks like some "
|
||||||
|
"commands may be executed."
|
||||||
|
msgstr ""
|
||||||
|
"Lijepljenje ovog teksta u terminal može biti opasno jer se čini da "
|
||||||
|
"neke naredbe mogu biti izvršene."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:47 src/apprt/gtk/Surface.zig:2531
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Zatvori"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:87
|
||||||
|
msgid "Quit Ghostty?"
|
||||||
|
msgstr "Zatvori Ghostty?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:88
|
||||||
|
msgid "Close Window?"
|
||||||
|
msgstr "Zatvori prozor?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:89
|
||||||
|
msgid "Close Tab?"
|
||||||
|
msgstr "Zatvori karticu?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:90
|
||||||
|
msgid "Close Split?"
|
||||||
|
msgstr "Zatvori podjelu?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:96
|
||||||
|
msgid "All terminal sessions will be terminated."
|
||||||
|
msgstr "Sve sesije terminala će biti prekinute."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:97
|
||||||
|
msgid "All terminal sessions in this window will be terminated."
|
||||||
|
msgstr "Sve sesije terminala u ovom prozoru će biti prekinute."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:98
|
||||||
|
msgid "All terminal sessions in this tab will be terminated."
|
||||||
|
msgstr "Sve sesije terminala u ovoj kartici će biti prekinute."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:99
|
||||||
|
msgid "The currently running process in this split will be terminated."
|
||||||
|
msgstr "Pokrenuti procesi u ovom odjeljku će biti prekinuti."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:1266
|
||||||
|
msgid "Copied to clipboard"
|
||||||
|
msgstr "Kopirano u međuspremnik"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:1268
|
||||||
|
msgid "Cleared clipboard"
|
||||||
|
msgstr "Očišćen međuspremnik"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:2525
|
||||||
|
msgid "Command succeeded"
|
||||||
|
msgstr "Naredba je uspjela"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:2527
|
||||||
|
msgid "Command failed"
|
||||||
|
msgstr "Naredba nije uspjela"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:216
|
||||||
|
msgid "Main Menu"
|
||||||
|
msgstr "Glavni izbornik"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:239
|
||||||
|
msgid "View Open Tabs"
|
||||||
|
msgstr "Pregledaj otvorene kartice"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:266
|
||||||
|
msgid "New Split"
|
||||||
|
msgstr "Nova podjela"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:329
|
||||||
|
msgid ""
|
||||||
|
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
|
||||||
|
msgstr ""
|
||||||
|
"⚠️ Pokrenuta je debug verzija Ghosttyja! Performanse će biti smanjene."
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:775
|
||||||
|
msgid "Reloaded the configuration"
|
||||||
|
msgstr "Ponovno učitane postavke"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:1019
|
||||||
|
msgid "Ghostty Developers"
|
||||||
|
msgstr "Razvijatelji Ghosttyja"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/inspector.zig:144
|
||||||
|
msgid "Ghostty: Terminal Inspector"
|
||||||
|
msgstr "Ghostty: inspektor terminala"
|
@@ -4,14 +4,15 @@
|
|||||||
# This file is distributed under the same license as the com.mitchellh.ghostty package.
|
# This file is distributed under the same license as the com.mitchellh.ghostty package.
|
||||||
# Gustavo Peres <gsodevel@gmail.com>, 2025.
|
# Gustavo Peres <gsodevel@gmail.com>, 2025.
|
||||||
# Guilherme Tiscoski <github@guilhermetiscoski.com>, 2025.
|
# Guilherme Tiscoski <github@guilhermetiscoski.com>, 2025.
|
||||||
|
# Nilton Perim Neto <niltonperimneto@gmail.com>, 2025.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: com.mitchellh.ghostty\n"
|
"Project-Id-Version: com.mitchellh.ghostty\n"
|
||||||
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
|
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
|
||||||
"POT-Creation-Date: 2025-07-22 17:18+0000\n"
|
"POT-Creation-Date: 2025-07-22 17:18+0000\n"
|
||||||
"PO-Revision-Date: 2025-08-25 11:46-0500\n"
|
"PO-Revision-Date: 2025-09-15 13:57-0300\n"
|
||||||
"Last-Translator: Guilherme Tiscoski <github@guihermetiscoski.com>\n"
|
"Last-Translator: Nilton Perim Neto <niltonperimneto@gmail.com>\n"
|
||||||
"Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge."
|
"Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge."
|
||||||
"net>\n"
|
"net>\n"
|
||||||
"Language: pt_BR\n"
|
"Language: pt_BR\n"
|
||||||
@@ -26,7 +27,7 @@ msgstr "Mudar título do Terminal"
|
|||||||
|
|
||||||
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:6
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:6
|
||||||
msgid "Leave blank to restore the default title."
|
msgid "Leave blank to restore the default title."
|
||||||
msgstr "Deixe em branco para restaurar o título original."
|
msgstr "Deixe em branco para restaurar o título padrão."
|
||||||
|
|
||||||
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:9
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:9
|
||||||
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:10 src/apprt/gtk/ui/1.2/ccw-paste.blp:10
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:10 src/apprt/gtk/ui/1.2/ccw-paste.blp:10
|
||||||
@@ -315,8 +316,8 @@ msgstr "Configuração recarregada"
|
|||||||
|
|
||||||
#: src/apprt/gtk/Window.zig:1019
|
#: src/apprt/gtk/Window.zig:1019
|
||||||
msgid "Ghostty Developers"
|
msgid "Ghostty Developers"
|
||||||
msgstr "Desenvolvedores Ghostty"
|
msgstr "Desenvolvedores do Ghostty"
|
||||||
|
|
||||||
#: src/apprt/gtk/inspector.zig:144
|
#: src/apprt/gtk/inspector.zig:144
|
||||||
msgid "Ghostty: Terminal Inspector"
|
msgid "Ghostty: Terminal Inspector"
|
||||||
msgstr "Ghostty: Inspetor de terminal"
|
msgstr "Ghostty: Inspetor do terminal"
|
||||||
|
314
po/zh_TW.UTF-8.po
Normal file
314
po/zh_TW.UTF-8.po
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
# Traditional Chinese (Taiwan) translation for com.mitchellh.ghostty package.
|
||||||
|
# Copyright (C) 2025 Mitchell Hashimoto
|
||||||
|
# This file is distributed under the same license as the com.mitchellh.ghostty package.
|
||||||
|
# Peter Dave Hello <hsu@peterdavehello.org>, 2025.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: com.mitchellh.ghostty\n"
|
||||||
|
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
|
||||||
|
"POT-Creation-Date: 2025-07-22 17:18+0000\n"
|
||||||
|
"PO-Revision-Date: 2025-09-21 18:59+0800\n"
|
||||||
|
"Last-Translator: Peter Dave Hello <hsu@peterdavehello.org>\n"
|
||||||
|
"Language-Team: Chinese (traditional)\n"
|
||||||
|
"Language: zh_TW\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:5
|
||||||
|
msgid "Change Terminal Title"
|
||||||
|
msgstr "變更終端機標題"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:6
|
||||||
|
msgid "Leave blank to restore the default title."
|
||||||
|
msgstr "留空即可還原為預設標題。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:9
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:10 src/apprt/gtk/ui/1.2/ccw-paste.blp:10
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:44
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "取消"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/prompt-title-dialog.blp:10
|
||||||
|
msgid "OK"
|
||||||
|
msgstr "確定"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:5
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:5
|
||||||
|
msgid "Configuration Errors"
|
||||||
|
msgstr "設定錯誤"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:6
|
||||||
|
msgid ""
|
||||||
|
"One or more configuration errors were found. Please review the errors below, "
|
||||||
|
"and either reload your configuration or ignore these errors."
|
||||||
|
msgstr ""
|
||||||
|
"發現有設定錯誤。請檢視以下錯誤,並重新載入設定或忽略這些錯誤。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:9
|
||||||
|
msgid "Ignore"
|
||||||
|
msgstr "忽略"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:97
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:100
|
||||||
|
#: src/apprt/gtk/ui/1.2/config-errors-dialog.blp:10
|
||||||
|
msgid "Reload Configuration"
|
||||||
|
msgstr "重新載入設定"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
|
||||||
|
msgid "Split Up"
|
||||||
|
msgstr "向上分割"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
|
||||||
|
msgid "Split Down"
|
||||||
|
msgstr "向下分割"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
|
||||||
|
msgid "Split Left"
|
||||||
|
msgstr "向左分割"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
|
||||||
|
msgid "Split Right"
|
||||||
|
msgstr "向右分割"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/command-palette.blp:16
|
||||||
|
msgid "Execute a command…"
|
||||||
|
msgstr "執行命令…"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
|
||||||
|
msgid "Copy"
|
||||||
|
msgstr "複製"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:11 src/apprt/gtk/ui/1.2/ccw-paste.blp:11
|
||||||
|
msgid "Paste"
|
||||||
|
msgstr "貼上"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:18
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:73
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "清除"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:23
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:78
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "重設"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:30
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:42
|
||||||
|
msgid "Split"
|
||||||
|
msgstr "分割"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:33
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:45
|
||||||
|
msgid "Change Title…"
|
||||||
|
msgstr "變更標題…"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
|
||||||
|
msgid "Tab"
|
||||||
|
msgstr "分頁"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
|
||||||
|
#: src/apprt/gtk/Window.zig:265
|
||||||
|
msgid "New Tab"
|
||||||
|
msgstr "開新分頁"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:67
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:35
|
||||||
|
msgid "Close Tab"
|
||||||
|
msgstr "關閉分頁"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:73
|
||||||
|
msgid "Window"
|
||||||
|
msgstr "視窗"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:76
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:18
|
||||||
|
msgid "New Window"
|
||||||
|
msgstr "開新視窗"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:81
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:23
|
||||||
|
msgid "Close Window"
|
||||||
|
msgstr "關閉視窗"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:89
|
||||||
|
msgid "Config"
|
||||||
|
msgstr "設定"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:92
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:95
|
||||||
|
msgid "Open Configuration"
|
||||||
|
msgstr "開啟設定"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:85
|
||||||
|
msgid "Command Palette"
|
||||||
|
msgstr "命令面板"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:90
|
||||||
|
msgid "Terminal Inspector"
|
||||||
|
msgstr "終端機檢查工具"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:107
|
||||||
|
#: src/apprt/gtk/Window.zig:1038
|
||||||
|
msgid "About Ghostty"
|
||||||
|
msgstr "關於 Ghostty"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:112
|
||||||
|
msgid "Quit"
|
||||||
|
msgstr "結束"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:6
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:6
|
||||||
|
msgid "Authorize Clipboard Access"
|
||||||
|
msgstr "授權存取剪貼簿"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:7
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:7
|
||||||
|
msgid ""
|
||||||
|
"An application is attempting to read from the clipboard. The current "
|
||||||
|
"clipboard contents are shown below."
|
||||||
|
msgstr ""
|
||||||
|
"有應用程式正嘗試讀取剪貼簿,目前的剪貼簿內容顯示如下。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:10
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:10
|
||||||
|
msgid "Deny"
|
||||||
|
msgstr "拒絕"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-read.blp:11
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:11
|
||||||
|
msgid "Allow"
|
||||||
|
msgstr "允許"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:81
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:77
|
||||||
|
msgid "Remember choice for this split"
|
||||||
|
msgstr "記住此窗格的選擇"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:82
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:78
|
||||||
|
msgid "Reload configuration to show this prompt again"
|
||||||
|
msgstr "重新載入設定以再次顯示此提示"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:7
|
||||||
|
#: src/apprt/gtk/ui/1.2/ccw-osc-52-write.blp:7
|
||||||
|
msgid ""
|
||||||
|
"An application is attempting to write to the clipboard. The current "
|
||||||
|
"clipboard contents are shown below."
|
||||||
|
msgstr ""
|
||||||
|
"有應用程式正嘗試寫入剪貼簿,目前的剪貼簿內容顯示如下。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:6 src/apprt/gtk/ui/1.2/ccw-paste.blp:6
|
||||||
|
msgid "Warning: Potentially Unsafe Paste"
|
||||||
|
msgstr "警告:可能有潛在安全風險的貼上操作"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:7 src/apprt/gtk/ui/1.2/ccw-paste.blp:7
|
||||||
|
msgid ""
|
||||||
|
"Pasting this text into the terminal may be dangerous as it looks like some "
|
||||||
|
"commands may be executed."
|
||||||
|
msgstr ""
|
||||||
|
"將這段文字貼到終端機具有潛在風險,因為它看起來像是可能會被執行的命令。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:47 src/apprt/gtk/Surface.zig:2531
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "關閉"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:87
|
||||||
|
msgid "Quit Ghostty?"
|
||||||
|
msgstr "要結束 Ghostty 嗎?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:88
|
||||||
|
msgid "Close Window?"
|
||||||
|
msgstr "是否要關閉視窗?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:89
|
||||||
|
msgid "Close Tab?"
|
||||||
|
msgstr "是否要關閉分頁?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:90
|
||||||
|
msgid "Close Split?"
|
||||||
|
msgstr "是否要關閉窗格?"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:96
|
||||||
|
msgid "All terminal sessions will be terminated."
|
||||||
|
msgstr "所有終端機工作階段都將被終止。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:97
|
||||||
|
msgid "All terminal sessions in this window will be terminated."
|
||||||
|
msgstr "此視窗中的所有終端機工作階段都將被終止。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:98
|
||||||
|
msgid "All terminal sessions in this tab will be terminated."
|
||||||
|
msgstr "此分頁中的所有終端機工作階段都將被終止。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/CloseDialog.zig:99
|
||||||
|
msgid "The currently running process in this split will be terminated."
|
||||||
|
msgstr "此窗格中目前執行的處理程序將被終止。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:1266
|
||||||
|
msgid "Copied to clipboard"
|
||||||
|
msgstr "已複製到剪貼簿"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:1268
|
||||||
|
msgid "Cleared clipboard"
|
||||||
|
msgstr "已清除剪貼簿"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:2525
|
||||||
|
msgid "Command succeeded"
|
||||||
|
msgstr "命令執行成功"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Surface.zig:2527
|
||||||
|
msgid "Command failed"
|
||||||
|
msgstr "命令執行失敗"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:216
|
||||||
|
msgid "Main Menu"
|
||||||
|
msgstr "主選單"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:239
|
||||||
|
msgid "View Open Tabs"
|
||||||
|
msgstr "檢視已開啟的分頁"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:266
|
||||||
|
msgid "New Split"
|
||||||
|
msgstr "新增窗格"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:329
|
||||||
|
msgid ""
|
||||||
|
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
|
||||||
|
msgstr ""
|
||||||
|
"⚠️ 您正在執行 Ghostty 的除錯版本!程式運作效能將會受到影響。"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:775
|
||||||
|
msgid "Reloaded the configuration"
|
||||||
|
msgstr "已重新載入設定"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/Window.zig:1019
|
||||||
|
msgid "Ghostty Developers"
|
||||||
|
msgstr "Ghostty 開發者"
|
||||||
|
|
||||||
|
#: src/apprt/gtk/inspector.zig:144
|
||||||
|
msgid "Ghostty: Terminal Inspector"
|
||||||
|
msgstr "Ghostty:終端機檢查工具"
|
@@ -61,10 +61,4 @@ fi
|
|||||||
|
|
||||||
[ "$needs_update" = true ] && echo "LAST_REVISION=$SNAP_REVISION" > "$SNAP_USER_DATA/.last_revision"
|
[ "$needs_update" = true ] && echo "LAST_REVISION=$SNAP_REVISION" > "$SNAP_USER_DATA/.last_revision"
|
||||||
|
|
||||||
# Unset all SNAP specific environment variables to keep them from leaking
|
|
||||||
# into other snaps that might get executed from within the shell
|
|
||||||
for var in $(printenv | grep SNAP_ | cut -d= -f1); do
|
|
||||||
unset $var
|
|
||||||
done
|
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
@@ -20,7 +20,7 @@ platforms:
|
|||||||
apps:
|
apps:
|
||||||
ghostty:
|
ghostty:
|
||||||
command: bin/ghostty
|
command: bin/ghostty
|
||||||
command-chain: [bin/launcher]
|
command-chain: [app/launcher]
|
||||||
completer: share/bash-completion/completions/ghostty.bash
|
completer: share/bash-completion/completions/ghostty.bash
|
||||||
desktop: share/applications/com.mitchellh.ghostty.desktop
|
desktop: share/applications/com.mitchellh.ghostty.desktop
|
||||||
#refresh-mode: ignore-running # Store rejects this, needs fix in review-tools
|
#refresh-mode: ignore-running # Store rejects this, needs fix in review-tools
|
||||||
@@ -35,7 +35,7 @@ parts:
|
|||||||
source: snap/local
|
source: snap/local
|
||||||
source-type: local
|
source-type: local
|
||||||
organize:
|
organize:
|
||||||
launcher: bin/
|
launcher: app/
|
||||||
|
|
||||||
zig:
|
zig:
|
||||||
plugin: nil
|
plugin: nil
|
||||||
@@ -79,7 +79,12 @@ parts:
|
|||||||
# TODO: Remove -fno-sys=gtk4-layer-shell when we upgrade to a version that packages it Ubuntu 24.10+
|
# TODO: Remove -fno-sys=gtk4-layer-shell when we upgrade to a version that packages it Ubuntu 24.10+
|
||||||
override-build: |
|
override-build: |
|
||||||
craftctl set version=$(cat VERSION)
|
craftctl set version=$(cat VERSION)
|
||||||
$CRAFT_PART_SRC/../../zig/src/zig build -Dpatch-rpath=\$ORIGIN/../usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/core24/current/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR -Doptimize=ReleaseFast -Dcpu=baseline -fno-sys=gtk4-layer-shell
|
$CRAFT_PART_SRC/../../zig/src/zig build \
|
||||||
|
-Dsnap \
|
||||||
|
-Dpatch-rpath=\$ORIGIN/../usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/core24/current/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR \
|
||||||
|
-Doptimize=ReleaseFast \
|
||||||
|
-Dcpu=baseline \
|
||||||
|
-fno-sys=gtk4-layer-shell
|
||||||
cp -rp zig-out/* $CRAFT_PART_INSTALL/
|
cp -rp zig-out/* $CRAFT_PART_INSTALL/
|
||||||
sed -i 's|Icon=com.mitchellh.ghostty|Icon=${SNAP}/share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png|g' $CRAFT_PART_INSTALL/share/applications/com.mitchellh.ghostty.desktop
|
sed -i 's|Icon=com.mitchellh.ghostty|Icon=${SNAP}/share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png|g' $CRAFT_PART_INSTALL/share/applications/com.mitchellh.ghostty.desktop
|
||||||
|
|
||||||
|
@@ -404,91 +404,6 @@ pub fn getData(self: Command, comptime DT: type) ?*DT {
|
|||||||
return if (self.data) |ptr| @ptrCast(@alignCast(ptr)) else null;
|
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
|
// Copied from Zig. This is a publicly exported function but there is no
|
||||||
// way to get it from the std package.
|
// way to get it from the std package.
|
||||||
fn createNullDelimitedEnvMap(arena: mem.Allocator, env_map: *const EnvMap) ![:null]?[*:0]u8 {
|
fn createNullDelimitedEnvMap(arena: mem.Allocator, env_map: *const EnvMap) ![:null]?[*:0]u8 {
|
||||||
|
@@ -66,6 +66,12 @@ font_grid_key: font.SharedGridSet.Key,
|
|||||||
font_size: font.face.DesiredSize,
|
font_size: font.face.DesiredSize,
|
||||||
font_metrics: font.Metrics,
|
font_metrics: font.Metrics,
|
||||||
|
|
||||||
|
/// This keeps track of if the font size was ever modified. If it wasn't,
|
||||||
|
/// then config reloading will change the font. If it was manually adjusted,
|
||||||
|
/// we don't change it on config reload since we assume the user wants
|
||||||
|
/// a specific size.
|
||||||
|
font_size_adjusted: bool,
|
||||||
|
|
||||||
/// The renderer for this surface.
|
/// The renderer for this surface.
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
|
||||||
@@ -514,6 +520,7 @@ pub fn init(
|
|||||||
.rt_surface = rt_surface,
|
.rt_surface = rt_surface,
|
||||||
.font_grid_key = font_grid_key,
|
.font_grid_key = font_grid_key,
|
||||||
.font_size = font_size,
|
.font_size = font_size,
|
||||||
|
.font_size_adjusted = false,
|
||||||
.font_metrics = font_grid.metrics,
|
.font_metrics = font_grid.metrics,
|
||||||
.renderer = renderer_impl,
|
.renderer = renderer_impl,
|
||||||
.renderer_thread = render_thread,
|
.renderer_thread = render_thread,
|
||||||
@@ -1446,7 +1453,21 @@ pub fn updateConfig(
|
|||||||
// but this is easier and pretty rare so it's not a performance concern.
|
// but this is easier and pretty rare so it's not a performance concern.
|
||||||
//
|
//
|
||||||
// (Calling setFontSize builds and sends a new font grid to the renderer.)
|
// (Calling setFontSize builds and sends a new font grid to the renderer.)
|
||||||
try self.setFontSize(self.font_size);
|
try self.setFontSize(font_size: {
|
||||||
|
// If we have manually adjusted the font size, keep it that way.
|
||||||
|
if (self.font_size_adjusted) {
|
||||||
|
log.info("font size manually adjusted, preserving previous size on config reload", .{});
|
||||||
|
break :font_size self.font_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we haven't, then we update to the configured font size.
|
||||||
|
// This allows config changes to update the font size. We used to
|
||||||
|
// never do this but it was a common source of confusion and people
|
||||||
|
// assumed that Ghostty was broken! This logic makes more sense.
|
||||||
|
var size = self.font_size;
|
||||||
|
size.points = std.math.clamp(config.@"font-size", 1.0, 255.0);
|
||||||
|
break :font_size size;
|
||||||
|
});
|
||||||
|
|
||||||
// We need to store our configs in a heap-allocated pointer so that
|
// We need to store our configs in a heap-allocated pointer so that
|
||||||
// our messages aren't huge.
|
// our messages aren't huge.
|
||||||
@@ -3991,7 +4012,7 @@ pub fn cursorPosCallback(
|
|||||||
|
|
||||||
// Stop selection scrolling when inside the viewport within a 1px buffer
|
// Stop selection scrolling when inside the viewport within a 1px buffer
|
||||||
// for fullscreen windows, but only when selection scrolling is active.
|
// for fullscreen windows, but only when selection scrolling is active.
|
||||||
if (pos.x >= 1 and pos.y >= 1 and self.selection_scroll_active) {
|
if (pos.y >= 1 and self.selection_scroll_active) {
|
||||||
self.io.queueMessage(
|
self.io.queueMessage(
|
||||||
.{ .selection_scroll = false },
|
.{ .selection_scroll = false },
|
||||||
.locked,
|
.locked,
|
||||||
@@ -4637,10 +4658,13 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
|
|
||||||
log.debug("increase font size={}", .{clamped_delta});
|
log.debug("increase font size={}", .{clamped_delta});
|
||||||
|
|
||||||
var size = self.font_size;
|
|
||||||
// Max point size is somewhat arbitrary.
|
// Max point size is somewhat arbitrary.
|
||||||
|
var size = self.font_size;
|
||||||
size.points = @min(size.points + clamped_delta, 255);
|
size.points = @min(size.points + clamped_delta, 255);
|
||||||
try self.setFontSize(size);
|
try self.setFontSize(size);
|
||||||
|
|
||||||
|
// Mark that we manually adjusted the font size
|
||||||
|
self.font_size_adjusted = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
.decrease_font_size => |delta| {
|
.decrease_font_size => |delta| {
|
||||||
@@ -4652,6 +4676,9 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
var size = self.font_size;
|
var size = self.font_size;
|
||||||
size.points = @max(1, size.points - clamped_delta);
|
size.points = @max(1, size.points - clamped_delta);
|
||||||
try self.setFontSize(size);
|
try self.setFontSize(size);
|
||||||
|
|
||||||
|
// Mark that we manually adjusted the font size
|
||||||
|
self.font_size_adjusted = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
.reset_font_size => {
|
.reset_font_size => {
|
||||||
@@ -4660,6 +4687,9 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
var size = self.font_size;
|
var size = self.font_size;
|
||||||
size.points = self.config.original_font_size;
|
size.points = self.config.original_font_size;
|
||||||
try self.setFontSize(size);
|
try self.setFontSize(size);
|
||||||
|
|
||||||
|
// Reset font size also resets the manual adjustment state
|
||||||
|
self.font_size_adjusted = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
.set_font_size => |points| {
|
.set_font_size => |points| {
|
||||||
@@ -4668,6 +4698,9 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
var size = self.font_size;
|
var size = self.font_size;
|
||||||
size.points = std.math.clamp(points, 1.0, 255.0);
|
size.points = std.math.clamp(points, 1.0, 255.0);
|
||||||
try self.setFontSize(size);
|
try self.setFontSize(size);
|
||||||
|
|
||||||
|
// Mark that we manually adjusted the font size
|
||||||
|
self.font_size_adjusted = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
.prompt_surface_title => return try self.rt_app.performAction(
|
.prompt_surface_title => return try self.rt_app.performAction(
|
||||||
|
@@ -23,6 +23,7 @@ pub const embedded = @import("apprt/embedded.zig");
|
|||||||
pub const surface = @import("apprt/surface.zig");
|
pub const surface = @import("apprt/surface.zig");
|
||||||
|
|
||||||
pub const Action = action.Action;
|
pub const Action = action.Action;
|
||||||
|
pub const Runtime = @import("apprt/runtime.zig").Runtime;
|
||||||
pub const Target = action.Target;
|
pub const Target = action.Target;
|
||||||
|
|
||||||
pub const ContentScale = structs.ContentScale;
|
pub const ContentScale = structs.ContentScale;
|
||||||
@@ -51,30 +52,6 @@ pub const runtime = switch (build_config.artifact) {
|
|||||||
pub const App = runtime.App;
|
pub const App = runtime.App;
|
||||||
pub const Surface = runtime.Surface;
|
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 {
|
test {
|
||||||
_ = Runtime;
|
_ = Runtime;
|
||||||
_ = runtime;
|
_ = runtime;
|
||||||
|
@@ -569,6 +569,15 @@ pub const SetTitle = struct {
|
|||||||
.title = self.title.ptr,
|
.title = self.title.ptr,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format(
|
||||||
|
value: @This(),
|
||||||
|
comptime _: []const u8,
|
||||||
|
_: std.fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
try writer.print("{s}{{ {s} }}", .{ @typeName(@This()), value.title });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Pwd = struct {
|
pub const Pwd = struct {
|
||||||
@@ -584,6 +593,15 @@ pub const Pwd = struct {
|
|||||||
.pwd = self.pwd.ptr,
|
.pwd = self.pwd.ptr,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format(
|
||||||
|
value: @This(),
|
||||||
|
comptime _: []const u8,
|
||||||
|
_: std.fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
try writer.print("{s}{{ {s} }}", .{ @typeName(@This()), value.pwd });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The desktop notification to show.
|
/// The desktop notification to show.
|
||||||
@@ -603,6 +621,19 @@ pub const DesktopNotification = struct {
|
|||||||
.body = self.body.ptr,
|
.body = self.body.ptr,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format(
|
||||||
|
value: @This(),
|
||||||
|
comptime _: []const u8,
|
||||||
|
_: std.fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
try writer.print("{s}{{ title: {s}, body: {s} }}", .{
|
||||||
|
@typeName(@This()),
|
||||||
|
value.title,
|
||||||
|
value.body,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const KeySequence = union(enum) {
|
pub const KeySequence = union(enum) {
|
||||||
|
@@ -3,7 +3,7 @@ const internal_os = @import("../os/main.zig");
|
|||||||
// The required comptime API for any apprt.
|
// The required comptime API for any apprt.
|
||||||
pub const App = @import("gtk/App.zig");
|
pub const App = @import("gtk/App.zig");
|
||||||
pub const Surface = @import("gtk/Surface.zig");
|
pub const Surface = @import("gtk/Surface.zig");
|
||||||
pub const resourcesDir = internal_os.resourcesDir;
|
pub const resourcesDir = @import("gtk/flatpak.zig").resourcesDir;
|
||||||
|
|
||||||
// The exported API, custom for the apprt.
|
// The exported API, custom for the apprt.
|
||||||
pub const class = @import("gtk/class.zig");
|
pub const class = @import("gtk/class.zig");
|
||||||
|
@@ -42,6 +42,70 @@ const GlobalShortcuts = @import("global_shortcuts.zig").GlobalShortcuts;
|
|||||||
|
|
||||||
const log = std.log.scoped(.gtk_ghostty_application);
|
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.
|
/// The primary entrypoint for the Ghostty GTK application.
|
||||||
///
|
///
|
||||||
/// This requires a `ghostty.App` and `ghostty.Config` and takes
|
/// This requires a `ghostty.App` and `ghostty.Config` and takes
|
||||||
@@ -177,6 +241,10 @@ pub const Application = extern struct {
|
|||||||
) Allocator.Error!*Self {
|
) Allocator.Error!*Self {
|
||||||
const alloc = core_app.alloc;
|
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
|
// Log our GTK versions
|
||||||
gtk_version.logVersion();
|
gtk_version.logVersion();
|
||||||
adw_version.logVersion();
|
adw_version.logVersion();
|
||||||
@@ -741,6 +809,10 @@ pub const Application = extern struct {
|
|||||||
|
|
||||||
const writer = buf.writer(alloc);
|
const writer = buf.writer(alloc);
|
||||||
|
|
||||||
|
// Load standard css first as it can override some of the user configured styling.
|
||||||
|
try loadRuntimeCss414(config, &writer);
|
||||||
|
try loadRuntimeCss416(config, &writer);
|
||||||
|
|
||||||
const unfocused_fill: CoreConfig.Color = config.@"unfocused-split-fill" orelse config.background;
|
const unfocused_fill: CoreConfig.Color = config.@"unfocused-split-fill" orelse config.background;
|
||||||
|
|
||||||
try writer.print(
|
try writer.print(
|
||||||
@@ -779,9 +851,6 @@ pub const Application = extern struct {
|
|||||||
, .{ .font_family = font_family });
|
, .{ .font_family = font_family });
|
||||||
}
|
}
|
||||||
|
|
||||||
try loadRuntimeCss414(config, &writer);
|
|
||||||
try loadRuntimeCss416(config, &writer);
|
|
||||||
|
|
||||||
// ensure that we have a sentinel
|
// ensure that we have a sentinel
|
||||||
try writer.writeByte(0);
|
try writer.writeByte(0);
|
||||||
|
|
||||||
|
@@ -112,6 +112,25 @@ pub const SplitTree = extern struct {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const @"is-split" = struct {
|
||||||
|
pub const name = "is-split";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.default = false,
|
||||||
|
.accessor = gobject.ext.typedAccessor(
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.getter = getIsSplit,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const signals = struct {
|
pub const signals = struct {
|
||||||
@@ -210,6 +229,14 @@ pub const SplitTree = extern struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind is-split property for new surface
|
||||||
|
_ = self.as(gobject.Object).bindProperty(
|
||||||
|
"is-split",
|
||||||
|
surface.as(gobject.Object),
|
||||||
|
"is-split",
|
||||||
|
.{ .sync_create = true },
|
||||||
|
);
|
||||||
|
|
||||||
// Create our tree
|
// Create our tree
|
||||||
var single_tree = try Surface.Tree.init(alloc, surface);
|
var single_tree = try Surface.Tree.init(alloc, surface);
|
||||||
defer single_tree.deinit();
|
defer single_tree.deinit();
|
||||||
@@ -511,6 +538,18 @@ pub const SplitTree = extern struct {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getIsSplit(self: *Self) bool {
|
||||||
|
const tree: *const Surface.Tree = self.private().tree orelse &.empty;
|
||||||
|
if (tree.isEmpty()) return false;
|
||||||
|
|
||||||
|
const root_handle: Surface.Tree.Node.Handle = .root;
|
||||||
|
const root = tree.nodes[root_handle.idx()];
|
||||||
|
return switch (root) {
|
||||||
|
.leaf => false,
|
||||||
|
.split => true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Virtual methods
|
// Virtual methods
|
||||||
|
|
||||||
@@ -816,6 +855,9 @@ pub const SplitTree = extern struct {
|
|||||||
v.grabFocus();
|
v.grabFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Our split status may have changed
|
||||||
|
self.as(gobject.Object).notifyByPspec(properties.@"is-split".impl.param_spec);
|
||||||
|
|
||||||
// Our active surface may have changed
|
// Our active surface may have changed
|
||||||
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
|
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
|
||||||
|
|
||||||
@@ -873,6 +915,7 @@ pub const SplitTree = extern struct {
|
|||||||
properties.@"has-surfaces".impl,
|
properties.@"has-surfaces".impl,
|
||||||
properties.@"is-zoomed".impl,
|
properties.@"is-zoomed".impl,
|
||||||
properties.tree.impl,
|
properties.tree.impl,
|
||||||
|
properties.@"is-split".impl,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bindings
|
// Bindings
|
||||||
|
@@ -9,6 +9,7 @@ const gobject = @import("gobject");
|
|||||||
const gtk = @import("gtk");
|
const gtk = @import("gtk");
|
||||||
|
|
||||||
const apprt = @import("../../../apprt.zig");
|
const apprt = @import("../../../apprt.zig");
|
||||||
|
const build_config = @import("../../../build_config.zig");
|
||||||
const datastruct = @import("../../../datastruct/main.zig");
|
const datastruct = @import("../../../datastruct/main.zig");
|
||||||
const font = @import("../../../font/main.zig");
|
const font = @import("../../../font/main.zig");
|
||||||
const input = @import("../../../input.zig");
|
const input = @import("../../../input.zig");
|
||||||
@@ -274,6 +275,24 @@ pub const Surface = extern struct {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const @"is-split" = struct {
|
||||||
|
pub const name = "is-split";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.default = false,
|
||||||
|
.accessor = gobject.ext.privateFieldAccessor(
|
||||||
|
Self,
|
||||||
|
Private,
|
||||||
|
&Private.offset,
|
||||||
|
"is_split",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const signals = struct {
|
pub const signals = struct {
|
||||||
@@ -502,6 +521,10 @@ pub const Surface = extern struct {
|
|||||||
/// A weak reference to an inspector window.
|
/// A weak reference to an inspector window.
|
||||||
inspector: ?*InspectorWindow = null,
|
inspector: ?*InspectorWindow = null,
|
||||||
|
|
||||||
|
// True if the current surface is a split, this is used to apply
|
||||||
|
// unfocused-split-* options
|
||||||
|
is_split: bool = false,
|
||||||
|
|
||||||
// Template binds
|
// Template binds
|
||||||
child_exited_overlay: *ChildExited,
|
child_exited_overlay: *ChildExited,
|
||||||
context_menu: *gtk.PopoverMenu,
|
context_menu: *gtk.PopoverMenu,
|
||||||
@@ -600,6 +623,16 @@ pub const Surface = extern struct {
|
|||||||
return @intFromBool(config.@"bell-features".border);
|
return @intFromBool(config.@"bell-features".border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Callback used to determine whether unfocused-split-fill / unfocused-split-opacity
|
||||||
|
/// should be applied to the surface
|
||||||
|
fn closureShouldUnfocusedSplitBeShown(
|
||||||
|
_: *Self,
|
||||||
|
focused: c_int,
|
||||||
|
is_split: c_int,
|
||||||
|
) callconv(.c) c_int {
|
||||||
|
return @intFromBool(focused == 0 and is_split != 0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn toggleFullscreen(self: *Self) void {
|
pub fn toggleFullscreen(self: *Self) void {
|
||||||
signals.@"toggle-fullscreen".impl.emit(
|
signals.@"toggle-fullscreen".impl.emit(
|
||||||
self,
|
self,
|
||||||
@@ -1227,19 +1260,11 @@ pub const Surface = extern struct {
|
|||||||
|
|
||||||
// Unset environment varies set by snaps if we're running in a snap.
|
// Unset environment varies set by snaps if we're running in a snap.
|
||||||
// This allows Ghostty to further launch additional snaps.
|
// This allows Ghostty to further launch additional snaps.
|
||||||
if (env.get("SNAP")) |_| {
|
if (comptime build_config.snap) {
|
||||||
env.remove("SNAP");
|
if (env.get("SNAP") != null) try filterSnapPaths(
|
||||||
env.remove("DRIRC_CONFIGDIR");
|
alloc,
|
||||||
env.remove("__EGL_EXTERNAL_PLATFORM_CONFIG_DIRS");
|
&env,
|
||||||
env.remove("__EGL_VENDOR_LIBRARY_DIRS");
|
);
|
||||||
env.remove("LD_LIBRARY_PATH");
|
|
||||||
env.remove("LIBGL_DRIVERS_PATH");
|
|
||||||
env.remove("LIBVA_DRIVERS_PATH");
|
|
||||||
env.remove("VK_LAYER_PATH");
|
|
||||||
env.remove("XLOCALEDIR");
|
|
||||||
env.remove("GDK_PIXBUF_MODULEDIR");
|
|
||||||
env.remove("GDK_PIXBUF_MODULE_FILE");
|
|
||||||
env.remove("GTK_PATH");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a hack because it ties ourselves (optionally) to the
|
// This is a hack because it ties ourselves (optionally) to the
|
||||||
@@ -1253,6 +1278,79 @@ pub const Surface = extern struct {
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Filter out environment variables that start with forbidden prefixes.
|
||||||
|
fn filterSnapPaths(gpa: std.mem.Allocator, env_map: *std.process.EnvMap) !void {
|
||||||
|
comptime assert(build_config.snap);
|
||||||
|
|
||||||
|
const snap_vars = [_][]const u8{
|
||||||
|
"SNAP",
|
||||||
|
"SNAP_USER_COMMON",
|
||||||
|
"SNAP_USER_DATA",
|
||||||
|
"SNAP_DATA",
|
||||||
|
"SNAP_COMMON",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use an arena because everything in this function is temporary.
|
||||||
|
var arena = std.heap.ArenaAllocator.init(gpa);
|
||||||
|
defer arena.deinit();
|
||||||
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
|
var env_to_remove = std.ArrayList([]const u8).init(alloc);
|
||||||
|
var env_to_update = std.ArrayList(struct {
|
||||||
|
key: []const u8,
|
||||||
|
value: []const u8,
|
||||||
|
}).init(alloc);
|
||||||
|
|
||||||
|
var it = env_map.iterator();
|
||||||
|
while (it.next()) |entry| {
|
||||||
|
const key = entry.key_ptr.*;
|
||||||
|
const value = entry.value_ptr.*;
|
||||||
|
|
||||||
|
// Ignore fields we set ourself
|
||||||
|
if (std.mem.eql(u8, key, "TERMINFO")) continue;
|
||||||
|
if (std.mem.startsWith(u8, key, "GHOSTTY")) continue;
|
||||||
|
|
||||||
|
// Any env var starting with SNAP must be removed
|
||||||
|
if (std.mem.startsWith(u8, key, "SNAP_")) {
|
||||||
|
try env_to_remove.append(key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filtered_paths = std.ArrayList([]const u8).init(alloc);
|
||||||
|
defer filtered_paths.deinit();
|
||||||
|
|
||||||
|
var modified = false;
|
||||||
|
var paths = std.mem.splitAny(u8, value, ":");
|
||||||
|
while (paths.next()) |path| {
|
||||||
|
var include = true;
|
||||||
|
for (snap_vars) |k| if (env_map.get(k)) |snap_path| {
|
||||||
|
if (snap_path.len == 0) continue;
|
||||||
|
if (std.mem.startsWith(u8, path, snap_path)) {
|
||||||
|
include = false;
|
||||||
|
modified = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (include) try filtered_paths.append(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
if (filtered_paths.items.len > 0) {
|
||||||
|
const new_value = try std.mem.join(alloc, ":", filtered_paths.items);
|
||||||
|
try env_to_update.append(.{ .key = key, .value = new_value });
|
||||||
|
} else {
|
||||||
|
try env_to_remove.append(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (env_to_update.items) |item| try env_map.put(
|
||||||
|
item.key,
|
||||||
|
item.value,
|
||||||
|
);
|
||||||
|
for (env_to_remove.items) |key| _ = env_map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clipboardRequest(
|
pub fn clipboardRequest(
|
||||||
self: *Self,
|
self: *Self,
|
||||||
clipboard_type: apprt.Clipboard,
|
clipboard_type: apprt.Clipboard,
|
||||||
@@ -2763,6 +2861,7 @@ pub const Surface = extern struct {
|
|||||||
class.bindTemplateCallback("notify_mouse_shape", &propMouseShape);
|
class.bindTemplateCallback("notify_mouse_shape", &propMouseShape);
|
||||||
class.bindTemplateCallback("notify_bell_ringing", &propBellRinging);
|
class.bindTemplateCallback("notify_bell_ringing", &propBellRinging);
|
||||||
class.bindTemplateCallback("should_border_be_shown", &closureShouldBorderBeShown);
|
class.bindTemplateCallback("should_border_be_shown", &closureShouldBorderBeShown);
|
||||||
|
class.bindTemplateCallback("should_unfocused_split_be_shown", &closureShouldUnfocusedSplitBeShown);
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
gobject.ext.registerProperties(class, &.{
|
gobject.ext.registerProperties(class, &.{
|
||||||
@@ -2781,6 +2880,7 @@ pub const Surface = extern struct {
|
|||||||
properties.title.impl,
|
properties.title.impl,
|
||||||
properties.@"title-override".impl,
|
properties.@"title-override".impl,
|
||||||
properties.zoom.impl,
|
properties.zoom.impl,
|
||||||
|
properties.@"is-split".impl,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
|
29
src/apprt/gtk/flatpak.zig
Normal file
29
src/apprt/gtk/flatpak.zig
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const build_config = @import("../../build_config.zig");
|
||||||
|
const internal_os = @import("../../os/main.zig");
|
||||||
|
const glib = @import("glib");
|
||||||
|
|
||||||
|
pub fn resourcesDir(alloc: Allocator) !internal_os.ResourcesDir {
|
||||||
|
if (comptime build_config.flatpak) {
|
||||||
|
// Only consult Flatpak runtime data for host case.
|
||||||
|
if (internal_os.isFlatpak()) {
|
||||||
|
var result: internal_os.ResourcesDir = .{
|
||||||
|
.app_path = try alloc.dupe(u8, "/app/share/ghostty"),
|
||||||
|
};
|
||||||
|
errdefer alloc.free(result.app_path.?);
|
||||||
|
|
||||||
|
const keyfile = glib.KeyFile.new();
|
||||||
|
defer keyfile.unref();
|
||||||
|
|
||||||
|
if (keyfile.loadFromFile("/.flatpak-info", .{}, null) == 0) return result;
|
||||||
|
const app_dir = std.mem.span(keyfile.getString("Instance", "app-path", null)) orelse return result;
|
||||||
|
defer glib.free(app_dir.ptr);
|
||||||
|
|
||||||
|
result.host_path = try std.fs.path.join(alloc, &[_][]const u8{ app_dir, "share", "ghostty" });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return try internal_os.resourcesDir(alloc);
|
||||||
|
}
|
@@ -115,6 +115,20 @@ Overlay terminal_page {
|
|||||||
label: bind template.mouse-hover-url;
|
label: bind template.mouse-hover-url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[overlay]
|
||||||
|
// Apply unfocused-split-fill and unfocused-split-opacity to current surface
|
||||||
|
// this is only applied when a tab has more than one surface
|
||||||
|
Revealer {
|
||||||
|
reveal-child: bind $should_unfocused_split_be_shown(template.focused, template.is-split) as <bool>;
|
||||||
|
transition-duration: 0;
|
||||||
|
|
||||||
|
DrawingArea {
|
||||||
|
styles [
|
||||||
|
"unfocused-split",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Event controllers for interactivity
|
// Event controllers for interactivity
|
||||||
EventControllerFocus {
|
EventControllerFocus {
|
||||||
enter => $focus_enter();
|
enter => $focus_enter();
|
||||||
|
29
src/apprt/runtime.zig
Normal file
29
src/apprt/runtime.zig
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
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,8 @@ const Allocator = std.mem.Allocator;
|
|||||||
const Benchmark = @import("Benchmark.zig");
|
const Benchmark = @import("Benchmark.zig");
|
||||||
const options = @import("options.zig");
|
const options = @import("options.zig");
|
||||||
const UTF8Decoder = @import("../terminal/UTF8Decoder.zig");
|
const UTF8Decoder = @import("../terminal/UTF8Decoder.zig");
|
||||||
const symbols = @import("../unicode/symbols.zig");
|
const symbols = @import("../unicode/symbols_ziglyph.zig");
|
||||||
|
const symbols_table = @import("../unicode/symbols_table.zig").table;
|
||||||
|
|
||||||
const log = std.log.scoped(.@"is-symbol-bench");
|
const log = std.log.scoped(.@"is-symbol-bench");
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ fn stepTable(ptr: *anyopaque) Benchmark.Error!void {
|
|||||||
const cp_, const consumed = d.next(c);
|
const cp_, const consumed = d.next(c);
|
||||||
assert(consumed);
|
assert(consumed);
|
||||||
if (cp_) |cp| {
|
if (cp_) |cp| {
|
||||||
std.mem.doNotOptimizeAway(symbols.table.get(cp));
|
std.mem.doNotOptimizeAway(symbols_table.get(cp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,12 +5,13 @@ const Config = @This();
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const apprt = @import("../apprt.zig");
|
const ApprtRuntime = @import("../apprt/runtime.zig").Runtime;
|
||||||
const font = @import("../font/main.zig");
|
const FontBackend = @import("../font/backend.zig").Backend;
|
||||||
const rendererpkg = @import("../renderer.zig");
|
const RendererBackend = @import("../renderer/backend.zig").Backend;
|
||||||
const Command = @import("../Command.zig");
|
const TerminalBuildOptions = @import("../terminal/build_options.zig").Options;
|
||||||
const XCFramework = @import("GhosttyXCFramework.zig");
|
const XCFramework = @import("GhosttyXCFramework.zig");
|
||||||
const WasmTarget = @import("../os/wasm/target.zig").Target;
|
const WasmTarget = @import("../os/wasm/target.zig").Target;
|
||||||
|
const expandPath = @import("../os/path.zig").expand;
|
||||||
|
|
||||||
const gtk = @import("gtk.zig");
|
const gtk = @import("gtk.zig");
|
||||||
const GitVersion = @import("GitVersion.zig");
|
const GitVersion = @import("GitVersion.zig");
|
||||||
@@ -20,7 +21,7 @@ const GitVersion = @import("GitVersion.zig");
|
|||||||
/// TODO: When Zig 0.14 is released, derive this from build.zig.zon directly.
|
/// 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
|
/// Until then this MUST match build.zig.zon and should always be the
|
||||||
/// _next_ version to release.
|
/// _next_ version to release.
|
||||||
const app_version: std.SemanticVersion = .{ .major = 1, .minor = 2, .patch = 0 };
|
const app_version: std.SemanticVersion = .{ .major = 1, .minor = 2, .patch = 1 };
|
||||||
|
|
||||||
/// Standard build configuration options.
|
/// Standard build configuration options.
|
||||||
optimize: std.builtin.OptimizeMode,
|
optimize: std.builtin.OptimizeMode,
|
||||||
@@ -29,14 +30,15 @@ xcframework_target: XCFramework.Target = .universal,
|
|||||||
wasm_target: WasmTarget,
|
wasm_target: WasmTarget,
|
||||||
|
|
||||||
/// Comptime interfaces
|
/// Comptime interfaces
|
||||||
app_runtime: apprt.Runtime = .none,
|
app_runtime: ApprtRuntime = .none,
|
||||||
renderer: rendererpkg.Impl = .opengl,
|
renderer: RendererBackend = .opengl,
|
||||||
font_backend: font.Backend = .freetype,
|
font_backend: FontBackend = .freetype,
|
||||||
|
|
||||||
/// Feature flags
|
/// Feature flags
|
||||||
x11: bool = false,
|
x11: bool = false,
|
||||||
wayland: bool = false,
|
wayland: bool = false,
|
||||||
sentry: bool = true,
|
sentry: bool = true,
|
||||||
|
simd: bool = true,
|
||||||
i18n: bool = true,
|
i18n: bool = true,
|
||||||
wasm_shared: bool = true,
|
wasm_shared: bool = true,
|
||||||
|
|
||||||
@@ -51,6 +53,7 @@ patch_rpath: ?[]const u8 = null,
|
|||||||
|
|
||||||
/// Artifacts
|
/// Artifacts
|
||||||
flatpak: bool = false,
|
flatpak: bool = false,
|
||||||
|
snap: bool = false,
|
||||||
emit_bench: bool = false,
|
emit_bench: bool = false,
|
||||||
emit_docs: bool = false,
|
emit_docs: bool = false,
|
||||||
emit_exe: bool = false,
|
emit_exe: bool = false,
|
||||||
@@ -126,22 +129,22 @@ pub fn init(b: *std.Build) !Config {
|
|||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Comptime Interfaces
|
// Comptime Interfaces
|
||||||
config.font_backend = b.option(
|
config.font_backend = b.option(
|
||||||
font.Backend,
|
FontBackend,
|
||||||
"font-backend",
|
"font-backend",
|
||||||
"The font backend to use for discovery and rasterization.",
|
"The font backend to use for discovery and rasterization.",
|
||||||
) orelse font.Backend.default(target.result, wasm_target);
|
) orelse FontBackend.default(target.result, wasm_target);
|
||||||
|
|
||||||
config.app_runtime = b.option(
|
config.app_runtime = b.option(
|
||||||
apprt.Runtime,
|
ApprtRuntime,
|
||||||
"app-runtime",
|
"app-runtime",
|
||||||
"The app runtime to use. Not all values supported on all platforms.",
|
"The app runtime to use. Not all values supported on all platforms.",
|
||||||
) orelse apprt.Runtime.default(target.result);
|
) orelse ApprtRuntime.default(target.result);
|
||||||
|
|
||||||
config.renderer = b.option(
|
config.renderer = b.option(
|
||||||
rendererpkg.Impl,
|
RendererBackend,
|
||||||
"renderer",
|
"renderer",
|
||||||
"The app runtime to use. Not all values supported on all platforms.",
|
"The app runtime to use. Not all values supported on all platforms.",
|
||||||
) orelse rendererpkg.Impl.default(target.result, wasm_target);
|
) orelse RendererBackend.default(target.result, wasm_target);
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Feature Flags
|
// Feature Flags
|
||||||
@@ -152,6 +155,12 @@ pub fn init(b: *std.Build) !Config {
|
|||||||
"Build for Flatpak (integrates with Flatpak APIs). Only has an effect targeting Linux.",
|
"Build for Flatpak (integrates with Flatpak APIs). Only has an effect targeting Linux.",
|
||||||
) orelse false;
|
) orelse false;
|
||||||
|
|
||||||
|
config.snap = b.option(
|
||||||
|
bool,
|
||||||
|
"snap",
|
||||||
|
"Build for Snap (do specific Snap operations). Only has an effect targeting Linux.",
|
||||||
|
) orelse false;
|
||||||
|
|
||||||
config.sentry = b.option(
|
config.sentry = b.option(
|
||||||
bool,
|
bool,
|
||||||
"sentry",
|
"sentry",
|
||||||
@@ -166,6 +175,12 @@ 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(
|
config.wayland = b.option(
|
||||||
bool,
|
bool,
|
||||||
"gtk-wayland",
|
"gtk-wayland",
|
||||||
@@ -332,7 +347,7 @@ pub fn init(b: *std.Build) !Config {
|
|||||||
if (system_package) break :emit_docs true;
|
if (system_package) break :emit_docs true;
|
||||||
|
|
||||||
// We only default to true if we can find pandoc.
|
// We only default to true if we can find pandoc.
|
||||||
const path = Command.expandPath(b.allocator, "pandoc") catch
|
const path = expandPath(b.allocator, "pandoc") catch
|
||||||
break :emit_docs false;
|
break :emit_docs false;
|
||||||
defer if (path) |p| b.allocator.free(p);
|
defer if (path) |p| b.allocator.free(p);
|
||||||
break :emit_docs path != null;
|
break :emit_docs path != null;
|
||||||
@@ -442,13 +457,15 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void {
|
|||||||
// We need to break these down individual because addOption doesn't
|
// We need to break these down individual because addOption doesn't
|
||||||
// support all types.
|
// support all types.
|
||||||
step.addOption(bool, "flatpak", self.flatpak);
|
step.addOption(bool, "flatpak", self.flatpak);
|
||||||
|
step.addOption(bool, "snap", self.snap);
|
||||||
step.addOption(bool, "x11", self.x11);
|
step.addOption(bool, "x11", self.x11);
|
||||||
step.addOption(bool, "wayland", self.wayland);
|
step.addOption(bool, "wayland", self.wayland);
|
||||||
step.addOption(bool, "sentry", self.sentry);
|
step.addOption(bool, "sentry", self.sentry);
|
||||||
|
step.addOption(bool, "simd", self.simd);
|
||||||
step.addOption(bool, "i18n", self.i18n);
|
step.addOption(bool, "i18n", self.i18n);
|
||||||
step.addOption(apprt.Runtime, "app_runtime", self.app_runtime);
|
step.addOption(ApprtRuntime, "app_runtime", self.app_runtime);
|
||||||
step.addOption(font.Backend, "font_backend", self.font_backend);
|
step.addOption(FontBackend, "font_backend", self.font_backend);
|
||||||
step.addOption(rendererpkg.Impl, "renderer", self.renderer);
|
step.addOption(RendererBackend, "renderer", self.renderer);
|
||||||
step.addOption(ExeEntrypoint, "exe_entrypoint", self.exe_entrypoint);
|
step.addOption(ExeEntrypoint, "exe_entrypoint", self.exe_entrypoint);
|
||||||
step.addOption(WasmTarget, "wasm_target", self.wasm_target);
|
step.addOption(WasmTarget, "wasm_target", self.wasm_target);
|
||||||
step.addOption(bool, "wasm_shared", self.wasm_shared);
|
step.addOption(bool, "wasm_shared", self.wasm_shared);
|
||||||
@@ -474,6 +491,23 @@ 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,
|
||||||
|
.slow_runtime_safety = switch (self.optimize) {
|
||||||
|
.Debug => true,
|
||||||
|
.ReleaseSafe,
|
||||||
|
.ReleaseSmall,
|
||||||
|
.ReleaseFast,
|
||||||
|
=> false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a baseline CPU target retaining all the other CPU configs.
|
/// Returns a baseline CPU target retaining all the other CPU configs.
|
||||||
pub fn baselineTarget(self: *const Config) std.Build.ResolvedTarget {
|
pub fn baselineTarget(self: *const Config) std.Build.ResolvedTarget {
|
||||||
// Set our cpu model as baseline. There may need to be other modifications
|
// Set our cpu model as baseline. There may need to be other modifications
|
||||||
@@ -503,9 +537,10 @@ pub fn fromOptions() Config {
|
|||||||
|
|
||||||
.version = options.app_version,
|
.version = options.app_version,
|
||||||
.flatpak = options.flatpak,
|
.flatpak = options.flatpak,
|
||||||
.app_runtime = std.meta.stringToEnum(apprt.Runtime, @tagName(options.app_runtime)).?,
|
.app_runtime = std.meta.stringToEnum(ApprtRuntime, @tagName(options.app_runtime)).?,
|
||||||
.font_backend = std.meta.stringToEnum(font.Backend, @tagName(options.font_backend)).?,
|
.font_backend = std.meta.stringToEnum(FontBackend, @tagName(options.font_backend)).?,
|
||||||
.renderer = std.meta.stringToEnum(rendererpkg.Impl, @tagName(options.renderer)).?,
|
.renderer = std.meta.stringToEnum(RendererBackend, @tagName(options.renderer)).?,
|
||||||
|
.snap = options.snap,
|
||||||
.exe_entrypoint = std.meta.stringToEnum(ExeEntrypoint, @tagName(options.exe_entrypoint)).?,
|
.exe_entrypoint = std.meta.stringToEnum(ExeEntrypoint, @tagName(options.exe_entrypoint)).?,
|
||||||
.wasm_target = std.meta.stringToEnum(WasmTarget, @tagName(options.wasm_target)).?,
|
.wasm_target = std.meta.stringToEnum(WasmTarget, @tagName(options.wasm_target)).?,
|
||||||
.wasm_shared = options.wasm_shared,
|
.wasm_shared = options.wasm_shared,
|
||||||
|
@@ -25,11 +25,14 @@ pub fn init(b: *std.Build) !GhosttyFrameData {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const run = b.addRunArtifact(exe);
|
const run = b.addRunArtifact(exe);
|
||||||
|
// Both the compressed framedata and the Zig source file
|
||||||
|
// have to be put in the same directory, since the compressed file
|
||||||
|
// has to be within the source file's include path.
|
||||||
|
const dir = run.addOutputDirectoryArg("framedata");
|
||||||
|
|
||||||
_ = run.addOutputFileArg("framedata.compressed");
|
|
||||||
return .{
|
return .{
|
||||||
.exe = exe,
|
.exe = exe,
|
||||||
.output = run.captureStdOut(),
|
.output = dir.path(b, "framedata.zig"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@ const std = @import("std");
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const Config = @import("Config.zig");
|
const Config = @import("Config.zig");
|
||||||
const gresource = @import("../apprt/gtk/build/gresource.zig");
|
const gresource = @import("../apprt/gtk/build/gresource.zig");
|
||||||
const internal_os = @import("../os/main.zig");
|
const locales = @import("../os/i18n_locales.zig").locales;
|
||||||
|
|
||||||
const domain = "com.mitchellh.ghostty";
|
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);
|
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||||
defer steps.deinit();
|
defer steps.deinit();
|
||||||
|
|
||||||
inline for (internal_os.i18n.locales) |locale| {
|
inline for (locales) |locale| {
|
||||||
// There is no encoding suffix in the LC_MESSAGES path on FreeBSD,
|
// 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.
|
// so we need to remove it from `locale` to have a correct destination string.
|
||||||
// (/usr/local/share/locale/en_AU/LC_MESSAGES)
|
// (/usr/local/share/locale/en_AU/LC_MESSAGES)
|
||||||
@@ -155,7 +155,7 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step {
|
|||||||
"po/" ++ domain ++ ".pot",
|
"po/" ++ domain ++ ".pot",
|
||||||
);
|
);
|
||||||
|
|
||||||
inline for (internal_os.i18n.locales) |locale| {
|
inline for (locales) |locale| {
|
||||||
const msgmerge = b.addSystemCommand(&.{ "msgmerge", "--quiet", "--no-fuzzy-matching" });
|
const msgmerge = b.addSystemCommand(&.{ "msgmerge", "--quiet", "--no-fuzzy-matching" });
|
||||||
msgmerge.addFileArg(b.path("po/" ++ locale ++ ".po"));
|
msgmerge.addFileArg(b.path("po/" ++ locale ++ ".po"));
|
||||||
msgmerge.addFileArg(xgettext.captureStdOut());
|
msgmerge.addFileArg(xgettext.captureStdOut());
|
||||||
|
87
src/build/GhosttyLibVt.zig
Normal file
87
src/build/GhosttyLibVt.zig
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
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,
|
||||||
|
});
|
||||||
|
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,9 +5,6 @@ const builtin = @import("builtin");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const buildpkg = @import("main.zig");
|
const buildpkg = @import("main.zig");
|
||||||
const Config = @import("Config.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;
|
const RunStep = std.Build.Step.Run;
|
||||||
|
|
||||||
steps: []*std.Build.Step,
|
steps: []*std.Build.Step,
|
||||||
@@ -16,6 +13,19 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||||
errdefer steps.deinit();
|
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
|
||||||
terminfo: {
|
terminfo: {
|
||||||
const os_tag = cfg.target.result.os.tag;
|
const os_tag = cfg.target.result.os.tag;
|
||||||
@@ -25,13 +35,10 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
"terminfo";
|
"terminfo";
|
||||||
|
|
||||||
// Encode our terminfo
|
// Encode our terminfo
|
||||||
var str = std.ArrayList(u8).init(b.allocator);
|
const run = b.addRunArtifact(build_data_exe);
|
||||||
defer str.deinit();
|
run.addArg("+terminfo");
|
||||||
try terminfo.ghostty.encode(str.writer());
|
const wf = b.addWriteFiles();
|
||||||
|
const source = wf.addCopyFile(run.captureStdOut(), "ghostty.terminfo");
|
||||||
// Write it
|
|
||||||
var wf = b.addWriteFiles();
|
|
||||||
const source = wf.add("ghostty.terminfo", str.items);
|
|
||||||
|
|
||||||
if (cfg.emit_terminfo) {
|
if (cfg.emit_terminfo) {
|
||||||
const source_install = b.addInstallFile(
|
const source_install = b.addInstallFile(
|
||||||
@@ -130,8 +137,10 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
|
|
||||||
// Fish shell completions
|
// Fish shell completions
|
||||||
{
|
{
|
||||||
|
const run = b.addRunArtifact(build_data_exe);
|
||||||
|
run.addArg("+fish");
|
||||||
const wf = b.addWriteFiles();
|
const wf = b.addWriteFiles();
|
||||||
_ = wf.add("ghostty.fish", buildpkg.fish_completions);
|
_ = wf.addCopyFile(run.captureStdOut(), "ghostty.fish");
|
||||||
|
|
||||||
const install_step = b.addInstallDirectory(.{
|
const install_step = b.addInstallDirectory(.{
|
||||||
.source_dir = wf.getDirectory(),
|
.source_dir = wf.getDirectory(),
|
||||||
@@ -143,8 +152,10 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
|
|
||||||
// zsh shell completions
|
// zsh shell completions
|
||||||
{
|
{
|
||||||
|
const run = b.addRunArtifact(build_data_exe);
|
||||||
|
run.addArg("+zsh");
|
||||||
const wf = b.addWriteFiles();
|
const wf = b.addWriteFiles();
|
||||||
_ = wf.add("_ghostty", buildpkg.zsh_completions);
|
_ = wf.addCopyFile(run.captureStdOut(), "_ghostty");
|
||||||
|
|
||||||
const install_step = b.addInstallDirectory(.{
|
const install_step = b.addInstallDirectory(.{
|
||||||
.source_dir = wf.getDirectory(),
|
.source_dir = wf.getDirectory(),
|
||||||
@@ -156,8 +167,10 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
|
|
||||||
// bash shell completions
|
// bash shell completions
|
||||||
{
|
{
|
||||||
|
const run = b.addRunArtifact(build_data_exe);
|
||||||
|
run.addArg("+bash");
|
||||||
const wf = b.addWriteFiles();
|
const wf = b.addWriteFiles();
|
||||||
_ = wf.add("ghostty.bash", buildpkg.bash_completions);
|
_ = wf.addCopyFile(run.captureStdOut(), "ghostty.bash");
|
||||||
|
|
||||||
const install_step = b.addInstallDirectory(.{
|
const install_step = b.addInstallDirectory(.{
|
||||||
.source_dir = wf.getDirectory(),
|
.source_dir = wf.getDirectory(),
|
||||||
@@ -167,39 +180,44 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
try steps.append(&install_step.step);
|
try steps.append(&install_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vim plugin
|
// Vim and Neovim plugin
|
||||||
{
|
{
|
||||||
const wf = b.addWriteFiles();
|
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(.{
|
{
|
||||||
|
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(.{
|
||||||
.source_dir = wf.getDirectory(),
|
.source_dir = wf.getDirectory(),
|
||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/vim/vimfiles",
|
.install_subdir = "share/vim/vimfiles",
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(&vim_step.step);
|
||||||
}
|
|
||||||
|
|
||||||
// Neovim plugin
|
const neovim_step = b.addInstallDirectory(.{
|
||||||
// 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(),
|
.source_dir = wf.getDirectory(),
|
||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/nvim/site",
|
.install_subdir = "share/nvim/site",
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(&neovim_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sublime syntax highlighting for bat cli tool
|
// Sublime syntax highlighting for bat cli tool
|
||||||
@@ -209,8 +227,10 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
// the config file within the '~.config/bat' directory
|
// the config file within the '~.config/bat' directory
|
||||||
// (ex: --map-syntax "/Users/user/.config/ghostty/config:Ghostty Config").
|
// (ex: --map-syntax "/Users/user/.config/ghostty/config:Ghostty Config").
|
||||||
{
|
{
|
||||||
|
const run = b.addRunArtifact(build_data_exe);
|
||||||
|
run.addArg("+sublime");
|
||||||
const wf = b.addWriteFiles();
|
const wf = b.addWriteFiles();
|
||||||
_ = wf.add("ghostty.sublime-syntax", config_sublime_syntax.syntax);
|
_ = wf.addCopyFile(run.captureStdOut(), "ghostty.sublime-syntax");
|
||||||
|
|
||||||
const install_step = b.addInstallDirectory(.{
|
const install_step = b.addInstallDirectory(.{
|
||||||
.source_dir = wf.getDirectory(),
|
.source_dir = wf.getDirectory(),
|
||||||
|
49
src/build/GhosttyZig.zig
Normal file
49
src/build/GhosttyZig.zig
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//! 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");
|
||||||
|
|
||||||
|
vt: *std.Build.Module,
|
||||||
|
|
||||||
|
pub fn init(
|
||||||
|
b: *std.Build,
|
||||||
|
cfg: *const Config,
|
||||||
|
deps: *const SharedDeps,
|
||||||
|
) !GhosttyZig {
|
||||||
|
// General build options
|
||||||
|
const general_options = b.addOptions();
|
||||||
|
try cfg.addOptions(general_options);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
const vt = b.addModule("ghostty-vt", .{
|
||||||
|
.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 = vt };
|
||||||
|
}
|
@@ -31,9 +31,14 @@ pub fn init(b: *std.Build, cfg: *const Config) !HelpStrings {
|
|||||||
exe.root_module.addOptions("build_options", options);
|
exe.root_module.addOptions("build_options", options);
|
||||||
|
|
||||||
const help_run = b.addRunArtifact(exe);
|
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 .{
|
return .{
|
||||||
.exe = exe,
|
.exe = exe,
|
||||||
.output = help_run.captureStdOut(),
|
.output = output,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
const SharedDeps = @This();
|
const SharedDeps = @This();
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const Config = @import("Config.zig");
|
const Config = @import("Config.zig");
|
||||||
const HelpStrings = @import("HelpStrings.zig");
|
const HelpStrings = @import("HelpStrings.zig");
|
||||||
const MetallibStep = @import("MetallibStep.zig");
|
const MetallibStep = @import("MetallibStep.zig");
|
||||||
@@ -104,9 +106,25 @@ pub fn add(
|
|||||||
var static_libs = LazyPathList.init(b.allocator);
|
var static_libs = LazyPathList.init(b.allocator);
|
||||||
errdefer static_libs.deinit();
|
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
|
// Every exe gets build options populated
|
||||||
step.root_module.addOptions("build_options", self.options);
|
step.root_module.addOptions("build_options", self.options);
|
||||||
|
|
||||||
|
// Every exe needs the terminal options
|
||||||
|
self.config.terminalOptions().add(b, step.root_module);
|
||||||
|
|
||||||
// Freetype
|
// Freetype
|
||||||
_ = b.systemIntegrationOption("freetype", .{}); // Shows it in help
|
_ = b.systemIntegrationOption("freetype", .{}); // Shows it in help
|
||||||
if (self.config.font_backend.hasFreetype()) {
|
if (self.config.font_backend.hasFreetype()) {
|
||||||
@@ -257,7 +275,7 @@ pub fn add(
|
|||||||
spirv_cross_dep.module("spirv_cross"),
|
spirv_cross_dep.module("spirv_cross"),
|
||||||
);
|
);
|
||||||
if (b.systemIntegrationOption("spirv-cross", .{})) {
|
if (b.systemIntegrationOption("spirv-cross", .{})) {
|
||||||
step.linkSystemLibrary2("spirv-cross", dynamic_link_opts);
|
step.linkSystemLibrary2("spirv-cross-c-shared", dynamic_link_opts);
|
||||||
} else {
|
} else {
|
||||||
step.linkLibrary(spirv_cross_dep.artifact("spirv_cross"));
|
step.linkLibrary(spirv_cross_dep.artifact("spirv_cross"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
@@ -266,21 +284,6 @@ 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
|
// Sentry
|
||||||
if (self.config.sentry) {
|
if (self.config.sentry) {
|
||||||
if (b.lazyDependency("sentry", .{
|
if (b.lazyDependency("sentry", .{
|
||||||
@@ -309,6 +312,13 @@ 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.
|
// Wasm we do manually since it is such a different build.
|
||||||
if (step.rootModuleTarget().cpu.arch == .wasm32) {
|
if (step.rootModuleTarget().cpu.arch == .wasm32) {
|
||||||
if (b.lazyDependency("zig_js", .{
|
if (b.lazyDependency("zig_js", .{
|
||||||
@@ -343,35 +353,8 @@ pub fn add(
|
|||||||
step.addIncludePath(b.path("src/apprt/gtk"));
|
step.addIncludePath(b.path("src/apprt/gtk"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++ files
|
// libcpp is required for various dependencies
|
||||||
step.linkLibCpp();
|
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.
|
// We always require the system SDK so that our system headers are available.
|
||||||
// This makes things like `os/log.h` available for cross-compiling.
|
// This makes things like `os/log.h` available for cross-compiling.
|
||||||
@@ -481,59 +464,43 @@ pub fn add(
|
|||||||
try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin());
|
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
|
// Fonts
|
||||||
{
|
{
|
||||||
// JetBrains Mono
|
// JetBrains Mono
|
||||||
const jb_mono = b.dependency("jetbrains_mono", .{});
|
if (b.lazyDependency("jetbrains_mono", .{})) |jb_mono| {
|
||||||
step.root_module.addAnonymousImport(
|
step.root_module.addAnonymousImport(
|
||||||
"jetbrains_mono_regular",
|
"jetbrains_mono_regular",
|
||||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Regular.ttf") },
|
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Regular.ttf") },
|
||||||
);
|
);
|
||||||
step.root_module.addAnonymousImport(
|
step.root_module.addAnonymousImport(
|
||||||
"jetbrains_mono_bold",
|
"jetbrains_mono_bold",
|
||||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Bold.ttf") },
|
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Bold.ttf") },
|
||||||
);
|
);
|
||||||
step.root_module.addAnonymousImport(
|
step.root_module.addAnonymousImport(
|
||||||
"jetbrains_mono_italic",
|
"jetbrains_mono_italic",
|
||||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Italic.ttf") },
|
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-Italic.ttf") },
|
||||||
);
|
);
|
||||||
step.root_module.addAnonymousImport(
|
step.root_module.addAnonymousImport(
|
||||||
"jetbrains_mono_bold_italic",
|
"jetbrains_mono_bold_italic",
|
||||||
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-BoldItalic.ttf") },
|
.{ .root_source_file = jb_mono.path("fonts/ttf/JetBrainsMono-BoldItalic.ttf") },
|
||||||
);
|
);
|
||||||
step.root_module.addAnonymousImport(
|
step.root_module.addAnonymousImport(
|
||||||
"jetbrains_mono_variable",
|
"jetbrains_mono_variable",
|
||||||
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono[wght].ttf") },
|
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono[wght].ttf") },
|
||||||
);
|
);
|
||||||
step.root_module.addAnonymousImport(
|
step.root_module.addAnonymousImport(
|
||||||
"jetbrains_mono_variable_italic",
|
"jetbrains_mono_variable_italic",
|
||||||
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono-Italic[wght].ttf") },
|
.{ .root_source_file = jb_mono.path("fonts/variable/JetBrainsMono-Italic[wght].ttf") },
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Symbols-only nerd font
|
// Symbols-only nerd font
|
||||||
const nf_symbols = b.dependency("nerd_fonts_symbols_only", .{});
|
if (b.lazyDependency("nerd_fonts_symbols_only", .{})) |nf_symbols| {
|
||||||
step.root_module.addAnonymousImport(
|
step.root_module.addAnonymousImport(
|
||||||
"nerd_fonts_symbols_only",
|
"nerd_fonts_symbols_only",
|
||||||
.{ .root_source_file = nf_symbols.path("SymbolsNerdFont-Regular.ttf") },
|
.{ .root_source_file = nf_symbols.path("SymbolsNerdFont-Regular.ttf") },
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're building an exe then we have additional dependencies.
|
// If we're building an exe then we have additional dependencies.
|
||||||
@@ -615,17 +582,20 @@ fn addGtkNg(
|
|||||||
"plasma_wayland_protocols",
|
"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.
|
// Unwrap or return, there are no more dependencies below.
|
||||||
const wayland_dep = wayland_dep_ orelse break :wayland;
|
const wayland_dep = wayland_dep_ orelse break :wayland;
|
||||||
const wayland_protocols_dep = wayland_protocols_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 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;
|
||||||
|
|
||||||
// Note that zig_wayland cannot be lazy because lazy dependencies
|
const Scanner = zig_wayland_import.Scanner;
|
||||||
// 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, .{
|
const scanner = Scanner.create(zig_wayland_dep.builder, .{
|
||||||
.wayland_xml = wayland_dep.path("protocol/wayland.xml"),
|
.wayland_xml = wayland_dep.path("protocol/wayland.xml"),
|
||||||
.wayland_protocols = wayland_protocols_dep.path(""),
|
.wayland_protocols = wayland_protocols_dep.path(""),
|
||||||
@@ -695,6 +665,79 @@ 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.
|
/// Creates the resources that can be prebuilt for our dist build.
|
||||||
pub fn gtkNgDistResources(
|
pub fn gtkNgDistResources(
|
||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
|
@@ -15,7 +15,7 @@ pub fn init(b: *std.Build) !UnicodeTables {
|
|||||||
const props_exe = b.addExecutable(.{
|
const props_exe = b.addExecutable(.{
|
||||||
.name = "props-unigen",
|
.name = "props-unigen",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/unicode/props.zig"),
|
.root_source_file = b.path("src/unicode/props_ziglyph.zig"),
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
.strip = false,
|
.strip = false,
|
||||||
.omit_frame_pointer = false,
|
.omit_frame_pointer = false,
|
||||||
@@ -26,7 +26,7 @@ pub fn init(b: *std.Build) !UnicodeTables {
|
|||||||
const symbols_exe = b.addExecutable(.{
|
const symbols_exe = b.addExecutable(.{
|
||||||
.name = "symbols-unigen",
|
.name = "symbols-unigen",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/unicode/symbols.zig"),
|
.root_source_file = b.path("src/unicode/symbols_ziglyph.zig"),
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
.strip = false,
|
.strip = false,
|
||||||
.omit_frame_pointer = false,
|
.omit_frame_pointer = false,
|
||||||
@@ -48,22 +48,35 @@ pub fn init(b: *std.Build) !UnicodeTables {
|
|||||||
const props_run = b.addRunArtifact(props_exe);
|
const props_run = b.addRunArtifact(props_exe);
|
||||||
const symbols_run = b.addRunArtifact(symbols_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 .{
|
return .{
|
||||||
.props_exe = props_exe,
|
.props_exe = props_exe,
|
||||||
.symbols_exe = symbols_exe,
|
.symbols_exe = symbols_exe,
|
||||||
.props_output = props_run.captureStdOut(),
|
.props_output = props_output,
|
||||||
.symbols_output = symbols_run.captureStdOut(),
|
.symbols_output = symbols_output,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the "unicode_tables" import.
|
/// Add the "unicode_tables" import.
|
||||||
pub fn addImport(self: *const UnicodeTables, step: *std.Build.Step.Compile) void {
|
pub fn addImport(self: *const UnicodeTables, step: *std.Build.Step.Compile) void {
|
||||||
self.props_output.addStepDependencies(&step.step);
|
self.props_output.addStepDependencies(&step.step);
|
||||||
step.root_module.addAnonymousImport("unicode_tables", .{
|
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", .{
|
||||||
.root_source_file = self.props_output,
|
.root_source_file = self.props_output,
|
||||||
});
|
});
|
||||||
self.symbols_output.addStepDependencies(&step.step);
|
module.addAnonymousImport("symbols_tables", .{
|
||||||
step.root_module.addAnonymousImport("symbols_tables", .{
|
|
||||||
.root_source_file = self.symbols_output,
|
.root_source_file = self.symbols_output,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -9,12 +9,12 @@ pub fn main() !void {
|
|||||||
// Skip the exe name
|
// Skip the exe name
|
||||||
_ = arg_iter.skip();
|
_ = arg_iter.skip();
|
||||||
|
|
||||||
const output_path = arg_iter.next() orelse return error.MissingOutputPath;
|
const out_dir_path = arg_iter.next() orelse return error.MissingOutputPath;
|
||||||
|
const compressed_out = "framedata.compressed";
|
||||||
|
const zig_out = "framedata.zig";
|
||||||
|
|
||||||
const out_dir_path = fs.path.dirname(output_path) orelse return error.InvalidOutputPath;
|
|
||||||
const out_dir = try fs.cwd().openDir(out_dir_path, .{});
|
const out_dir = try fs.cwd().openDir(out_dir_path, .{});
|
||||||
|
const compressed_file = try out_dir.createFile(compressed_out, .{});
|
||||||
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
|
// Join the frames with a null byte. We'll split on this later
|
||||||
const all_frames = try std.mem.join(gpa.allocator(), "\x01", &frames);
|
const all_frames = try std.mem.join(gpa.allocator(), "\x01", &frames);
|
||||||
@@ -23,13 +23,15 @@ pub fn main() !void {
|
|||||||
const reader = fbs.reader();
|
const reader = fbs.reader();
|
||||||
try std.compress.flate.compress(reader, compressed_file.writer(), .{});
|
try std.compress.flate.compress(reader, compressed_file.writer(), .{});
|
||||||
|
|
||||||
const stdout = std.io.getStdOut().writer();
|
const compressed_path = try std.fs.path.join(gpa.allocator(), &.{ out_dir_path, compressed_out });
|
||||||
|
|
||||||
try stdout.print(
|
const zig_file = try out_dir.createFile(zig_out, .{});
|
||||||
|
|
||||||
|
try zig_file.writer().print(
|
||||||
\\//! This file is auto-generated. Do not edit.
|
\\//! This file is auto-generated. Do not edit.
|
||||||
\\
|
\\
|
||||||
\\pub const compressed = @embedFile("{s}");
|
\\pub const compressed = @embedFile("{s}");
|
||||||
, .{output_path});
|
, .{compressed_path});
|
||||||
}
|
}
|
||||||
|
|
||||||
const frames = [_][]const u8{
|
const frames = [_][]const u8{
|
||||||
|
@@ -13,11 +13,13 @@ pub const GhosttyDocs = @import("GhosttyDocs.zig");
|
|||||||
pub const GhosttyExe = @import("GhosttyExe.zig");
|
pub const GhosttyExe = @import("GhosttyExe.zig");
|
||||||
pub const GhosttyFrameData = @import("GhosttyFrameData.zig");
|
pub const GhosttyFrameData = @import("GhosttyFrameData.zig");
|
||||||
pub const GhosttyLib = @import("GhosttyLib.zig");
|
pub const GhosttyLib = @import("GhosttyLib.zig");
|
||||||
|
pub const GhosttyLibVt = @import("GhosttyLibVt.zig");
|
||||||
pub const GhosttyResources = @import("GhosttyResources.zig");
|
pub const GhosttyResources = @import("GhosttyResources.zig");
|
||||||
pub const GhosttyI18n = @import("GhosttyI18n.zig");
|
pub const GhosttyI18n = @import("GhosttyI18n.zig");
|
||||||
pub const GhosttyXcodebuild = @import("GhosttyXcodebuild.zig");
|
pub const GhosttyXcodebuild = @import("GhosttyXcodebuild.zig");
|
||||||
pub const GhosttyXCFramework = @import("GhosttyXCFramework.zig");
|
pub const GhosttyXCFramework = @import("GhosttyXCFramework.zig");
|
||||||
pub const GhosttyWebdata = @import("GhosttyWebdata.zig");
|
pub const GhosttyWebdata = @import("GhosttyWebdata.zig");
|
||||||
|
pub const GhosttyZig = @import("GhosttyZig.zig");
|
||||||
pub const HelpStrings = @import("HelpStrings.zig");
|
pub const HelpStrings = @import("HelpStrings.zig");
|
||||||
pub const SharedDeps = @import("SharedDeps.zig");
|
pub const SharedDeps = @import("SharedDeps.zig");
|
||||||
pub const UnicodeTables = @import("UnicodeTables.zig");
|
pub const UnicodeTables = @import("UnicodeTables.zig");
|
||||||
@@ -28,10 +30,5 @@ pub const LipoStep = @import("LipoStep.zig");
|
|||||||
pub const MetallibStep = @import("MetallibStep.zig");
|
pub const MetallibStep = @import("MetallibStep.zig");
|
||||||
pub const XCFrameworkStep = @import("XCFrameworkStep.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
|
// Helpers
|
||||||
pub const requireZig = @import("zig.zig").requireZig;
|
pub const requireZig = @import("zig.zig").requireZig;
|
||||||
|
@@ -38,9 +38,10 @@ pub const artifact = Artifact.detect();
|
|||||||
const config = BuildConfig.fromOptions();
|
const config = BuildConfig.fromOptions();
|
||||||
pub const exe_entrypoint = config.exe_entrypoint;
|
pub const exe_entrypoint = config.exe_entrypoint;
|
||||||
pub const flatpak = options.flatpak;
|
pub const flatpak = options.flatpak;
|
||||||
|
pub const snap = options.snap;
|
||||||
pub const app_runtime: apprt.Runtime = config.app_runtime;
|
pub const app_runtime: apprt.Runtime = config.app_runtime;
|
||||||
pub const font_backend: font.Backend = config.font_backend;
|
pub const font_backend: font.Backend = config.font_backend;
|
||||||
pub const renderer: rendererpkg.Impl = config.renderer;
|
pub const renderer: rendererpkg.Backend = config.renderer;
|
||||||
pub const i18n: bool = config.i18n;
|
pub const i18n: bool = config.i18n;
|
||||||
|
|
||||||
/// The bundle ID for the app. This is used in many places and is currently
|
/// The bundle ID for the app. This is used in many places and is currently
|
||||||
|
424
src/cli/CommaSplitter.zig
Normal file
424
src/cli/CommaSplitter.zig
Normal file
@@ -0,0 +1,424 @@
|
|||||||
|
//! Iterator to split a string into fields by commas, taking into account
|
||||||
|
//! quotes and escapes.
|
||||||
|
//!
|
||||||
|
//! Supports the same escapes as in Zig literal strings.
|
||||||
|
//!
|
||||||
|
//! Quotes must begin and end with a double quote (`"`). It is an error to not
|
||||||
|
//! end a quote that was begun. To include a double quote inside a quote (or to
|
||||||
|
//! not have a double quote start a quoted section) escape it with a backslash.
|
||||||
|
//!
|
||||||
|
//! Single quotes (`'`) are not special, they do not begin a quoted block.
|
||||||
|
//!
|
||||||
|
//! Zig multiline string literals are NOT supported.
|
||||||
|
//!
|
||||||
|
//! Quotes and escapes are not stripped or decoded, that must be handled as a
|
||||||
|
//! separate step!
|
||||||
|
const CommaSplitter = @This();
|
||||||
|
|
||||||
|
pub const Error = error{
|
||||||
|
UnclosedQuote,
|
||||||
|
UnfinishedEscape,
|
||||||
|
IllegalEscape,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// the string that we are splitting
|
||||||
|
str: []const u8,
|
||||||
|
/// how much of the string has been consumed so far
|
||||||
|
index: usize,
|
||||||
|
|
||||||
|
/// initialize a splitter with the given string
|
||||||
|
pub fn init(str: []const u8) CommaSplitter {
|
||||||
|
return .{
|
||||||
|
.str = str,
|
||||||
|
.index = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return the next field, null if no more fields
|
||||||
|
pub fn next(self: *CommaSplitter) Error!?[]const u8 {
|
||||||
|
if (self.index >= self.str.len) return null;
|
||||||
|
|
||||||
|
// where the current field starts
|
||||||
|
const start = self.index;
|
||||||
|
// state of state machine
|
||||||
|
const State = enum {
|
||||||
|
normal,
|
||||||
|
quoted,
|
||||||
|
escape,
|
||||||
|
hexescape,
|
||||||
|
unicodeescape,
|
||||||
|
};
|
||||||
|
// keep track of the state to return to when done processing an escape
|
||||||
|
// sequence.
|
||||||
|
var last: State = .normal;
|
||||||
|
// used to count number of digits seen in a hex escape
|
||||||
|
var hexescape_digits: usize = 0;
|
||||||
|
// sub-state of parsing hex escapes
|
||||||
|
var unicodeescape_state: enum {
|
||||||
|
start,
|
||||||
|
digits,
|
||||||
|
} = .start;
|
||||||
|
// number of digits in a unicode escape seen so far
|
||||||
|
var unicodeescape_digits: usize = 0;
|
||||||
|
// accumulator for value of unicode escape
|
||||||
|
var unicodeescape_value: usize = 0;
|
||||||
|
|
||||||
|
loop: switch (State.normal) {
|
||||||
|
.normal => {
|
||||||
|
if (self.index >= self.str.len) return self.str[start..];
|
||||||
|
switch (self.str[self.index]) {
|
||||||
|
',' => {
|
||||||
|
self.index += 1;
|
||||||
|
return self.str[start .. self.index - 1];
|
||||||
|
},
|
||||||
|
'"' => {
|
||||||
|
self.index += 1;
|
||||||
|
continue :loop .quoted;
|
||||||
|
},
|
||||||
|
'\\' => {
|
||||||
|
self.index += 1;
|
||||||
|
last = .normal;
|
||||||
|
continue :loop .escape;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
self.index += 1;
|
||||||
|
continue :loop .normal;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.quoted => {
|
||||||
|
if (self.index >= self.str.len) return error.UnclosedQuote;
|
||||||
|
switch (self.str[self.index]) {
|
||||||
|
'"' => {
|
||||||
|
self.index += 1;
|
||||||
|
continue :loop .normal;
|
||||||
|
},
|
||||||
|
'\\' => {
|
||||||
|
self.index += 1;
|
||||||
|
last = .quoted;
|
||||||
|
continue :loop .escape;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
self.index += 1;
|
||||||
|
continue :loop .quoted;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.escape => {
|
||||||
|
if (self.index >= self.str.len) return error.UnfinishedEscape;
|
||||||
|
switch (self.str[self.index]) {
|
||||||
|
'n', 'r', 't', '\\', '\'', '"' => {
|
||||||
|
self.index += 1;
|
||||||
|
continue :loop last;
|
||||||
|
},
|
||||||
|
'x' => {
|
||||||
|
self.index += 1;
|
||||||
|
hexescape_digits = 0;
|
||||||
|
continue :loop .hexescape;
|
||||||
|
},
|
||||||
|
'u' => {
|
||||||
|
self.index += 1;
|
||||||
|
unicodeescape_state = .start;
|
||||||
|
unicodeescape_digits = 0;
|
||||||
|
unicodeescape_value = 0;
|
||||||
|
continue :loop .unicodeescape;
|
||||||
|
},
|
||||||
|
else => return error.IllegalEscape,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.hexescape => {
|
||||||
|
if (self.index >= self.str.len) return error.UnfinishedEscape;
|
||||||
|
switch (self.str[self.index]) {
|
||||||
|
'0'...'9', 'a'...'f', 'A'...'F' => {
|
||||||
|
self.index += 1;
|
||||||
|
hexescape_digits += 1;
|
||||||
|
if (hexescape_digits == 2) continue :loop last;
|
||||||
|
continue :loop .hexescape;
|
||||||
|
},
|
||||||
|
else => return error.IllegalEscape,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.unicodeescape => {
|
||||||
|
if (self.index >= self.str.len) return error.UnfinishedEscape;
|
||||||
|
switch (unicodeescape_state) {
|
||||||
|
.start => {
|
||||||
|
switch (self.str[self.index]) {
|
||||||
|
'{' => {
|
||||||
|
self.index += 1;
|
||||||
|
unicodeescape_value = 0;
|
||||||
|
unicodeescape_state = .digits;
|
||||||
|
continue :loop .unicodeescape;
|
||||||
|
},
|
||||||
|
else => return error.IllegalEscape,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.digits => {
|
||||||
|
switch (self.str[self.index]) {
|
||||||
|
'}' => {
|
||||||
|
self.index += 1;
|
||||||
|
if (unicodeescape_digits == 0) return error.IllegalEscape;
|
||||||
|
continue :loop last;
|
||||||
|
},
|
||||||
|
'0'...'9' => |d| {
|
||||||
|
self.index += 1;
|
||||||
|
unicodeescape_digits += 1;
|
||||||
|
unicodeescape_value <<= 4;
|
||||||
|
unicodeescape_value += d - '0';
|
||||||
|
},
|
||||||
|
'a'...'f' => |d| {
|
||||||
|
self.index += 1;
|
||||||
|
unicodeescape_digits += 1;
|
||||||
|
unicodeescape_value <<= 4;
|
||||||
|
unicodeescape_value += d - 'a';
|
||||||
|
},
|
||||||
|
'A'...'F' => |d| {
|
||||||
|
self.index += 1;
|
||||||
|
unicodeescape_digits += 1;
|
||||||
|
unicodeescape_value <<= 4;
|
||||||
|
unicodeescape_value += d - 'A';
|
||||||
|
},
|
||||||
|
else => return error.IllegalEscape,
|
||||||
|
}
|
||||||
|
if (unicodeescape_value > 0x10ffff) return error.IllegalEscape;
|
||||||
|
continue :loop .unicodeescape;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return any remaining string data, whether it has a comma or not.
|
||||||
|
pub fn rest(self: *CommaSplitter) ?[]const u8 {
|
||||||
|
if (self.index >= self.str.len) return null;
|
||||||
|
defer self.index = self.str.len;
|
||||||
|
return self.str[self.index..];
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 1" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("a,b,c");
|
||||||
|
try testing.expectEqualStrings("a", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("b", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("c", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 2" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("");
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 3" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("a");
|
||||||
|
try testing.expectEqualStrings("a", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 4" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\x5a");
|
||||||
|
try testing.expectEqualStrings("\\x5a", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 5" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("'a',b");
|
||||||
|
try testing.expectEqualStrings("'a'", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("b", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 6" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("'a,b',c");
|
||||||
|
try testing.expectEqualStrings("'a", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("b'", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("c", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 7" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\"a,b\",c");
|
||||||
|
try testing.expectEqualStrings("\"a,b\"", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("c", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 8" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init(" a , b ");
|
||||||
|
try testing.expectEqualStrings(" a ", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings(" b ", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 9" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\x");
|
||||||
|
try testing.expectError(error.UnfinishedEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 10" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\x5");
|
||||||
|
try testing.expectError(error.UnfinishedEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 11" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\u");
|
||||||
|
try testing.expectError(error.UnfinishedEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 12" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\u{");
|
||||||
|
try testing.expectError(error.UnfinishedEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 13" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\u{}");
|
||||||
|
try testing.expectError(error.IllegalEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 14" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\u{h1}");
|
||||||
|
try testing.expectError(error.IllegalEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 15" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\u{10ffff}");
|
||||||
|
try testing.expectEqualStrings("\\u{10ffff}", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 16" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\u{110000}");
|
||||||
|
try testing.expectError(error.IllegalEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 17" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\d");
|
||||||
|
try testing.expectError(error.IllegalEscape, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 18" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\\n\\r\\t\\\"\\'\\\\");
|
||||||
|
try testing.expectEqualStrings("\\n\\r\\t\\\"\\'\\\\", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 19" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\"abc'def'ghi\"");
|
||||||
|
try testing.expectEqualStrings("\"abc'def'ghi\"", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 20" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("\",\",abc");
|
||||||
|
try testing.expectEqualStrings("\",\"", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("abc", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 21" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("'a','b', 'c'");
|
||||||
|
try testing.expectEqualStrings("'a'", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("'b'", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings(" 'c'", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 22" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("abc\"def");
|
||||||
|
try testing.expectError(error.UnclosedQuote, s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 23" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("title:\"Focus Split: Up\",description:\"Focus the split above, if it exists.\",action:goto_split:up");
|
||||||
|
try testing.expectEqualStrings("title:\"Focus Split: Up\"", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("description:\"Focus the split above, if it exists.\"", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("action:goto_split:up", (try s.next()).?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 24" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("a,b,c,def");
|
||||||
|
try testing.expectEqualStrings("a", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("b", (try s.next()).?);
|
||||||
|
try testing.expectEqualStrings("c,def", s.rest().?);
|
||||||
|
try testing.expect(null == try s.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "splitter 25" {
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var s: CommaSplitter = .init("a,\\u{10,df}");
|
||||||
|
try testing.expectEqualStrings("a", (try s.next()).?);
|
||||||
|
try testing.expectError(error.IllegalEscape, s.next());
|
||||||
|
}
|
@@ -7,6 +7,7 @@ const diags = @import("diagnostics.zig");
|
|||||||
const internal_os = @import("../os/main.zig");
|
const internal_os = @import("../os/main.zig");
|
||||||
const Diagnostic = diags.Diagnostic;
|
const Diagnostic = diags.Diagnostic;
|
||||||
const DiagnosticList = diags.DiagnosticList;
|
const DiagnosticList = diags.DiagnosticList;
|
||||||
|
const CommaSplitter = @import("CommaSplitter.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.cli);
|
const log = std.log.scoped(.cli);
|
||||||
|
|
||||||
@@ -527,24 +528,31 @@ pub fn parseAutoStruct(comptime T: type, alloc: Allocator, v: []const u8) !T {
|
|||||||
const FieldSet = std.StaticBitSet(info.fields.len);
|
const FieldSet = std.StaticBitSet(info.fields.len);
|
||||||
var fields_set: FieldSet = .initEmpty();
|
var fields_set: FieldSet = .initEmpty();
|
||||||
|
|
||||||
// We split each value by ","
|
// We split each value by "," allowing for quoting and escaping.
|
||||||
var iter = std.mem.splitSequence(u8, v, ",");
|
var iter: CommaSplitter = .init(v);
|
||||||
loop: while (iter.next()) |entry| {
|
loop: while (try iter.next()) |entry| {
|
||||||
// Find the key/value, trimming whitespace. The value may be quoted
|
// Find the key/value, trimming whitespace. The value may be quoted
|
||||||
// which we strip the quotes from.
|
// which we strip the quotes from.
|
||||||
const idx = mem.indexOf(u8, entry, ":") orelse return error.InvalidValue;
|
const idx = mem.indexOf(u8, entry, ":") orelse return error.InvalidValue;
|
||||||
const key = std.mem.trim(u8, entry[0..idx], whitespace);
|
const key = std.mem.trim(u8, entry[0..idx], whitespace);
|
||||||
|
|
||||||
|
// used if we need to decode a double-quoted string.
|
||||||
|
var buf: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer buf.deinit(alloc);
|
||||||
|
|
||||||
const value = value: {
|
const value = value: {
|
||||||
var value = std.mem.trim(u8, entry[idx + 1 ..], whitespace);
|
const value = std.mem.trim(u8, entry[idx + 1 ..], whitespace);
|
||||||
|
|
||||||
// Detect a quoted string.
|
// Detect a quoted string.
|
||||||
if (value.len >= 2 and
|
if (value.len >= 2 and
|
||||||
value[0] == '"' and
|
value[0] == '"' and
|
||||||
value[value.len - 1] == '"')
|
value[value.len - 1] == '"')
|
||||||
{
|
{
|
||||||
// Trim quotes since our CLI args processor expects
|
// Decode a double-quoted string as a Zig string literal.
|
||||||
// quotes to already be gone.
|
const writer = buf.writer(alloc);
|
||||||
value = value[1 .. value.len - 1];
|
const parsed = try std.zig.string_literal.parseWrite(writer, value);
|
||||||
|
if (parsed == .failure) return error.InvalidValue;
|
||||||
|
break :value buf.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :value value;
|
break :value value;
|
||||||
|
@@ -133,13 +133,23 @@ pub fn run(alloc: Allocator) !u8 {
|
|||||||
// so this is not a big deal.
|
// so this is not a big deal.
|
||||||
comptime assert(builtin.link_libc);
|
comptime assert(builtin.link_libc);
|
||||||
|
|
||||||
const editorZ = try alloc.dupeZ(u8, editor);
|
var buf: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
defer alloc.free(editorZ);
|
errdefer buf.deinit(alloc);
|
||||||
const pathZ = try alloc.dupeZ(u8, path);
|
|
||||||
defer alloc.free(pathZ);
|
const writer = buf.writer(alloc);
|
||||||
|
var shellescape: internal_os.ShellEscapeWriter(std.ArrayListUnmanaged(u8).Writer) = .init(writer);
|
||||||
|
var shellescapewriter = shellescape.writer();
|
||||||
|
|
||||||
|
try writer.writeAll(editor);
|
||||||
|
try writer.writeByte(' ');
|
||||||
|
try shellescapewriter.writeAll(path);
|
||||||
|
|
||||||
|
const command = try buf.toOwnedSliceSentinel(alloc, 0);
|
||||||
|
defer alloc.free(command);
|
||||||
|
|
||||||
const err = std.posix.execvpeZ(
|
const err = std.posix.execvpeZ(
|
||||||
editorZ,
|
"sh",
|
||||||
&.{ editorZ, pathZ },
|
&.{ "sh", "-c", command },
|
||||||
std.c.environ,
|
std.c.environ,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -895,6 +895,42 @@ const Preview = struct {
|
|||||||
config.background.b,
|
config.background.b,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
const cursor_fg: vaxis.Color = if (config.@"cursor-text") |cursor_text| .{
|
||||||
|
.rgb = [_]u8{
|
||||||
|
cursor_text.color.r,
|
||||||
|
cursor_text.color.g,
|
||||||
|
cursor_text.color.b,
|
||||||
|
},
|
||||||
|
} else bg;
|
||||||
|
const cursor_bg: vaxis.Color = if (config.@"cursor-color") |cursor_bg| .{
|
||||||
|
.rgb = [_]u8{
|
||||||
|
cursor_bg.color.r,
|
||||||
|
cursor_bg.color.g,
|
||||||
|
cursor_bg.color.b,
|
||||||
|
},
|
||||||
|
} else fg;
|
||||||
|
const selection_fg: vaxis.Color = if (config.@"selection-foreground") |selection_fg| .{
|
||||||
|
.rgb = [_]u8{
|
||||||
|
selection_fg.color.r,
|
||||||
|
selection_fg.color.g,
|
||||||
|
selection_fg.color.b,
|
||||||
|
},
|
||||||
|
} else bg;
|
||||||
|
const selection_bg: vaxis.Color = if (config.@"selection-background") |selection_bg| .{
|
||||||
|
.rgb = [_]u8{
|
||||||
|
selection_bg.color.r,
|
||||||
|
selection_bg.color.g,
|
||||||
|
selection_bg.color.b,
|
||||||
|
},
|
||||||
|
} else fg;
|
||||||
|
const cursor: vaxis.Style = .{
|
||||||
|
.fg = cursor_fg,
|
||||||
|
.bg = cursor_bg,
|
||||||
|
};
|
||||||
|
const standard_selection: vaxis.Style = .{
|
||||||
|
.fg = selection_fg,
|
||||||
|
.bg = selection_bg,
|
||||||
|
};
|
||||||
const standard: vaxis.Style = .{
|
const standard: vaxis.Style = .{
|
||||||
.fg = fg,
|
.fg = fg,
|
||||||
.bg = bg,
|
.bg = bg,
|
||||||
@@ -1433,11 +1469,8 @@ const Preview = struct {
|
|||||||
&.{
|
&.{
|
||||||
.{ .text = " 14 │ ", .style = color238 },
|
.{ .text = " 14 │ ", .style = color238 },
|
||||||
.{ .text = "try ", .style = color5 },
|
.{ .text = "try ", .style = color5 },
|
||||||
.{ .text = "stdout.print(", .style = standard },
|
.{ .text = "stdout.print(\"{d}\\n\", .{i})", .style = standard_selection },
|
||||||
.{ .text = "\"{d}", .style = color10 },
|
.{ .text = ";", .style = cursor },
|
||||||
.{ .text = "\\n", .style = color12 },
|
|
||||||
.{ .text = "\"", .style = color10 },
|
|
||||||
.{ .text = ", .{i});", .style = standard },
|
|
||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.row_offset = 17,
|
.row_offset = 17,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user