Skip to content

Tmux integration

This page documents the semantic differences and conveniences Honeymux introduces on top of vanilla tmux. These behaviors are applied through the control client bootstrap and through the helpers that drive splits, windows, and the quick terminal.

Honeymux runs its own dedicated tmux server on a separate socket — equivalent to running tmux -L honeymux — so it does not interact with any tmux servers you already have. Sessions, windows, and panes created inside Honeymux are not visible to a plain tmux ls outside Honeymux. To attach a second client to the same server (for example, from another terminal), use tmux -L honeymux attach rather than the default socket.

~/.tmux.conf is loaded by Honeymux’s tmux server when it starts — options, key bindings, and aliases all apply — but the bootstrap defaults below are written after tmux.conf runs and override any conflicting settings on Honeymux’s private server only. Your other tmux servers are unaffected.

When you create a new pane (split), pane tab, window, or quick terminal, the new shell starts in the active pane’s current working directory rather than the directory hmx was launched from.

Vanilla tmux does not do this. Its default bindings — bind c new-window, bind '"' split-window, and bind % split-window -h — all start new shells in the tmux server’s launch directory. The widely used remediation is to add -c "#{pane_current_path}" to each binding in tmux.conf. Honeymux applies that fix automatically through two mechanisms:

  • Honeymux-driven spawns. Splits, new windows, pane tabs, the quick terminal, and layout-profile pane creation all flow through the control client. Each spawn command embeds -c '#{pane_current_path}' literally, and tmux expands the format server-side at command-execution time.
  • Tmux’s default prefix bindings. The control client bootstrap conditionally rebinds C-b c, C-b ", and C-b %. It first queries the existing binding (list-keys -T prefix <key>) and only rewrites when the action body still matches tmux’s bare default (new-window, split-window, split-window -h). Anything else — a custom command, an existing -c, a removed binding — is left untouched.

If you have remapped split-window or new-window to your own keys, Honeymux does not modify those bindings. To get the same cwd behavior, append the format flag in your tmux.conf:

bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

When the control client connects, Honeymux applies a small set of opinionated defaults to its private tmux server:

  • detach-on-destroy on — exiting the last shell detaches the client cleanly. Tmux’s default would otherwise switch to another available session, which is undesirable when Honeymux owns the lifecycle.
  • window-size smallest — when multiple clients are attached to the server, panes size to the smallest attached client. This pairs with Honeymux’s 80×24 minimum floor on its own control client to keep layout predictable across multi-attach scenarios. If you attach a second client at a smaller size, panes shrink for everyone.
  • mouse on — mouse selection, drag-resize, and click-to-focus work out of the box. Most terminal emulators allow you to bypass tmux’s mouse capture for native selection by holding the terminal’s modifier key (commonly Shift).
  • Pane border styling — pane-border-status top is enabled and pane-border-format is set to a Honeymux-specific format that shows pane_current_command with active-pane highlighting in theme accent colors. pane-border-style and pane-active-border-style use the theme’s dim foreground so all border characters paint uniformly across active and inactive panes.

These are applied every time a Honeymux instance connects, so values from your tmux.conf are overridden if they conflict.

Honeymux persists its own metadata inside tmux via session-scoped and pane-scoped user options (the @-prefixed namespace tmux reserves for this purpose). All such options are prefixed with @hmx-:

  • @hmx-agent-socket-path — per-pane socket path for coding-agent hook routing.
  • @hmx-color — per-session display color used in session selectors.
  • @hmx-local-window-id — remote-mirror layout pinning.
  • @hmx-pane-tab-active, @hmx-pane-tab-member — per-pane routing for active pane tabs.
  • @hmx-pane-tabs-v1 — serialized pane-tab group state for the session.
  • @hmx-remote-host, @hmx-remote-pane, @hmx-remote-token — remote-stitching attribution on the local proxy pane.

If you inspect a Honeymux session with tmux -L honeymux show-options -t <session> (or show-options -p for pane scope), you will see these load-bearing values. Removing them with set-option -u will break the corresponding feature on that session or pane until Honeymux reattaches and rewrites them.

The design rule behind this is that Honeymux state should live with the tmux objects it describes, not in an external sidecar file — so detach, reattach, server restart, and move-window all carry the metadata along automatically.

The pane tabs feature stores inactive tabs as panes in hidden tmux windows named _hmx_tab. These windows are excluded from the Honeymux UI, but they are real tmux windows and will appear in raw inspection commands such as tmux -L honeymux list-windows -a. Each _hmx_tab window holds the pane(s) that are not currently swapped into the visible slot; when you switch tabs, Honeymux performs a swap-pane between the visible pane and one stashed in a staging window.

Screen captures powered by Honeyshots

Copyright © 2026 Aaron Campbell · Apache 2.0