Commit Graph

13545 Commits

Author SHA1 Message Date
Mitchell Hashimoto
c85847c693 Update iTerm2 colorschemes (#9988)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251201-150531-bfb3ee1
2025-12-21 13:18:15 -08:00
Mitchell Hashimoto
56b024d8fc Fix typo (#9998)
This PR fixes a small typo in the documentation.
2025-12-21 10:10:06 -08:00
Henrique Albuquerque
97cd4c71d5 Fix typo 2025-12-21 17:57:23 +00:00
Mitchell Hashimoto
df8dde946d Reset key tables on config reload, bound max active key tables (#9994)
Two unrelated changes to polish key tables:

1. Key tables should be reset (deactivated) when teh config is reloaded.
This matches the behavior of key sequences as well, which are reset on
config reload.

2. A maximum number of active key tables is now enforced (8). This
prevents a misbehaving config from consuming too much memory by
activating too many key tables. This is an arbitrary limit we can adjust
later if needed.
2025-12-21 08:24:25 -08:00
Mitchell Hashimoto
18c8c338e0 Reset key tables on config reload, bound max active key tables
Two unrelated changes to polish key tables:

1. Key tables should be reset (deactivated) when teh config is reloaded.
   This matches the behavior of key sequences as well, which are reset
   on config reload. 

2. A maximum number of active key tables is now enforced (8).
   This prevents a misbehaving config from consuming too much memory
   by activating too many key tables. This is an arbitrary limit we
   can adjust later if needed.
2025-12-21 08:14:37 -08:00
Mitchell Hashimoto
c422650881 Key tables apprt action plus macOS UI (#9990)
Fixes #9963 (we'll open new issues to track GTK and other stuff)

This adds the apprt actions necessary for key tables to be shown
visually, and adapts the macOS UI to show them.

## Demo

```
keybind = example/
keybind = example/ctrl+a=text:hello
keybind = example/ctrl+b>x=text:wow
keybind = example/ctrl+c=activate_key_table:another
keybind = example/escape=deactivate_key_table
keybind = ctrl+a=activate_key_table:example

keybind = another/
keybind = another/catch_all=deactivate_key_table
```


https://github.com/user-attachments/assets/75e94ec9-b52e-439d-b0ca-229ce533c656

**AI disclosure:** The SwiftUI view was written by AI, everything else
was manual.
2025-12-21 08:11:36 -08:00
Lukas
7d3db17396 macOS: key table animations and cleanup 2025-12-21 09:29:47 +01:00
Mitchell Hashimoto
dc8f082392 macos: copy the key table action bytes 2025-12-20 20:36:35 -08:00
Mitchell Hashimoto
eac0ec14fd macOS: revamped key table/sequence UI 2025-12-20 20:27:56 -08:00
Mitchell Hashimoto
901618cd8f macOS: hook up key table apprt action to state 2025-12-20 20:01:38 -08:00
Mitchell Hashimoto
44972198ae apprt: add action for key table activation/deactivation 2025-12-20 19:53:12 -08:00
Mitchell Hashimoto
028691766d Key Tables (#9984)
This does the core implementation of #9963. This implements the config
parsing, bindings (`activate_key_table`, `activate_key_table_once`,
`deactivate_key_table` and `deactivate_all_key_tables`), and core key
handling logic so they work.

I'm not going to close the issue yet because I still want to integrate
GUI onto it so that it's clear you're in a key table (similar to the
sequence UI).

No demos or anything here because it is well explained in #9963.
2025-12-20 19:43:56 -08:00
mitchellh
1fbdcf1ee7 deps: Update iTerm2 color schemes 2025-12-21 00:15:47 +00:00
Mitchell Hashimoto
845bcdb498 config: copy key table name into arena 2025-12-20 15:15:30 -08:00
Mitchell Hashimoto
daa613482e keybind = clear and reset should reset tables, too 2025-12-20 14:57:37 -08:00
Mitchell Hashimoto
14bbc4893f implement one-shot key tables 2025-12-20 14:36:39 -08:00
Mitchell Hashimoto
36f891afd8 implement key table lookup in maybeHandleBinding 2025-12-20 14:30:36 -08:00
Mitchell Hashimoto
18ce219d78 input: activate/deactivate key table binding actions 2025-12-20 14:23:02 -08:00
Mitchell Hashimoto
34ae3848b6 core: key tables 2025-12-20 14:04:11 -08:00
Mitchell Hashimoto
8c59143c1a rename some key sequence state so it is clearer what it is 2025-12-20 14:04:03 -08:00
Mitchell Hashimoto
c53b3fffd5 config: keybind table parsing 2025-12-20 13:32:52 -08:00
Mitchell Hashimoto
aac5d65ded add the catch_all binding key (#9977)
Part of #9963

This adds a new special key `catch_all` that can be used in keybinding
definitions to match any key that is not explicitly bound. For example:
`keybind = catch_all=new_window` (chaos!).

`catch_all` can be used in combination with modifiers, so if you want to
catch any non-bound key with Ctrl held down, you can do: `keybind =
ctrl+catch_all=new_window`.

`catch_all` can also be used with trigger sequences, so you can do:
`keybind = ctrl+a>catch_all=new_window` to catch any key pressed after
`ctrl+a` that is not explicitly bound and make a new window!

And if you want to remove the catch all binding, it is like any other:
`keybind = catch_all=unbind`.
2025-12-20 13:13:19 -08:00
Mitchell Hashimoto
63422f4d4e add the catch_all binding key
Part of #9963

This adds a new special key `catch_all` that can be used in keybinding
definitions to match any key that is not explicitly bound. For example:
`keybind = catch_all=new_window` (chaos!). 

`catch_all` can be used in combination with modifiers, so if you want to
catch any non-bound key with Ctrl held down, you can do:
`keybind = ctrl+catch_all=new_window`.

`catch_all` can also be used with trigger sequences, so you can do:
`keybind = ctrl+a>catch_all=new_window` to catch any key pressed after
`ctrl+a` that is not explicitly bound and make a new window!

And if you want to remove the catch all binding, it is like any other:
`keybind = catch_all=unbind`.
2025-12-19 15:03:38 -08:00
Mitchell Hashimoto
73a93abf7b renderer/metal: clamp texture sizes to the maximum allowed by the device (#9972)
This prevents a crash in our renderer when it is larger.

I will pair this with apprt changes so that our mac app won't ever allow
a default window larger than the screen but we should be resilient at
the renderer level as well.
2025-12-19 10:39:06 -08:00
Mitchell Hashimoto
2e4b11a4d7 macos: window width/height should be clamped, work with position (#9975)
Fixes #9952
Fixes #9969

This fixes our `constrainToScreen` implementation to properly clamp the
window size to the visible screen its coming on as documented. Further,
this addresses the positioning problem, too.
2025-12-19 10:38:57 -08:00
Mitchell Hashimoto
d1bea9d737 macos: window width/height should be clamped, work with position
Fixes #9952
Fixes #9969

This fixes our `constrainToScreen` implementation to properly clamp the
window size to the visible screen its coming on as documented. Further,
this addresses the positioning problem, too.
2025-12-19 10:30:03 -08:00
Mitchell Hashimoto
594195963d Update src/renderer/Metal.zig
Co-authored-by: Jon Parise <jon@indelible.org>
2025-12-19 09:31:10 -08:00
Mitchell Hashimoto
07b47b87fa renderer/metal: clamp texture sizes to the maximum allowed by the device
This prevents a crash in our renderer when it is larger.

I will pair this with apprt changes so that our mac app won't ever allow
a default window larger than the screen but we should be resilient at
the renderer level as well.
2025-12-19 09:24:49 -08:00
Mitchell Hashimoto
e2be65da8e macos: hide tab overview on escape (#9971)
This hides the macOS tab overview when the `escape` key is pressed.

Our solution is a bit blunt here and I don't think its right. I think we
have a first responder problem somewhere but I haven't been able to find
it and find the proper place to implement `cancel` (or equivalent) to
hide the overview. I tried implementing `cancel` in all the places I
expect the responder chain to go through but none worked.

For now let's do this since it is pretty tightly scoped!
2025-12-19 07:18:32 -08:00
Mitchell Hashimoto
86a0eb1a75 macos: hide tab overview on escape
This hides the macOS tab overview when the `escape` key is pressed.

Our solution is a bit blunt here and I don't think its right. I think we
have a first responder problem somewhere but I haven't been able to find
it and find the proper place to implement `cancel` (or equivalent) to
hide the overview. I tried implementing `cancel` in all the places I
expect the responder chain to go through but none worked.

For now let's do this since it is pretty tightly scoped!
2025-12-19 07:13:47 -08:00
Mitchell Hashimoto
fa0a982ff2 macos: remove the command palette appear/disappear animation (#9964)
Lots of people complained about this and I don't see value in it.
2025-12-18 15:41:55 -08:00
Mitchell Hashimoto
0ace736f46 macos: remove the command palette appear/disappear animation
Lots of people complained about this and I don't see value in it.
2025-12-18 15:36:11 -08:00
Mitchell Hashimoto
faa22c032e terminal: RenderState linkCells needs to use Page y not Viewport y (#9959)
Fixes #9957

Our `Page.getRowAndCell` uses a _page-relative_ x/y coordinate system
and we were passing in viewport x/y. This has the possibility to leading
to all sorts of bugs, including the crash found in #9957 but also simply
reading the wrong cell even in single-page scenarios.
2025-12-18 14:06:02 -08:00
Mitchell Hashimoto
5a2f5a6b9e terminal: RenderState linkCells needs to use Page y not Viewport y
Fixes #9957

Our `Page.getRowAndCell` uses a _page-relative_ x/y coordinate system
and we were passing in viewport x/y. This has the possibility to leading
to all sorts of bugs, including the crash found in #9957 but also simply
reading the wrong cell even in single-page scenarios.
2025-12-18 13:54:35 -08:00
Mitchell Hashimoto
5eb335d694 fix(macOS): re-apply icon after app update (#9951)
## macOS: Re-apply custom icon after app build changes

### Summary

Fixes the regression where custom icons are not re-applied after app
updates, particularly affecting users on the tip channel.

### Problem

PR #9670 introduced caching to avoid redundantly setting the app icon on
every launch. However when Ghostty updates, the app bundle is replaced
and the custom icon is reset by macOS. Since `UserDefaults` persists
across updates, the cached icon name still matches the desired icon
name, causing the icon update to be incorrectly skipped.

This was reported by users in #9670 comments as well, that after
updating Ghostty the custom icon would disappear and require manual
re-application.

### Solution

- Track the app build number (`CFBundleVersion`) alongside the icon name
in `UserDefaults`
- Re-apply the icon if either the icon config has changed OR the build
number has changed
- Only update `UserDefaults` if `NSWorkspace.setIcon()` succeeds,
preventing false-positive caching on failure

I used `CFBundleVersion` (build number, e.g. `13509`) rather than
`CFBundleShortVersionString` (e.g. `1.2.3`) because tip builds increment
the build number with each release while the short version string
remains constant. I considered combining both but this seemed redundant.

### Related

- Fixes regression mentioned in comments on #9670
- Original issue: #9666
- Original discussion: #9665
2025-12-18 13:10:23 -08:00
Jake Nelson
377bcddb46 fix(macOS): re-apply icon after app update 2025-12-18 12:55:49 +11:00
Mitchell Hashimoto
a4cb73db84 macOS: Session Search (#9945)
Replaces #9785 

This adds session search to the command palette on macOS. Session search
lets you jump to any running terminal based on title or working
directory. The command palette shows you the title, working directory,
and tab color (if any) to help you identify the terminal you care about.

This also enhances our command palette in general to support better
sorting, more stable sorts when keys are identical, etc.

## Demo


https://github.com/user-attachments/assets/602a9424-e182-4651-bf08-378e9c5e1616




## Future

Since this inherits the command palette infrastructure, we don't have
fuzzy search capabilities yet, but I still think this is useful already.
We should add fuzzy searching in the future.

Thanks @phaistonian for the inspiration here but I did do a full
rewrite.

**AI disclosure:** I used AI to assist with this in places, but I
understand everything and touched up almost everything manually.
2025-12-17 11:01:19 -08:00
Mitchell Hashimoto
e1d0b22029 macos: allow searching sessions by color too 2025-12-17 10:52:03 -08:00
Mitchell Hashimoto
842583b628 macos: fix uikit build 2025-12-17 10:26:02 -08:00
Mitchell Hashimoto
829dd1b9b2 macos: focus shenangians 2025-12-17 10:13:53 -08:00
Mitchell Hashimoto
e1356538ac macos: show a highlight animation when a terminal is presented 2025-12-17 10:12:44 -08:00
Mitchell Hashimoto
d23f7e051f macos: stable sort for surfaces 2025-12-17 09:52:06 -08:00
Mitchell Hashimoto
1fd3f27e26 macos: show pwd for jump options 2025-12-17 09:47:16 -08:00
Mitchell Hashimoto
b30e94c0ec macos: sort in the focus jumps in other commands 2025-12-17 09:34:30 -08:00
Mitchell Hashimoto
835fe3dd0f macos: add the active terminals to our command palette to jump 2025-12-17 09:30:39 -08:00
Mitchell Hashimoto
e1e782c617 macos: clean up the way command options are built up 2025-12-17 09:10:46 -08:00
Mitchell Hashimoto
5d11bdddc3 macos: implement the present terminal action so we can use that 2025-12-17 09:04:51 -08:00
Mitchell Hashimoto
7e46200d31 macos: command palette entries support leading color 2025-12-17 08:56:22 -08:00
Mitchell Hashimoto
c84113d199 font/coretext: Use positions to correct glyph placement (#9883)
This PR uses positions to get correct glyph placement, which affects a
small number of shaped runs but can even re-order glyphs from how
they're appearing on `main`. This came from an investigation in
https://github.com/jquast/wcwidth/issues/155#issuecomment-3630555803
that involved shaping text from the [Universal Declaration of Human
Rights](https://www.un.org/en/about-us/universal-declaration-of-human-rights)
in 500+ languages, taken from
[ucs-detect](https://github.com/jquast/ucs-detect) (but actually run
with [ttylang](https://github.com/jacobsandlund/ttylang) for more
consistent results).

The full result of running this with the commented out debug lines
enabled is here, showing 1704 differences (a small number compared to
the number of cells being rendered):
https://gist.github.com/jacobsandlund/9cb2c603308085fa03e758640583541e

Some positions are only a small offset that is applied to many letters
from a script (e.g. Syriac letters are getting offset by some small
amount).

There are more egregious cases, though. Consider Tai Tham vowels, that
[according to the Unicode core
spec](https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-16/#G46437),
are rendered visually ahead of the consonant they follow in the text.
The Unicode spec oddly mentions this under the "New Tai Lue" section,
contrasting it with other Brahmi-derived scripts such as Tai Tham:

> This practice differs from the usual pattern for Brahmi-derived
scripts, in which all dependent vowels are stored in logical order after
their associated consonants, even when they are displayed to the left of
those consonants.

For example `"\u{1A2F}\u{1A70}"` renders like this on `main`:

<img width="608" height="90" alt="CleanShot 2025-12-12 at 09 25 16@2x"
src="https://github.com/user-attachments/assets/964063b7-59e7-43f7-b2c9-a0c0c827034a"
/>

And it now renders like this on the PR:

<img width="500" height="90" alt="CleanShot 2025-12-12 at 09 25 38@2x"
src="https://github.com/user-attachments/assets/b6dded0b-30cc-40d8-857d-06b64f7cf19d"
/>

This is the correct rendering as U+1A70 is "TAI THAM VOWEL SIGN OO" and
needs to render ahead of the U+1A2F "TAI THAM LETTER DA"

Note, this PR just fixes CoreText. I'll work on Harfbuzz right after
this, but I wanted to get this out first.

## vtebench

vtebench does show some potential impact on dense cells:


![output](https://github.com/user-attachments/assets/d6741f28-88b9-49a9-b8ef-1f5a61c346da)


![dense_cells](https://github.com/user-attachments/assets/ea18801c-4529-42db-b259-edbe4e4b939b)

This is the first time I've run `vtebench`, so to confirm it's
consistent I ran it again:


![output-2](https://github.com/user-attachments/assets/c418b4b2-18cc-47fd-8fc9-d1e4826942d3)


![dense_cells](https://github.com/user-attachments/assets/c70d573c-4282-4719-ac52-5121b0c155c6)

### AI disclaimer
I had been using Amp when I made this change, but looks like the thread
just fell off of recent threads (about a week ago). I think Amp was the
one to add the getPositionsPtr line and add `position` to the for loop.
I manually restructured the code around a separate `run_offset` and
`cell_offset`, and added the tests.
2025-12-17 08:46:12 -08:00
Mitchell Hashimoto
d820a633ee fix up typos 2025-12-17 08:34:31 -08:00