Commit Graph

13884 Commits

Author SHA1 Message Date
Mitchell Hashimoto
ec0a150098 terminal: moveLastRowToNewPage needs to fix up total_rows 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
c9d15949d8 terminal: on reflow OutOfSpace, move last row to new page and try again 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
42321cc7d5 terminal: write to the proper cell 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
97621ece93 terminal: handle reflowRow OutOfSpace by no-op 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
25643ec806 terminal: reflowRow extract writeCell 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
d626984418 terminal: reflowCursor improve error handling on assumed cases 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
6b2455828e terminal: resizeWithoutReflowGrowCols can only fail for OOM 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
e704525887 terminal: PageList remove adjustCapacity 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
b59ac60a87 terminal: remove Screen.adjustCapacity 2026-01-16 13:23:55 -08:00
Mitchell Hashimoto
c8afc42308 terminal: switch to increaseCapacity 2026-01-16 13:09:19 -08:00
Mitchell Hashimoto
25b7cc9f2c terminal: hyperlink state uses increaseCapacity on screen 2026-01-16 13:09:19 -08:00
Mitchell Hashimoto
29d4aba033 terminal: Screen replace adjust with increaseCapacity 2026-01-16 13:09:19 -08:00
Mitchell Hashimoto
1e5973386b terminal: Screen.increaseCapacity 2026-01-16 13:09:19 -08:00
Mitchell Hashimoto
8306f96d94 terminal: PageList.increaseCapacity 2026-01-16 13:07:32 -08:00
Mitchell Hashimoto
95a23f756d terminal: more strict sizing for page capacities, max cap can fit 64-bit 2026-01-16 13:07:32 -08:00
Mitchell Hashimoto
c8295815cb terminal: fix stale cursor pin usage after cursorChangePin (#10348)
Fixes #10282

The function `cursorChangePin` is supposed to be called anytime the
cursor page pin changes, but it itself may alter the page pin if setting
up the underlying managed memory forces a page size adjustment.

Multiple callers to this function were erroneously reusing the old page
pin value.

**AI disclosure:** I had Amp help me write the test. I eyeballed and
found the bug myself, verified it by asking Amp to write the test,
reviewed that manually, then implemented the fixes manually and got it
to pass.
2026-01-16 13:03:09 -08:00
Mitchell Hashimoto
f1dbdc7965 terminal: fix stale cursor pin usage after cursorChangePin
Fixes #10282

The function `cursorChangePin` is supposed to be called anytime the
cursor page pin changes, but it itself may alter the page pin if setting
up the underlying managed memory forces a page size adjustment. 

Multiple callers to this function were erroneously reusing the old page
pin value.
2026-01-16 12:57:29 -08:00
Jon Parise
204170d052 shellcheck: move common directives to .shellcheckrc (#10343)
This simplifies our CI command line and makes it easier to document
expected usage (in HACKING.md).

There unfortunately isn't a way to set --checked-sourced or our default
warning level in .shellcheckrc, and our `find` command is still a bit
unwieldy, but this is still a net improvement.
2026-01-16 10:41:01 -05:00
Jon Parise
bf1ca59196 shellcheck: move common directives to .shellcheckrc
This simplifies our CI command line and makes it easier to document
expected usage (in HACKING.md).

There unfortunately isn't a way to set --checked-sourced or our default
warning level in .shellcheckrc, and our `find` command is still a bit
unwieldy, but this is still a net improvement.
2026-01-16 09:31:11 -05:00
Jon Parise
af2d33895d zsh: strip control characters from window title (#10341)
## Summary
- Fix literal \n appearing in window titles when running commands in zsh

## Description
The zsh shell integration was using ${(V)1} parameter expansion to set
the window title. The (V) flag converts control characters to their
visible escape sequence representations, causing commands ending with a
newline to display as command\n in the title bar.

Changed to use ${1//[[:cntrl:]]} which strips control characters
entirely, matching the behavior of the bash integration.

<img width="231" height="47" alt="image"
src="https://github.com/user-attachments/assets/356c77a1-32da-47b0-bf86-29735cc67e90"
/>

## Test

  - Open Ghostty with zsh shell integration enabled
  - Run a command (e.g., cargo install trunk)

  ---
AI Disclosure: This PR was written primarily by Claude Code. (Opus 4.5)
2026-01-16 09:07:15 -05:00
Jon Parise
ca924f4f45 zsh: improve title-related comment 2026-01-16 08:53:18 -05:00
Julian Haag
3ca8b97ca7 fix(zsh): strip control characters from window title
The zsh shell integration was using `${(V)1}` parameter expansion to set
the window title, which converts control characters to their visible
escape sequence representations. This caused commands ending with a
newline to display as `command\n` in the title bar.

Changed to use `${1//[[:cntrl:]]}` which strips control characters
entirely, matching the behavior of the bash integration.
2026-01-16 10:53:50 +01:00
Mitchell Hashimoto
26e243a919 font/shaper/coretext: Detect ligatures to avoid positioning (marking) glyphs incorrectly (#10295)
This PR implements a heuristic for detecting ligatures that then
prevents resetting to the cell grid prematurely, avoiding position
errors from glyphs that follow ligatures. The inspiration for this was
the example from https://github.com/ghostty-org/ghostty/pull/10179 that
was off.

See the giant comment for an explanation of the heuristic.

The tests for this are the following:

### Tai Tham
The Tai Tham example from
https://github.com/ghostty-org/ghostty/pull/10179 got updated since now
the marking glyph is attached to the ligature cell correctly.

Browser:
ᩉ᩠ᨿᩩ

Before:
<img width="970" height="110" alt="CleanShot 2026-01-12 at 10 02 42@2x"
src="https://github.com/user-attachments/assets/1315bbeb-0541-420a-91a1-bac39897efe3"
/>

After:
<img width="962" height="122" alt="CleanShot 2026-01-12 at 10 02 57@2x"
src="https://github.com/user-attachments/assets/ca2b3e1d-0785-462f-993c-f482d875a1e9"
/>

### Javanese

Browser:
ꦤ꧀ꦲꦸ

Before:
<img width="962" height="98" alt="CleanShot 2026-01-12 at 10 05 43@2x"
src="https://github.com/user-attachments/assets/74002334-7140-4646-806e-2194457e56c5"
/>

After:
<img width="962" height="110" alt="CleanShot 2026-01-12 at 10 05 23@2x"
src="https://github.com/user-attachments/assets/49c08ac9-98af-409c-9b0e-49a34da93597"
/>

There does seem to be a small maybe single pixel difference here, and I
didn't investigate why.

### Chakma

Browser:
𑄝𑄖𑄳𑄠𑄬

Before:
<img width="1406" height="104" alt="CleanShot 2026-01-12 at 10 07 52@2x"
src="https://github.com/user-attachments/assets/3ba7a9d8-d2a2-4e47-976a-8c7702462a49"
/>

After:
<img width="1408" height="104" alt="CleanShot 2026-01-12 at 10 08 08@2x"
src="https://github.com/user-attachments/assets/c25c4a41-b651-4109-8ded-69983fc77267"
/>

### Bengali

Browser:
রাষ্ট্রে

Before:
<img width="1370" height="84" alt="CleanShot 2026-01-12 at 10 10 42@2x"
src="https://github.com/user-attachments/assets/c59e5fc9-0e9e-4c8f-b937-025ad28866d2"
/>

After:
<img width="1370" height="96" alt="CleanShot 2026-01-12 at 10 11 00@2x"
src="https://github.com/user-attachments/assets/d108dcda-b0b5-4824-b3e4-d1e2ddb6d6de"
/>

This one doesn't match the browser, but it seems like a CoreText or font
issue.

### Log output

I've got a `log.txt` with 15k lines from "cell_offset.cluster differs
from cluster (potential ligature detected)" logs when I run
[ttylang](https://github.com/jacobsandlund/ttylang) (printing the
Universal Declaration of Human Rights in various languages).

But right now when I try to create a gist with it, I get:

<img width="1554" height="584" alt="CleanShot 2026-01-12 at 10 15 29@2x"
src="https://github.com/user-attachments/assets/b8a5dd0c-c034-45f6-a2fb-80c67f93f26f"
/>
2026-01-15 08:06:07 -08:00
Mitchell Hashimoto
24b0ff05e2 terminal: parse kitty text sizing protocol (OSC 66), redux (#10315)
#9845 redone to use the new OSC parser

Implements the VT side of #5563
2026-01-15 06:58:47 -08:00
Mitchell Hashimoto
33555be934 build(deps): bump namespacelabs/nscloud-setup-buildx-action from 0.0.20 to 0.0.21 (#10308)
Bumps
[namespacelabs/nscloud-setup-buildx-action](https://github.com/namespacelabs/nscloud-setup-buildx-action)
from 0.0.20 to 0.0.21.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a7e5254161"><code>a7e5254</code></a>
Adopt new wait command in action. (<a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/issues/12">#12</a>)</li>
<li>See full diff in <a
href="91c2e65377...a7e5254161">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=namespacelabs/nscloud-setup-buildx-action&package-manager=github_actions&previous-version=0.0.20&new-version=0.0.21)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2026-01-15 06:57:10 -08:00
Leah Amelia Chen
916b99df7c terminal: parse kitty text sizing protocol (OSC 66), redux
#9845 redone to use the new OSC parser

Implements the VT side of #5563
2026-01-15 00:13:55 +08:00
Ken VanDine
2fd3efd6cd snap: fix handling of nonexistent last_revision file (#10241)
Assuming /bin/sh is symlinked to bash, the handling of special builtin
'source' is slightly different between bash and bash-in-POSIX-mode (as a
result of being invoked through /bin/sh). Specifically errors in builtin
'source' cannot be masked with `|| true`. Compare

```
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Dec 11 11:00 /bin/sh -> bash
$ /bin/sh -c 'set -e ; source nofile || true; echo ok'
/bin/sh: line 1: source: nofile: file not found
$ /bin/bash -c 'set -e ; source nofile || true; echo ok'
/bin/bash: line 1: nofile: No such file or directory
ok
```

Thus ghostty from snap would not start at all when
$SNAP_USER_DATA/.last_revision does not exist causign the launcher
script to exit prematurely.
2026-01-14 09:47:40 -05:00
Jacob Sandlund
54f1a6ce5e Merge remote-tracking branch 'upstream/main' into ligature-detect 2026-01-14 08:56:22 -05:00
Jon Parise
5ff99ba9a0 macos: cycle through our icons in the About view (#10298)
Clicking on the icon immediately advances to the next one. Hovering on
the icon pauses the automatic cycling, and the "help" tooltip displays
the icon's configuration name (for `macos-icon`).

---


https://github.com/user-attachments/assets/5cfbd225-bbdf-4077-96c1-7da315ce02cc
2026-01-14 07:53:51 -05:00
dependabot[bot]
38117f5445 build(deps): bump namespacelabs/nscloud-setup-buildx-action
Bumps [namespacelabs/nscloud-setup-buildx-action](https://github.com/namespacelabs/nscloud-setup-buildx-action) from 0.0.20 to 0.0.21.
- [Release notes](https://github.com/namespacelabs/nscloud-setup-buildx-action/releases)
- [Commits](91c2e65377...a7e5254161)

---
updated-dependencies:
- dependency-name: namespacelabs/nscloud-setup-buildx-action
  dependency-version: 0.0.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-14 00:15:44 +00:00
Jacob Sandlund
55583d9f27 fix Devanagari test 2026-01-13 10:36:20 -05:00
Jacob Sandlund
0becd6a1e1 Merge remote-tracking branch 'upstream/main' into ligature-detect 2026-01-13 09:48:53 -05:00
Jon Parise
1537590a5f macos: cycle through our icons in the About view
Clicking on the icon immediately advances to the next one. Hovering on
the icon pauses the automatic cycling, and the "help" tooltip displays
the icon's configuration name (for `macos-icon`).
2026-01-12 15:20:14 -05:00
Mitchell Hashimoto
c90f47f11f Terminal: keep cross-boundary rows dirty in {insert,delete}Lines (#10290)
This fixes #10265 and thus also the remaining part of #9718 and likely
#10250.

The issue was that when using `insertLines` and `deleteLines` to
generate scrolling in a region that spans a page boundary, rows that are
replaced by a row from a different page lose their dirty flags in the
clone operation, since the flag is part of the data that gets cloned.
The solution is to set the dirty flag again after the clone, just like
the non-cloning branch does after the pointer swap.

**AI disclosure:** Amp is the MVP here. I prompted it with the
hypothesis I developed in #10265 (that this happens when the scrolling
region spans a page boundary), supplemented with insight I gained from
perusing asciicast files (that the offending scrolling operations are
always triggered by `CSI 1 L` or `CSI 1 M`, that is,
`Terminal.insertLines` or `Terminal.deleteLines`). Amp figured out the
rest and drafted the fix and tests. For free!

I cleaned up the tests and then pushed back a bit against the logic
behind the fix, which led to a better understanding and what I think is
a more appropriate fix. I can explain the details if there's interest,
or people can just skim the thread here:
https://ampcode.com/threads/T-019bb0d6-5334-744a-b78a-7c997ec1fade.
2026-01-12 10:21:36 -08:00
Mitchell Hashimoto
136df4a0f5 nix: update nixpkgs, remove zig.hook, and remove x11-gnome (#10286)
As of NixOS/nixpkgs#473413, `zig.hook` no longer supports
`zig_default_flags`, and now they can and must be provided in
`zigBuildFlags` instead.

Updating also requires removing gnome-xorg since it has been removed
from nixpkgs.

`nix flake check` succeeds on my system (x86_64-linux), with a couple
deprecation warnings that I believe aren't important.
2026-01-12 10:20:59 -08:00
MithicSpirit
8f4bfeece5 ci: fix ryand56/r2-upload-action version comment
Does not entail any actual changes in the version, merely in the comment
indicating the used version.

Detected by CI (GitHub Action Pins) after nixpkgs update.
2026-01-12 13:17:27 -05:00
MithicSpirit
2af6e255e4 chore: fix typo curor->cursor (2x)
Detected by CI (typos) after nixpkgs update.
2026-01-12 13:17:05 -05:00
Mitchell Hashimoto
eb462ad66f PageList can initialize with more than ~46,000 columns (#10297)
I've been poking around our internals around overflow cases while
diagnosing systemic ways to fix #10258.

One thing I found is that our terminal internals advertise that they can
accept up to u16 (~65K) rows and columns for the active area, but at
around 46K columns on x86_64 and 47K on aarch64, our terminal initialize
would error out. Worse, we'd actually trigger integer overflow and crash
in safe builds (and have silent corruption in release builds).

In fixing this, I realized we could comptime-verify a bunch of things
and avoid overflows completely. So this diff contains a bunch of places
that previously had error returns and now do not! 😄 This is a bit silly,
but with libghostty it's more relevant to have correctness around the
edges.

We now accept full u16 rows/cols. More than that isn't allowed by the
type system and our upstream callers must handle that appropriately.

cc @qwerasd205 since its relevant to layout fallibility but not on the
same path
2026-01-12 10:16:18 -08:00
Mitchell Hashimoto
5817e1dc5f terminal: PageList can initialize with memory requirements > std 2026-01-12 09:57:20 -08:00
MithicSpirit
d512de7e78 nix: update zon2nix
After the last commit, zon2nix required recompiling zig, which caused
slow build times and CI failures.
2026-01-12 12:53:21 -05:00
Daniel Wennberg
257aafb7b4 Consolidate dirty marking in insertLines/deleteLines 2026-01-12 09:49:08 -08:00
Mitchell Hashimoto
7ed19689b9 terminal: add Capacity.maxCols 2026-01-12 08:53:34 -08:00
Jacob Sandlund
2a0a575065 comment fixup 2026-01-12 10:22:37 -05:00
Jacob Sandlund
9c6f40680c Merge remote-tracking branch 'upstream/main' into ligature-detect 2026-01-12 09:57:05 -05:00
Jacob Sandlund
f37b0c56ec Keep track of run's max cluster seen. 2026-01-12 09:56:31 -05:00
Daniel Wennberg
095c82910b Terminal: keep cross-boundary rows dirty in {insert,delete}Lines 2026-01-11 23:26:46 -08:00
Daniel Wennberg
87b11e0892 Add failing tests for #10265 2026-01-11 23:25:44 -08:00
MithicSpirit
5c8c7c627c nix: update nixpkgs, remove zig.hook, and remove x11-gnome
As of NixOS/nixpkgs#473413[1], `zig.hook` no longer supports
`zig_default_flags`, and now they can and must be provided in
`zigBuildFlags` instead.

Updating also requires removing gnome-xorg since it has been removed
from nixpkgs.

[1] https://github.com/NixOS/nixpkgs/pull/473413
2026-01-11 20:17:12 -05:00
Jon Parise
bb1c3bce10 fix(completions.fish): add +help and +version to completions (#10287)
`+help` and `+version` is missing from completions, even though they are
working actions and are referenced in discussion template
[here](https://github.com/ghostty-org/ghostty/pull/7012). This PR adds
the completion for fish (as that is the shell that I use).
2026-01-11 19:45:25 -05:00
Jon Parise
e47272878d extra: enable +help and +version in bash and zsh 2026-01-11 19:26:27 -05:00