Commit Graph

622 Commits

Author SHA1 Message Date
Mitchell Hashimoto
935d37fbf1 terminal: add kitty image limits to Terminal.Options
Move kitty_image_storage_limit and kitty_image_loading_limits into
Terminal.Options so callers can set them at construction time
rather than calling setter functions after init. The values flow
through to Screen.Options during ScreenSet initialization. Termio
now passes both at construction, keeping the setter functions for
the updateConfig path.
2026-04-05 07:21:15 -07:00
Mitchell Hashimoto
64dcb91c1f terminal/kitty: add loading limits to kitty graphics protocol
Add a Limits type to LoadingImage that controls which transmission
mediums (file, temporary_file, shared_memory) are allowed when
loading images. This defaults to "direct" (most restrictive) on
ImageStorage and is set to "all" by Termio, allowing apprt
embedders like libghostty to restrict medium types for resource or
security reasons.

The limits are stored on ImageStorage, plumbed through
Screen.Options for screen initialization and inheritance, and
enforced in graphics_exec during both query and transmit. Two new
Terminal methods (setKittyGraphicsSizeLimit, setKittyGraphicsLoadingLimits)
centralize updating all screens, replacing the manual iteration
previously done in Termio.
2026-04-05 07:18:45 -07:00
Mitchell Hashimoto
d784600fd6 terminal: update page_serial_min in erasePage
Fixes #11957

erasePage now updates page_serial_min when the first page is erased,
and asserts that only front or back pages are erased since
page_serial_min cannot represent serial gaps from middle erasure.

