Skip to content

Save and restore pane titles, border status, and border format labels - #573

Open
nuffin wants to merge 5 commits into
tmux-plugins:masterfrom
nuffin:feat/pane-title-persistence
Open

Save and restore pane titles, border status, and border format labels#573
nuffin wants to merge 5 commits into
tmux-plugins:masterfrom
nuffin:feat/pane-title-persistence

Conversation

@nuffin

@nuffin nuffin commented Jun 20, 2026

Copy link
Copy Markdown

Summary

Extends tmux-resurrect to preserve pane titles and pane border visual state (border status and border format labels) across save/restore cycles. This ensures that custom pane titles like hermes-exec-pane/hermes-dialog-pane and border labels like 󰭻 Hermes 对话/ 执行终端 set by tools like tmux-dual-pane survive a full restore.

Changes

1. Re-apply pane titles after process restoration

The existing restore_pane() already sets pane_title via select-pane -T during pane creation, but shells (bash, zsh) overwrite it via PROMPT_COMMAND escape sequences once they start. A new restore_pane_titles() step re-applies saved pane titles after restore_all_pane_processes() so custom titles survive the shell restart.

To avoid restoring stale dynamic titles (e.g. user@host: /old/path) on panes that rely on the shell to set their title, title restoration is linked to the presence of a deliberate visual customization — only panes with custom pane_border overrides get their titles restored.

2. Save and restore pane border status and format

Save side (save.sh):

  • Extended dump_windows() to capture window-level pane-border-status and pane-border-format as two new tab-delimited fields at the end of each window line
  • New dump_pane_borders() function: queries each pane via show-options -p for per-pane overrides and emits pane_border lines only when the pane value differs from its window-level setting (actual overrides, not inherited values)

Restore side (restore.sh):

  • Extended restore_window_properties() to read and apply window-level pane-border-status and pane-border-format via set-option -w
  • New restore_pane_borders() function: applies per-pane overrides via set -p
  • restore_pane_titles() preserves the active pane (saves/restores it) around select-pane -T to avoid undoing restore_active_pane_for_each_window()

3. Backward compatibility

Old save files (missing pane_border lines and the two extra window fields) are handled gracefully:

  • Missing border_status/border_format fields → read assigns empty → skip checks → no-op
  • Missing pane_border lines → restore_pane_titles() builds an empty key set → no titles restored → original behavior
  • Missing pane_border lines → restore_pane_borders() reads nothing → no-op

4. Bug fix: is_line_type() tab anchor

The is_line_type() function used grep "^pane" which also matched pane_border lines (a new line type). This caused restore_all_panes() to feed pane_border data into restore_pane(), creating fake panes. Fixed by anchoring with a literal tab: grep "^${line_type}\t".

Related

Similar effort in #342 (c3r34lk1ll3r, 2020) proposed adding pane title save/restore — that feature was subsequently merged via #431 (Hologos). This PR builds on that foundation with border state persistence, post-process title re-application, and backward-compatible format extensions.

nuffin added 5 commits June 20, 2026 16:12
Shells (bash, zsh, etc.) set pane title via escape sequences during
startup (PROMPT_COMMAND/PS1), which overwrites the custom pane title
set during pane creation in restore_pane(). Running restore_pane_titles
after restore_all_pane_processes ensures custom titles like
"hermes-exec-pane" and "hermes-dialog-pane" survive the shell restart.
Save and restore window-level pane-border-status and pane-border-format
(via extended window format), plus per-pane overrides (via new
pane_border lines). This ensures that custom pane border labels like
"󰭻 Hermes 对话" and " 执行终端" survive save/restore.

- dump_windows() now captures window-level border status/format
- add dump_pane_borders() for per-pane overrides (only when different
  from window level, avoiding redundant data)
- restore_window_properties() applies window-level border options
- add restore_pane_borders() for per-pane border overrides
- called in main() after pane titles and processes are restored
Previously restore_pane_titles() restored the saved pane_title for ALL
panes, which would overwrite the dynamic shell-generated title
(e.g. "user@host: /path") with the stale value from save time.

Now it cross-references with pane_border lines: only panes that have
a custom border override (deliberate visual customization) get their
titles restored. For all other panes, the shell sets the title
dynamically as expected.
…tern

Two fixes:
1. select-pane -T changes the active pane, which undoes the work of
   restore_active_pane_for_each_window(). Save and restore the active
   pane around each title change to avoid unexpected active pane changes
   and the resulting layout shifts.
2. Use /^pane\t/ instead of /^pane/ in awk to avoid matching the new
   pane_border lines (harmless in practice but sloppy).
is_line_type() used grep "^pane" which also matches "pane_border".
When pane_border lines were fed to restore_pane(), the border format
string (e.g. "#[fg=yellow]  执行终端") was parsed as pane_index,
pane_exists() returned false, and new_pane() was called — creating
fake panes at the active pane position.

Fix: anchor the grep pattern with an actual tab character so that
is_line_type "pane" matches only lines starting with "pane\t".
@nuffin
nuffin force-pushed the feat/pane-title-persistence branch from 59b0ada to 1c228ba Compare June 20, 2026 08:13
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.

1 participant