Skip to content

Clear the terminal title on an empty OSC 0/2 - #623

Merged
dakra merged 1 commit into
mainfrom
feat/osc2-empty-title-clear
Aug 12, 2026
Merged

dakra merged 1 commit into
mainfrom
feat/osc2-empty-title-clear

Conversation

@dakra

@dakra dakra commented Aug 12, 2026

Copy link
Copy Markdown
Owner

An empty OSC 0/2 title (printf '\e]2;\a', the standard way to reset a title) was silently dropped at the native title callback: libghostty stores a cleared title as no title, getTitle returns null for it, and the callback only forwarded non-null titles. The stale title stayed in the mode line and in a title-derived buffer name until the next title report.

Changes

  • src/handler.zig — titleChangedCallback forwards a cleared title as "" instead of dropping it. libghostty delivers the clear correctly end to end (empty payload still parses as change_window_title, title_changed fires unconditionally); this guard was the only drop point.
  • lisp/ghostel.el — ghostel--set-title treats an empty title as "as if no title was ever set", matching Ghostty and iTerm2: ghostel--title normalizes to nil (invariant is now nil-or-non-empty, so the mode line falls back to the plain buffer name), and a title-derived buffer name reverts to ghostel--buffer-identity. The revert only applies to names title tracking has claimed and still goes through the manual-rename guard.
  • ghostel--init-buffer backfills a nil ghostel--buffer-identity with the creation name so buffers created outside the ghostel command (ghostel-exec, eshell visual commands) have a revert target.
  • The now-dead empty-string handling in ghostel--buffer-identification and ghostel-buffer-name-by-title is removed; the ghostel-buffer-name-function contract is now "nil or non-empty string" (custom name functions see nil on a clear, never "").

Tests

  • New native PTY-matrix regression test: title set, then cleared via OSC 2+ST, OSC 2+BEL, and OSC 0+BEL — asserts nil ghostel--title and the reverted buffer name on both backends.
  • New elisp unit tests: clear reverts a by-title name to the identity, declines after a manual rename, is a no-op for buffers title tracking never renamed, and leaves by-directory names alone.
  • Verified live in a terminal Emacs session (bash --norc, shell integration off): OSC 0/2 set/clear round-trips update ghostel--title, the mode line (no empty-parens leftovers), and by-title renames/reverts, with manual renames respected.

Fixes #619

An empty OSC 0/2 title was silently dropped at the native title
callback: libghostty stores a cleared title as no title, getTitle
returns null for it, and the callback only forwarded non-null titles.
The stale title stayed in the mode line and in a title-derived buffer
name until the next title report.

Forward the cleared title as "" and treat it in ghostel--set-title as
"as if no title was ever set", matching Ghostty and iTerm2: normalize
to a nil ghostel--title (the mode line falls back to the plain buffer
name) and revert a title-derived buffer name to
ghostel--buffer-identity.  The revert only applies to names title
tracking has claimed and still goes through the manual-rename guard.

ghostel--init-buffer now backfills a nil ghostel--buffer-identity with
the creation name so buffers created outside the ghostel command
(ghostel-exec, eshell visual commands) have a revert target.

With ghostel--title now nil or non-empty, drop the empty-string
handling in ghostel--buffer-identification and
ghostel-buffer-name-by-title.

Fixes #619
@mrcnski

mrcnski commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Thanks for picking this up so quickly! I built the module from this branch and ran it on macOS (aarch64, Emacs 30). The new regression test passes here, and a set/clear round-trip now clears ghostel--title and reverts a by-title buffer name.

The handler.zig change matches what I found when filing #619. The identity backfill for ghostel-exec buffers giving every buffer a revert target is a good touch. My config's name function reads ghostel--buffer-identity and benefits from the same guarantee.

LGTM!

@dakra
dakra merged commit 1c672c3 into main Aug 12, 2026
29 checks passed
@dakra
dakra deleted the feat/osc2-empty-title-clear branch August 12, 2026 13:02

This branch was previously deployed

1 inactive deployment
github-pages — 1c672c38 Deployed Aug 12, 2026 by dakra via deploy #154
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Empty OSC 0/2 title (title clear) never reaches elisp

2 participants