This is a new CLI action that prints an option or keybind's help
documentation to stdout.
ghostty +explain-config font-size
ghostty +explain-config copy_to_clipboard
ghostty +explain-config --option=font-size
ghostty +explain-config --keybind=copy_to_clipboard
The --option and --keybind flags perform a specific lookup. A string
passed as a positional argument attempts to look up the name first as an
option and then as a keybind.
Our vim plugin uses this with &keywordprg, which allows you to look up
the documentation for the config option or keybind under the cursor (K).
If the CLI argument `--working-directory` is not used with
`+new-window`, the current working directory that `ghostty +new-window`
is run from will be appended to the list of configuration data sent
to the main Ghostty process. If `-e` _was_ used on the CLI, the
`--working-directory` that was appended will be interpreted as part of
the command to be executed, likely causing it to fail.
Instead, insert `--working-directory` at the beginning of the list of
configuration that it sent to the main Ghostty process.
Fixes#11356
As discussed in Discord, this commit drops the `ConfigOverride` object
in favor of a simpler method of passing the overrides around. Completely
avoiding changes to the core wasn't possible but it's very minimal now.
Fixes: #8862Fixes: #10716
This adds the machinery to pass configuration settings received over
DBus down to the GObject Surface so that that configuration information
can be used to override some settings from the current "live" config
when creating a new window. Currently it's only possible to override
`--working-directory` and `--command`. `-e` on the `ghostty +new-window`
CLI works as well.
Adding more overridable settings is possible, but being able to fully
override any possible setting would better be served with a major
revamp of how Ghostty handles configs, which I is way out of scope at
the moment.
We previously wrote our new cache file into a temporary directory and
the (atomically) renamed it to the canonical cache file path. This
rename operation unfortunately only works when both files are on the
same file system, and that's not always the case (e.g. when $TMPDIR is
on its own file system).
Instead, we can use Zig's AtomicFile to safely perform this operation
inside of the cache directory.
There's a new risk of a crash leaving the temporary file around in this
directory (and not getting cleaned up like $TMPDIR-based files), but the
probability is low and those files will only be readable by the creating
user (mode 0o600).
There's a new test cash that verifies the expected AtomicFile clean up
behavior. I also switched the file-oriented tests to use testing.tmpDir
rather than using our application-level TempDir type.
- Display keybindings grouped by their source table, with table name as prefix
- Sort default bindings before table bindings, maintaining visual hierarchy
- Support keybindings defined in key tables alongside default bindings
- Enable users to discover all available keybindings across the entire config
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`.
not an accepted issue
https://github.com/ghostty-org/ghostty/discussions/9745 but it seemed
simple enough to add, pretty much copies how the previewer sorts based
on color
This allows --color argument to work when using --plain to sort the list
returned
std.fs.makeDirAbsolute() only creates the last directory. We instead
need Dir.makePath() to make the entire path, including intermediate
directories.
This fixes the problem where a missing $XDG_STATE_HOME directory (e.g.
~/.local/state/) would prevent our ssh cache file from being created.
Fixes#9393
contains() checks the cache for an existing entry. It's a read-only
operation, so we can drop the write bit and fixupPermissions() call.
This is also consistent with the list() operation.
fixupPermissions() is unnecessary in this code path. It provided minimal
additional security because all of our creation and update operations
enforce 0o600 (owner-only) permissions, so anyone tampering with this
file has already gotten around that. The contents of this (ssh host
cache) file are also not sensitive enough to warrant any additional
hardening on reads.
Remove the semi-magic upper bound on the total cache key length. The
hostname and username validation routines will perform their own length
checks.
Also consolidate this function's tests. We previously had a few
redundant test cases.
The host validation code previously expected IPv6 addresses to be
enclosed in [brackets], but that's not how ssh(1) expects them.
This change removes that requirement and reimplements the host
validation routine to check for valid hostnames and IP addresses (IPv4
and IPv6) using standard routines rather than custom logic.
Update libvaxis. The latest commit of libvaxis includes `uucode` as the
unicode
library. `uucode` has a much cleaner API and is actively developed by a
Ghostty
maintainer (@jacobsandlund). This also has the advantage of removing the
last
transitive dependency Ghostty has that is hosted on codeberg, which
separates us
from the frequent outages.
Disclosures: I used AI to debug the import issue in `boo.zig`
---------
Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
Resolves#8689
For various reason, ghostty wants to have a unique file extension for
the config files. The name was settled on `config.ghostty`. This will
help with tooling. See #8438 (original discussion) for more details.
This PR introduces the preferred default of `.ghostty` while still
supporting the previous `config` file. If both files exist, a warning
log is sent.
The docs / website will need to be updated to reflect this change.
> [!NOTE]
> Only tested on macOS 26.0.
---------
Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
Fixes#8849
Previously, the `parseAutoStruct` function that was used to parse
generic structs for the config simply split the input value on commas
without taking into account quoting or escapes. This led to problems
because it was impossible to include a comma in the value of config
entries that were parsed by `parseAutoStruct`. This is particularly
problematic because `ghostty +show-config --default` would produce
output like the following:
```
command-palette-entry = title:Focus Split: Next,description:Focus the next split, if any.,action:goto_split:next
```
Because the `description` contains a comma, Ghostty is unable to
parse this correctly. The value would be split into four parts:
```
title:Focus Split: Next
description:Focus the next split
if any.
action:goto_split:next
```
Instead of three parts:
```
title:Focus Split: Next
description:Focus the next split, if any.
action:goto_split:next
```
Because `parseAutoStruct` simply looked for commas to split on, no
amount of quoting or escaping would allow that to be parsed correctly.
This is fixed by (1) introducing a parser that will split the input
to `parseAutoStruct` into fields while taking into account quotes and
escaping. And (2) changing the `ghostty +show-config` output to put the
values in `command-palette-entry` into quotes so that Ghostty can parse
it's own output.
`parseAutoStruct` will also now parse double quoted values as a Zig
string literal. This makes it easier to embed control codes, whitespace,
and commas in values.
Detecting the launch source frequently failed because various launchers
fail to sanitize the environment variables that Ghostty used to
detect the launch source. For example, if your desktop environment was
launched by `systemd`, but your desktop environment did not sanitize the
`INVOCATION_ID` or the `JOURNAL_STREAM` environment variables, Ghostty
would assume that it had been launched by `systemd` and behave as such.
This led to complaints about Ghostty not creating new windows when users
expected that it would.
To remedy this, Ghostty no longer does any detection of the launch
source. If your launch source is something other than the CLI, it must
be explicitly speciflied on the CLI. All of Ghostty's default desktop
and service files do this. Users or packagers that create custom desktop
or service files will need to take this into account.
On GTK, the `desktop` setting for `gtk-single-instance` is replaced with
`detect`. `detect` behaves as `gtk-single-instance=true` if one of the
following conditions is true:
1. If no CLI arguments have been set.
2. If `--launched-from` has been set to `desktop`, `dbus`, or `systemd`.
Otherwise `detect` behaves as `gtk-single-instance=false`.
Fixes#8386
This is a fairly simple implementaion, there's no interactivity or
searching. It will adapt the number of columns to the available width of
the display though.
Will fallback to a plain text dump if there's no tty or the `--plain`
argument is specified on the CLI.
There are still problems linking due to `gettext`. No idea if this
actually _works_ on Windows. File locking had to be disabled on Windows
because of a bug in the Zig std library. Adding all of the explicit
error sets happened due to disabling file locking. Fixing permissions
had to be disabled on Windows as the Windows file system does not
support permissions in the way that POSIX systems like macOS and Linux
do.
Instead of using @hasDecl, use a performAction-stype API. The C
interface for interfacing with macOS (or any other apprt where Ghostty
is embedded) is unfinished.
This adds the `-e` flag to the `+new-window` CLI action. This allows a
command to be passed from the CLI to the running instance of Ghostty.
Nothing is done with that command besides logging its presence.
- Add a `GHOSTTY_CLASS` environment variables to any command executed by
Ghostty to make discovering the correct application ID easier.
- Add a flag to force the relelase application ID.
- Ensure that CLI flags to `+new-window` are mutually exclusive.
- Fix documentation about D-Bus activation requirements.