Commit Graph

8948 Commits

Author SHA1 Message Date
Mitchell Hashimoto
79e023b65e terminal,renderer: convert structs to extern
Convert Coordinate in terminal/point.zig and CellSize, ScreenSize,
GridSize, and Padding in renderer/size.zig to extern structs. All
fields are already extern-compatible types, so this gives them a
guaranteed C ABI layout with no functional change.
2026-03-15 19:39:17 -07:00
Mitchell Hashimoto
37efac99b0 terminal/mouse: convert Event and Format to lib.Enum
Convert the Event and Format enums from fixed-size Zig enums to
lib.Enum so they are C ABI compatible when targeting C. The motion
method on Event becomes a free function eventIsMotion since lib.Enum
types cannot have declarations.
2026-03-15 19:35:54 -07:00
Mitchell Hashimoto
f9f92f2e0f terminal: consolidate mouse types into mouse.zig
Move MouseEvent and MouseFormat out of Terminal.zig and MouseShape out
of mouse_shape.zig into a new mouse.zig file. The types are named
without the Mouse prefix inside the module (Event, Format, Shape) and
re-exported with the prefix from terminal/main.zig for external use.

Update all call sites (mouse_encode.zig, surface_mouse.zig, stream.zig)
to import through terminal/main.zig or directly from mouse.zig. Remove
the now-unused mouse_shape.zig.
2026-03-15 15:48:36 -07:00
Mitchell Hashimoto
ac5e57ce67 input: extract mouse encoding to a pure, testable file
Move mouse event encoding logic from Surface.zig into a new
input/mouse_encode.zig file.

The new file encapsulates event filtering (shouldReport),
button code computation, viewport bounds checking, motion
deduplication, and all five wire formats (X10, UTF-8, SGR,
urxvt, SGR-pixels). This makes the encoding independently
testable and adds unit tests covering each format and edge
case.

Additionally, Surface `mouseReport` can no longer fail, since the only
failure mode is no buffer space which should be impossible. Updated
the signature to remove the error set.
2026-03-15 15:37:54 -07:00
Mitchell Hashimoto
943d3d2e89 vt: add setopt_from_terminal to C API
Expose the key encoder Options.fromTerminal function to the C API as
ghostty_key_encoder_setopt_from_terminal. This lets C callers sync all
terminal-derived encoding options (cursor key application mode, keypad
mode, alt escape prefix, modifyOtherKeys, and Kitty flags) in a single
call instead of setting each option individually.
2026-03-15 07:05:07 -07:00
Jaeseok Lee
86d9a04ece config: add equal option to window-padding-balance
Change `window-padding-balance` from `bool` to an enum with three
values:

- `false` - no balancing (default, unchanged)
- `true` - balance with vshift that caps top padding and shifts excess
  to bottom (existing behavior, unchanged)
- `equal` - balance whitespace equally on all four sides

This gives users who prefer truly equal padding a way to opt in without
changing the default behavior.
2026-03-15 13:50:21 +09:00
Mitchell Hashimoto
647f5adf55 terminal/formatter: safely cast discarding.count to usize
The Discarding writer count field is u64, but several call sites
pass it where a usize is expected. On wasm32-freestanding, usize is
32-bit, so this caused compilation errors.

Use std.math.cast instead of a bare @intCast so that overflow is
handled gracefully, returning WriteFailed rather than triggering
safety-checked undefined behavior at runtime.
2026-03-14 15:29:53 -07:00
Mitchell Hashimoto
4ad7d03c56 terminal/formatter: safely cast discarding.count to usize
The Discarding writer count field is u64, but appendNTimes expects
usize which is u32 on 32-bit targets like arm-linux-androideabi.
Use std.math.cast instead of @intCast to safely handle the
conversion, returning WriteFailed on overflow rather than risking
undefined behavior.
2026-03-14 15:22:21 -07:00
Mitchell Hashimoto
3c8feda118 vt: add format_alloc to C API formatter
Rename the existing format function to format_buf to clarify that it
writes into a caller-provided buffer. Add a new format_alloc variant
that allocates the output buffer internally using the provided
allocator (or the default if NULL). The caller receives the allocated
pointer and length and is responsible for freeing it.