To enforce this invariant at the API level, PageList.eraseRows is
now private. Two public wrappers replace it: eraseHistory always
starts from the beginning of history, and eraseActive takes a y
coordinate (with bounds assertion) and always starts from the top
of the active area. This makes middle-page erasure impossible by
construction.
2026-03-29 15:10:12 -07:00
Mitchell Hashimoto
69104fb1f0 libghostty: introduce optional "effects" to handle queries and side effects for terminals (#11787)
Renames `ReadonlyStream` to `TerminalStream` and introduces an
effects-based callback system so that the stream handler can optionally
respond to queries and side effects (bell, title changes, device
attributes, device status, size reports, XTVERSION, ENQ, DECRQM, kitty
keyboard queries).

The default behavior is still read-only, callers have to opt-in to
setting callbacks to function pointers.

This doesn't handle every possible side effect yet, e.g. this doesn't
include clipboards, pwd reporting, and others. But this covers the
important ones.

This PR is Zig only, the C version of this will come later.
2026-03-23 15:30:18 -07:00
Mitchell Hashimoto
22c7edf3f8 terminal: rename set_window_title effect to title_changed
The effect callback no longer receives the title string directly.
Instead, the handler stores the title in terminal state via setTitle
before invoking the callback, so consumers query it through
handler.terminal.getTitle(). This removes the redundant parameter
and keeps the effect signature consistent with the new terminal
title field. Tests now verify terminal state directly rather than
tracking the title through the callback.
2026-03-23 14:17:10 -07:00
Mitchell Hashimoto
08a44d7e69 terminal: store title set by escape sequences
Add a title field to Terminal, mirroring the existing pwd field.
The title is set via setTitle/getTitle and tracks the most recent
value written by OSC 0/2 sequences. The stream handler now persists
the title in terminal state in addition to forwarding it to the
surface. The field is cleared on full reset.
2026-03-23 14:17:10 -07:00
Alessandro De Blasis
5ef2da8127 windows: fix XDG-related test failures on Windows
Make the "cache directory paths" test cross-platform by using
std.fs.path.join for expected values and a platform-appropriate
mock home path, since the function under test uses native path
separators.

Skip the two shell integration XDG_DATA_DIRS tests on Windows.
These tests use hardcoded Unix path separators (:) and Unix default
paths (/usr/local/share:/usr/share) which are not applicable on
Windows where the path delimiter is ; and XDG_DATA_DIRS is not a
standard concept.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:09:32 +01:00
Jeffrey C. Ollie
2ea6029c7a core: address getProcessInfo feedback
* consolidate *.c files into a single file
* consolidate ProcessInfo enums into a single enum
2026-03-19 22:01:16 -05:00
Jeffrey C. Ollie
89ae0ea6ef core: add function to get process info from the surface
This adds a function to the core surface to get process information
about the process(es) running in the terminal. Currently supported is
the PID of the foreground process and the name of the slave PTY.

If there is an error retrieving the information, or the platform does
not support retieving that information `null` is returned.

This will be useful in exposing the foreground PID and slave PTY name to
AppleScript or other APIs.
2026-03-19 22:01:15 -05:00
Mitchell Hashimoto
a1d7ad9243 terminal: extract size report encoder
Size report escape sequences were previously formatted inline in
Termio.sizeReportLocked, and termio.Message carried a duplicate enum for
report styles. That made the encoding logic harder to reuse and kept
the style type scoped to termio.

Move the encoding into terminal.size_report and export it through
terminal.main. The encoder now takes renderer.Size directly and derives
grid and pixel dimensions from one source of truth. termio.Message now
aliases terminal.size_report.Style, and Termio writes reports via the
shared encoder.
2026-03-17 16:21:34 -07:00
Mitchell Hashimoto
d6b37ba38f terminal: extract DECRPM mode report encoding to terminal package
This extracts our mode reporting from being hardcoded in termio
to being reusable in the existing `terminal.modes` namespace. The goal
is to expose this via the Zig API libghostty (done) and C API (to do
later).
2026-03-16 15:09:26 -07:00
Mitchell Hashimoto
bed9d92f04 vt: expose focus encoding in C and Zig APIs
Add focus event encoding (CSI I / CSI O) to the libghostty-vt public
API, following the same patterns as key and mouse encoding.

The focus Event enum uses lib.Enum for C ABI compatibility. The C API
provides ghostty_focus_encode() which writes into a caller-provided
buffer and returns GHOSTTY_OUT_OF_SPACE with the required size when
the buffer is too small.

Also update key and mouse encoders to return GHOSTTY_OUT_OF_SPACE
instead of GHOSTTY_OUT_OF_MEMORY for buffer-too-small errors,
reserving OUT_OF_MEMORY for actual allocation failures. Update all
corresponding header documentation.
2026-03-16 14:38:19 -07:00
Kat
6fabf775bb Lots of duplicate word typos + typo. 2026-03-16 09:19:09 +11:00
Mitchell Hashimoto
2044e5030f terminal: make stream processing infallible
The terminal.Stream next/nextSlice functions can now no longer fail.
All prior failure modes were fully isolated in the handler `vt`
callbacks. As such, vt callbacks are now required to not return an error
and handle their own errors somehow.

Allowing streams to be fallible before was an incorrect design. It
caused problematic scenarios like in `nextSlice` early terminating
processing due to handler errors. This should not be possible.

There is no safe way to bubble up vt errors through the stream because
if nextSlice is called and multiple errors are returned, we can't
coalesce them. We could modify that to return a partial result but its
just more work for stream that is unnecessary. The handler can do all of
this.

This work was discovered due to cleanups to prepare for more C APIs.
Less errors make C APIs easier to implement! And, it helps clean up our
Zig, too.
2026-03-13 13:56:14 -07:00
Mitchell Hashimoto
0eaf77da5f WIP: Make palette inversion opt-in (#10877)
From #10554

> I can see there being space for some kind of new sequence that tells
the terminal that "hey, I want a semantic palette" or something, that is
better adjusted to themes automatically. But, I don't think we should
this by default.

> So my concrete proposal is to eliminate the inversion and bg => fg
ramp and do a more typical dark => light ramp (still taking into account
bg/fg, but keeping 16 black and 231 white). I think this is the only way
we can really make this a default on feature. I think this would address
all the negative reactions we've gotten to it.

This adds a new `palette-harmonious`, disabled by default, which allows
generated light themes to be inverted.
2026-02-19 20:24:42 -08:00
Jake Stewart
f66a84b18a improve light theme detection 2026-02-19 20:17:47 -08:00
Jake Stewart
c4c87f8c85 make palette inversion opt-in 2026-02-20 07:46:16 +08:00
Mitchell Hashimoto
eb335fb8dd cleanup by just scrolling in the renderer 2026-02-19 14:06:58 -08:00
benodiwal
263469755c refactor: remove unused stream handler scroll-to-bottom code
The renderer approach doesn't need termio changes.

Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
2026-02-19 13:54:32 -08:00
benodiwal
81f537e992 feat: implement scroll-to-bottom on output option
Implements the `output` option for the `scroll-to-bottom` configuration,
which scrolls the viewport to the bottom when new lines are printed.

Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
2026-02-19 13:52:57 -08:00
Mitchell Hashimoto
73d6f07c5b gtk: revamp cgroup/transient scope handling (#10611)
This changes the way Ghostty assigns itself and subprocesses to
cgroups and how resource controls are applied.
    
* Ghostty itself no longer modifies it's own cgroup or moves itself
to a transient scope. To modify the main Ghostty process' resource
controls ensure that you're launching Ghostty with a systemd unit and
use the standard systemd methods for overriding and applying changes
to systemd units.
    
* If configured (on by default), the process used to run your command
will be moved to a transient systemd scope after it is forked from
Ghostty but before the user's command is executed. Resource controls
will be applied to the transient scope at this time. Changes to
the `linux-cgroup*` configuration entries will not alter existing
commands. If changes are made to the `linux-cgroup*` configuration
entries commands will need to be relaunched. Resource limits can also
be modified after launch outside of Ghostty using systemd tooling. The
transient scope name can be shown by running `systemctl --user whoami`
in a shell running inside Ghostty.
    
Fixes #2084.
Related to #6669

Example of `systemctl status` showing main Ghostty process and one
surface:
<img width="1132" height="135" alt="Screenshot From 2026-02-07 16-31-14"
src="https://github.com/user-attachments/assets/81dffd0b-8801-4695-adf4-213647cdf0c3"
/>
2026-02-17 16:23:54 -08:00
Mitchell Hashimoto
b25edc3e93 termio: don't auto-generate palette if user didn't customize any
This fixes the issue where our palette generation was changing our
default palette. The default palette is based on some well known values
chosen from various terminals and it was a bit jarring to have it
change.

We now only auto-generate the palette if the user has customized at
least one entry.
2026-02-17 13:04:35 -08:00
Jeffrey C. Ollie
1342eb5944 gtk: revamp cgroup/transient scope handling
This changes the way Ghostty assigns itself and subprocesses to
cgroups and how resource controls are applied.

* Ghostty itself no longer modifies it's own cgroup or moves itself
to a transient scope. To modify the main Ghostty process' resource
controls ensure that you're launching Ghostty with a systemd unit and
use the standard systemd methods for overriding and applying changes
to systemd units.

* If configured (on by default), the process used to run your command
will be moved to a transient systemd scope after it is forked from
Ghostty but before the user's command is executed. Resource controls
will be applied to the transient scope at this time. Changes to
the `linux-cgroup*` configuration entries will not alter existing
commands. If changes are made to the `linux-cgroup*` configuration
entries commands will need to be relaunched. Resource limits can also
be modified after launch outside of Ghostty using systemd tooling. The
transient scope name can be shown by running `systemctl --user whoami`
in a shell running inside Ghostty.

Fixes #2084.
Related to #6669
2026-02-17 12:54:26 -06:00
Mitchell Hashimoto
f0a1b05f63 rename config 2026-02-17 09:54:34 -08:00
Mitchell Hashimoto
50698c5c72 fmt 2026-02-17 09:18:03 -08:00
Jake Stewart
7729714935 refactor 256 color gen 2026-02-17 09:17:54 -08:00
Jake Stewart
fad72e0ed1 generate 256 palette 2026-02-17 09:17:54 -08:00
Jon Parise
3cfb9d64d1 shell-integration: respect cursor-style-blink
The `cursor` shell feature always used a blinking bar (beam), often to
the surprise of users who set `cursor-style-blink = false`.

This change extends our GHOSTTY_SHELL_FEATURES format to include either
`cursor:blink` (default) or `cursor:steady` based on cursor-style-blink
when the `cursor` feature is enabled, and all shell integrations have
been updated to use that additional information to choose the DECSCUSR
cursor value (5=blinking bar, 6=steady bar).

I also considered passing a DECSCUSR value in GHOSTTY_SHELL_FEATURES
(e.g. `cursor:5`). This mostly worked well, but zsh also needs the blink
state on its own for its block cursor. We also don't support any other
shell feature cursor configurability (e.g. the shape), so this was an
over generalization.

This does change the behavior for users who like the blinking bar in the
shell but have `cursor-blink-style = false` for other reasons. We could
provide additional `cursor` shell feature configurability, but I think
that's best left to a separate change.
2026-02-10 18:46:36 -05:00
Mitchell Hashimoto
1b2376d366 terminal: remove last semantic_prompt usage from Terminal 2026-01-31 11:01:03 -08:00
Mitchell Hashimoto
84cfb9de1c restore old marking behavior so everything keeps working 2026-01-31 11:01:02 -08:00
Mitchell Hashimoto
3e825dd608 inspector: clean up Inspector 2026-01-31 08:47:15 -08:00
Mitchell Hashimoto
c9e60b322b terminal: OSC133 options parse from raw string
This changes our OSC133 parser to parse options lazily. We do this for
multiple reasons:

1. Parsing all our options ahead of time balloons our required
   osc.Command tagged union type which has C ABI implications. Adding
   all supported options (including Kitty extensions) today already
   breaks our C ABI.

2. Invalid options are allowed by the specification and should be 
   explicitly ignored, so we don't need to validate options at all
   during parse time.

3. Semantic prompt markers don't need to be high throughput, so we
   can afford to do some extra work at processing time to gather
   the options. They're also rather short usually.
2026-01-24 13:48:31 -08:00
Mitchell Hashimoto
d23722dbd7 terminal: remove old semantic prompt handling 2026-01-23 14:35:10 -08:00
Mitchell Hashimoto
389439b167 terminal: handle semantic prompt same as old 2026-01-23 14:30:27 -08:00
Mitchell Hashimoto
9f2808ce40 terminal: stream handles new SemanticPrompt type 2026-01-23 14:14:28 -08:00
Mitchell Hashimoto
82b10ae7af terminal: explicit error sets in Screen and ScreenSet 2026-01-21 11:34:59 -08:00
Mitchell Hashimoto
c8ffc0faa5 termio: report color scheme synchronously (#9705)
The reporting of color scheme was handled asynchronously by queuing a
handler in the surface. This could lead to race conditions where the DSR
is reported after subsequent VT sequences.

Fixes #5922
2026-01-20 09:48:43 -08:00
Mitchell Hashimoto
63075c926e shell-integration: initial nushell shell integration (#10274)
Nushell <https://www.nushell.sh/> is a modern interactive shell that
provides many shell features out-of-the-box, like `title` support. Our
shell integration therefore focuses on Ghostty-specific features like
`sudo`.

We use Nushell's module system to provide a `ghostty` module containing
our shell integration features. This module is automatically loaded from
$XDG_DATA_DIRS/nushell/vendor/autoload/ when `nushell` shell integration
is enabled.

Exported module functions need to be explicitly "used" before they're
available to the interactive shell environment. We do that automatically
by adding `--execute "use ghostty *"` to the `nu` command line.

This imports all available functions, and individual shell features are
runtime-guarded by the script code (using $GHOSTTY_SHELL_FEATURES). We
can consider further refining this later.

When automatic shell integration is disabled, users can still manually
source and enable the shell integration module:

source
$GHOSTTY_RESOURCES_DIR/shell-integration/nushell/vendor/autoload/ghostty.nu
    use ghostty *

This initial work implements our TERMINFO-aware `sudo` wrapper (via the
`sudo` shell feature). Support for additional features, like `ssh-env`
and `ssh-terminfo`, will follow (#9604).
2026-01-20 08:33:13 -08:00
Mitchell Hashimoto
a8b31ceb84 terminal: restoreCursor is now longer fallible
We need to have sane behavior in error handling because the running
program that sends the restore cursor command has no way to realize it
failed. So if our style fails to add (our only fail case) then we revert
to no style.

https://ampcode.com/threads/T-019bd7dc-cf0b-7439-ad2f-218b3406277a
2026-01-19 12:12:19 -08:00
Tobias Kohlbau
836d794b9e termio: report color scheme synchronously
The reporting of color scheme was handled asynchronously by queuing a
handler in the surface. This could lead to race conditions where the
DSR is reported after subsequent VT sequences.

Fixes #5922
2026-01-19 07:49:57 +01:00
Qwerasd
69066200ef fix: handle double tmux control mode exit command 2026-01-16 16:58:58 -05:00
Jon Parise
9434203725 shell-integration: always set up XDG_DATA_DIRS for nushell
This makes our 'ghostty' module available even if the rest of our
automatic integration steps fail, which is convenient for manual
"use"-age.

This is safe because autoload-ing our module doesn't have any side
effects other than cleaning up the XDG_DATA_DIRS environment variable.
2026-01-11 17:05:08 -05:00
Jon Parise
7e3c9f4d5a shell-integration: initial nushell shell integration
Nushell <https://www.nushell.sh/> is a modern interactive shell that
provides many shell features out-of-the-box, like `title` support. Our
shell integration therefore focuses on Ghostty-specific features like
`sudo`.

We use Nushell's module system to provide a `ghostty` module containing
our shell integration features. This module is automatically loaded from
$XDG_DATA_DIRS/nushell/vendor/autoload/ when `nushell` shell integration
is enabled.

Exported module functions need to be explicitly "used" before they're
available to the interactive shell environment. We do that automatically
by adding `--execute "use ghostty *"` to the `nu` command line.

This imports all available functions, and individual shell features are
runtime-guarded by the script code (using $GHOSTTY_SHELL_FEATURES). We
can consider further refining this later.

When automatic shell integration is disabled, users can still manually
source and enable the shell integration module:

    source $GHOSTTY_RESOURCES_DIR/shell-integration/nushell/vendor/autoload/ghostty.nu
    use ghostty *

This initial work implements our TERMINFO-aware `sudo` wrapper (via the
`sudo` shell feature). Support for additional features, like `ssh-env`
and `ssh-terminfo`, will follow.
2026-01-11 11:27:19 -05:00
Jon Parise
795de7938d shell-integration: better shell detection and setup
Command-based shell detection has been extracted to its own function
(detectShell), which is nicer for testing. It now uses argIterator to
determine the command's executable, rather than the previous string
operations, which allows us to handle command strings containing quotes
and spaces.

Also, our shell-specific setup functions now use a consistent signature,
which simplifies the calling code quite a bit.
2026-01-07 10:25:17 -08:00
Peter Cardenas
f36abed35a fix: reset progress bar on reset terminal 2026-01-05 05:26:33 -08:00
Mitchell Hashimoto
c00d7fc5c4 shell-integration: ensure clean env on failure (#10035)
Our shell integration routines can now fail when resources are missing.
This change introduces tests to ensure that they leave behind a clean
environment upon failure.

The bash integration needed a little reordering to support this.
2025-12-26 13:29:27 -08:00
Jon Parise
256c3b9ffb shell-integration: ensure clean env on failure
Our shell integration routines can now fail when resources are missing.
This change introduces tests to ensure that they leave behind a clean
environment upon failure.

The bash integration needed a little reordering to support this.
2025-12-23 14:51:09 -05:00
Jon Parise
3d2aa9bd82 shell-integration: always call setupFeatures
Our existing logic already ensured that setupFeatures() was always
called, but that was happening from two code paths: explicitly when
shell integration is .none and implicitly via setup().

We can simplify this by always calling setupFeatures() once, outside of
the (automatic) shell integration path.

There's one small behavioral change: we previously didn't set up shell
features in the automatic shell integration path if we didn't have a
resources directory (as a side effect). Resources are required for shell
integrations, but we don't need them to export GHOSTTY_SHELL_FEATURES,
which could potentially still be useful on its on.
2025-12-23 13:17:22 -05:00
Jon Parise
8f44b74b33 shell-integration: add failure regression test
Add a unit test to prevent regressions in our failure state.

For example, we always want to set GHOSTTY_SHELL_FEATURES, even if
automatic shell integration fails, because it's also used for manual
shell integration (e.g. #5048).
2025-12-23 12:27:59 -05:00
Jon Parise
73fd007a83 shell-integration: log warnings for missing paths 2025-12-21 16:44:43 -05:00