This is useful for consumers that do not know the required buffer size
ahead of time and want to avoid the two-pass query-then-format pattern
needed with format_buf.
2026-03-14 14:59:41 -07:00
Mitchell Hashimoto
a2d570b51e vt: add sized struct pattern and types.h
Add a size field as the first member of formatter option structs
(TerminalOptions, TerminalOptions.Extra, ScreenOptions.Extra) for ABI
compatibility. This allows adding new fields without breaking callers
compiled against older versions of the struct.

Introduce include/ghostty/vt/types.h as the foundational header
containing GhosttyResult and the GHOSTTY_INIT_SIZED macro for
zero-initializing sized structs. Remove the separate result.h header,
moving its contents into types.h.
2026-03-14 14:42:50 -07:00
Mitchell Hashimoto
09d3ebd80d vt: use explicit options structs 2026-03-14 14:30:36 -07:00
Mitchell Hashimoto
4e494ccd68 lib: lib.Struct can convert packed structs to extern structs 2026-03-14 14:21:00 -07:00
Mitchell Hashimoto
b5fb7ecaaa vt: wip formatter api 2026-03-14 14:16:44 -07:00
Mitchell Hashimoto
8e6bf829a7 terminal/osc: don't export context/semantic prompts to libvt yet 2026-03-13 20:06:33 -07:00
Mitchell Hashimoto
aa3e6e23a2 vt: ghostty_terminal_reset 2026-03-13 19:55:43 -07:00
Mitchell Hashimoto
fe6e7fbc6b vt: ghostty_terminal_resize 2026-03-13 19:54:20 -07:00
Mitchell Hashimoto
8b9afe35a7 vt: ghostty_terminal_scroll_viewport 2026-03-13 19:51:04 -07:00
Mitchell Hashimoto
18fdc15357 vt: ghostty_terminal_vt_write 2026-03-13 19:37:26 -07:00
Mitchell Hashimoto
302e68fd3d vt: expose ghostty_terminal_new/free 2026-03-13 14:10:57 -07: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
rhodes-b
af84fdbea8 fix tests 2026-03-12 20:42:56 -05:00
rhodes-b
6f8ffecb89 working basic search wrapping 2026-03-12 20:42:55 -05:00
Ken VanDine
64331b8c35 snap: Don't leak LD_LIBRARY_PATH set by the snap launcher 2026-03-12 16:27:54 -04:00
Mitchell Hashimoto
ab269e2c79 config: add progress-style option (#11289)
Adds progress-style config to control OSC 9;4 progress bar visibility.
Defaults to true, set false to hide.

Fixes #11241

AI Disclosure: Claude Code (Opus 4.6) used for codebase exploration,
code review, and testing assistance. All code written and reviewed by
hand.
2026-03-11 20:46:59 -07:00
Michal Olechowski
84d48d1c6a config: add progress-style option
Add option to disable OSC 9;4 ConEmu progress bars via config.

Fixes #11241
2026-03-12 01:33:25 +01:00
Jon Parise
e31615d00b bash: fix extra newlines with readline vi mode indicator
Use OSC 133;P (prompt mark) instead of 133;A (fresh line + prompt mark)
inside PS1 and PS2. Readline redraws the prompt on vi mode switches,
Ctrl-L, and other events, and 133;A's fresh-line behavior would emit a
CR+LF whenever the cursor wasn't at column 0, causing visible extra
newlines.

The one-time 133;A is now emitted via printf in __ghostty_precmd, which
only runs once per prompt cycle via PROMPT_COMMAND. On SIGWINCH, bash
redraws PS1 (firing the 133;P marks) but doesn't re-run PROMPT_COMMAND,
so there's no unwanted fresh-line on resize either. The redraw=last flag
persists from the initial printf.

This is a little less optimal than our previous approach, in terms of
number of prompt marks we emit, but it produces an overall more correct
result, which is the important thing.

Because readline prints its output outside the scope of PS1, those
characters "inherit" the surrounded prompt scope. This is usually fine,
but it can sometimes get out of sync (especially during redraws). This
is inherently a limitation of the fact that it's a separate output
channel, so we just have to accept that can happen.

See: #11267
2026-03-11 12:46:14 -04:00
Mitchell Hashimoto
86c2a2e87f input: add direct set_surface_title and set_tab_title actions
Fixes #11316

This mirrors the `prompt` actions (hence why there is no window action
here) and enables setting titles via keybind actions which importantly
lets this work via command palettes, App Intents, AppleScript, etc.
2026-03-11 09:25:08 -07:00
Jon Parise
26d8bd9e71 bash: fix multiline PS1 with command substitutions
Only replace the \n prompt escape when inserting secondary prompt marks,
not literal newlines ($'\n'). Literal newlines may appear inside $(...)
or `...` command substitutions, and inserting escape sequences there
breaks the shell syntax. For example:

      PS1='$(if [ $? -eq 0 ]; then echo -e "P";
                    else echo -e "F";
                    fi) $ '

The literal newlines between the if/else/fi are part of the shell syntax
inside the command substitution. The previous code replaced all literal
newlines in PS1 with newline + OSC 133 escape sequences, which injected
terminal escapes into the middle of the command substitution and caused
bash to report a syntax error when evaluating it.

The \n prompt escape is PS1-specific and safe to replace globally. This
means prompts using literal newlines for line breaks (rather than \n)
won't get per-line secondary marks, but this is the conventional form
and avoids the need for complex shell parsing.

Fixes: #11267
2026-03-11 10:46:43 -04:00
Jon Parise
23f3cd5f10 zsh: improve prompt marking with dynamic themes
Replace the strip-in-preexec / re-add-in-precmd pattern for OSC 133
marks with a save/restore approach. Instead of pattern-matching marks
out of PS1 (which exposes PS1 in intermediate states to other hooks), we
save the original PS1/PS2 before adding marks and then restore them.

This also adds dynamic theme detection: if PS1 changed between cycles
(e.g., a theme rebuilt it), we skip injecting continuation marks into
newlines. This prevents breaking plugins like Pure that use pattern
matching to strip/rebuild the prompt.

Additionally, move _ghostty_precmd to the end of precmd_functions in
_ghostty_deferred_init (instead of substituting in-place) so that the
first prompt is properly marked even when other hooks were appended
after our auto-injection.

There's one scenario that we still don't complete cover:

    precmd_functions+=(_test_overwrite_ps1)
    _test_overwrite_ps1() {
        PS1="test> "
    }

... which results in the first prompt not printing its prompt marks
because _test_overwrite_ps1 becomes the last thing to run, overwriting
our marks, but this will be fixed for subsequent prompts when we move
our handler back to the last index.

Fixes: #11282
2026-03-11 10:07:54 -04:00
Leah Amelia Chen
76e9ee7d37 gtk: fix +new-window --working-directory inferrence. (#11357) 2026-03-11 17:16:06 +08:00
Paul Oliver
82a805296c docs: fix backtick rendering in selection-word-chars default value
The default value contains a literal backtick which broke inline code
rendering on the website. Use double backtick delimiters to properly
contain it.
2026-03-11 21:15:20 +13:00
Jeffrey C. Ollie
ad6d3665c2 gtk: fix +new-window --working-directory inferrence.
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
2026-03-11 02:23:12 -05:00
Steve Hulet
f9862cd4e2 GTK does support scrollbars 2026-03-10 16:14:18 -07:00
Mitchell Hashimoto
04d5efc8eb config: working-directory expands ~/ prefix
Fixes #11336

Introduce a proper WorkingDirectory tagged union type with home, inherit,
and path variants. The field is now an optional (?WorkingDirectory) where
null represents "use platform default" which is resolved during Config.finalize
to .inherit (CLI) or .home (desktop launcher).
2026-03-10 14:33:40 -07:00
Mitchell Hashimoto
a4cc37db72 tests: disable tests that fail if you have locally installed fonts (#11285)
If you have "Noto Sans Tai Tham" and/or "Noto Sans Javanese" installed
locally on Linux, three tests fail. This PR disables those tests until a
more permanent solution can be found.
2026-03-10 11:53:23 -07:00
Jeffrey C. Ollie
c1313294cd add comments about why tests are disabled 2026-03-10 13:29:50 -05:00
Mitchell Hashimoto
53637ec7b2 fix jump_to_prompt forward behavior for multiline prompts
Fixes #11330.

When jumping forward from prompt content, skip prompt continuation rows so a 
multiline prompt is treated as a single prompt block.
2026-03-10 10:47:18 -07:00
Mitchell Hashimoto
aaad43c235 macos: make paste_from_clipboard performable on macos
Fixes #10751
2026-03-10 10:25:14 -07:00
Mitchell Hashimoto
d9039eb85a config: don't double load app support path on macOS
Fixes #11323
2026-03-10 09:23:51 -07:00
Jeffrey C. Ollie
96f9772cd8 tests: disable tests that fail if you have locally installed fonts
If you have "Noto Sans Tai Tham" and/or "Noto Sans Javanese" installed
locally on Linux, three tests fail. This PR disables those tests until a
more permanent solution can be found.
2026-03-09 19:59:21 -05:00
Jeffrey C. Ollie
f8f431ba67 docs: update bell-features docs for macOS
PR #11154 didn't fully update the docs regarding `bell-features=audio`
on macOS.
2026-03-09 16:47:07 -05:00
Mitchell Hashimoto
1e981f858a terminal: fix grapheme edge-wrap hyperlink integrity panic (#11264)
When a grapheme expands to width 2 at the screen edge, this path can
write spacer_head before printWrap() sets row.wrap. With an active
hyperlink, printCell triggers hyperlink bookkeeping and page integrity
checks in that intermediate state, causing UnwrappedSpacerHead.

Mark row.wrap before writing spacer_head in this grapheme-wrap path to
keep the intermediate state valid.
2026-03-09 07:57:42 -07:00
Mitchell Hashimoto
3ba49a784f terminal: fix grapheme edge-wrap hyperlink integrity panic
When a grapheme expands to width 2 at the screen edge, this path can write
spacer_head before printWrap() sets row.wrap. With an active hyperlink,
printCell triggers hyperlink bookkeeping and page integrity checks in that
intermediate state, causing UnwrappedSpacerHead.

Mark row.wrap before writing spacer_head in this grapheme-wrap path to keep
the intermediate state valid.
2026-03-09 07:53:08 -07:00
Mitchell Hashimoto
f4c40c7d53 bash: only define $__ghostty_ps0 when unset (#11258)
This fixes an error if the script was sourced a second time:

    bash: __ghostty_ps0: readonly variable

Because this is a non-exported variable, this would only happen if the
script was sourced multiple times in the same bash session.
2026-03-09 06:40:57 -07:00
Jon Parise
0a659af55f bash: handle existing ; in PROMPT_COMMAND
If an existing PROMPT_COMMAND was a string ending in ; (and maybe some
spaces), we'd add a redundant ;, resulting in a syntax error. Now we
strip any trailing `;[[:space:]]*` characters from the original string
before add ours.
2026-03-09 09:16:29 -04:00
Jon Parise
fd557e8347 bash: only define $__ghostty_ps0 when unset
This fixes an error if the script was sourced a second time:

    bash: __ghostty_ps0: readonly variable

Because this is a non-exported variable, this would only happen if the
script was sourced multiple times in the same bash session.
2026-03-09 08:52:52 -04:00
Mitchell Hashimoto
2d347cad33 GTK: Don't apply unfocused options when searching (#11224)
If you have multiple splits and start searching naturally the focus
transfers over to the search widget which would apply the unfocused
options. This could make it difficult to view your matches from
searching without re-focusing the surface.

This was discovered when I tested
https://github.com/ghostty-org/ghostty/discussions/11218 (which is a
different issue)
2026-03-08 14:03:23 -07:00
rhodes-b
1d59f5dbcd pass search active state through blueprint 2026-03-08 15:57:28 -05:00
Mitchell Hashimoto
2d9dc5cfd1 fix: list-actions outputs without --docs (#11231)
Explicitly flush the buffer once the generation is complete.

Resolves #11221
2026-03-08 07:59:55 -07:00
Damien Mehala
235dde6844 fix: list-actions outputs without --docs
Explicitly flush the buffer once the generation is complete.

Resolves #11221
2026-03-08 15:51:09 +01:00