tmux-popups

tmux-popups / field notes

Set your keys.
Keep your tools close.

Install the toolkit, open the quick menu, then add only what you need. The repository README is the complete option reference.

Install

You need a running tmux server and Bash. Use a tmux version with popup support. Some adapters need an editor or other installed tools; Python 3 is needed for JSON arguments and retained-exit recovery. The toolkit has no build step.

Install from source. There is no tagged release yet; see the release review for verification limits.

With TPM

Add this to your tmux config, alongside your other TPM registrations:

set -g @plugin 'PatrickFanella/tmux-popups'

Reload the config, then press Prefix + I to run TPM’s installer. The shorthand uses the GitHub push mirror; development and pull requests live on Gitea.

Manually

Clone the canonical repository:

git clone https://git.subcult.tv/PatrickFanella/tmux-popups.git ~/.config/tmux/plugins/tmux-popups

Add the entrypoint to your tmux config:

run-shell "$HOME/.config/tmux/plugins/tmux-popups/tmux-popups.tmux"

From an attached tmux pane, reload that file. For the usual path:

tmux source-file ~/.tmux.conf

If your config lives elsewhere, use its actual path and set @tmux-popups-config-file before loading the plugin. Configuration examples follow below.

First run & keys

Press Prefix + Enter. The small profile enables five entries: help, shell, daily notes, timer and tmux keys. Prefix means your configured tmux prefix, commonly Ctrl + b.

KeyAction
Prefix + EnterOpen the quick menu
Prefix + Ctrl-hHelp and dependency status
Prefix + TShell
Menu NDaily note
Menu PTimer
Prefix + Ctrl-btmux keys
Prefix + RReload the configured tmux file

Existing prefix bindings are skipped by default. If a shortcut appears not to work, check doctor’s conflict report.

The shell starts in the invoking pane’s directory. Daily notes default to ~/Notes/daily/YYYY-MM-DD.md; configure NOTES_DIR and your editor as needed. The timer accepts 1–1440 whole minutes, defaults to 25, and stops with Ctrl-C.

Configuration

Put plugin options before the plugin loads. These are the defaults:

set -g @tmux-popups-menu-key 'Enter'
set -g @tmux-popups-reload-key 'R'
set -g @tmux-popups-default-width '80%'
set -g @tmux-popups-default-height '80%'
set -g @tmux-popups-profile 'small'
set -g @tmux-popups-availability 'show-disabled'
set -g @tmux-popups-conflicts 'skip'

Rows with their own dimensions keep them: the shipped shell and timer use 75% × 75%. A row’s - width or height inherits the corresponding default.

For an XDG tmux config, set:

set -g @tmux-popups-config-file '~/.config/tmux/tmux.conf'

full enables all shipped entries. Availability show-disabled keeps missing tools visible as disabled labels; hide-unavailable omits them; ignore skips dependency preflight. An explicit per-entry enabled option takes precedence.

Conflict policy skip keeps an existing prefix binding. warn reports and replaces a newly claimed key; replace replaces it without a warning. All policies protect later user replacements or explicit unbinds of an owned key.

After editing, source your tmux config to load its options, then reload through the plugin entrypoint. Do not source the generated cache directly: that bypasses binding reconciliation.

Local registry

The shipped registry is popups.tsv. Keep personal rows in ${XDG_CONFIG_HOME:-$HOME/.config}/tmux-popups/popups.local.tsv, outside the plugin checkout. A row with an existing ID overrides that entry in place; new IDs append.

Use real tabs, with seven to thirteen nonempty fields. A dash means the documented default or no shortcut. The first seven fields are:

id  direct_key  menu_key  title  width  height  command

Here is a shell override. The separators in this example are tabs, ready to copy to your local TSV file:

shell	T	Enter	shell	90%	85%	-

Fields 8–13 add mode, completion, enabled, deps, kind and arguments. Read the complete field contract before adding executable or argument fields.

A nonempty TMUX_POPUPS_LOCAL_REGISTRY selects a file before the @tmux-popups-local-registry option, then the optional XDG default. Explicitly selected missing files are errors.

Personal scripts

Keep scripts in ${XDG_CONFIG_HOME:-$HOME/.config}/tmux-popups/scripts and make them executable. Use user or absolute kind for personal files. JSON arrays pass literal arguments and require Python 3. Only the explicit shell kind evaluates an expression.

The script walkthrough includes a complete thirteen-column row. All rows, including disabled ones, must have valid metadata and executables. Validation failures leave the last good generated cache intact.

Optional tools

The registry ships 25 entries, with five enabled in the small profile. Enable a tool without copying its row:

set -g @tmux-popups-lazygit-enabled 'on'

Install lazygit separately, place that option before the plugin load, then reload. Enabled state and dependency state are separate: an off entry has no binding; an enabled entry can still be unavailable.

From your plugin checkout, inspect the effective registry:

scripts/list-popups.sh --pretty
scripts/list-popups.sh --deps

--tsv and --deps-tsv provide machine-readable output. Help and doctor use the same registry resolver.

Search and project actions

Copy selected rows from optional examples or project examples. Check shortcuts for collisions before combining them.

The optional search launcher uses fzf when available and falls back to a native tmux menu. Project actions provide Git status, a shell, project notes and a coding-tool example. Session switching is left to tmux-sessionx or the optional built-in sessions row.

Dependency checks confirm local commands, not provider accounts or application configuration. The chat adapter, for example, needs its own working provider setup.

Modes & window reuse

  • popup: an interactive popup over the invoking pane.
  • window: a normal tmux window in the invoking session.
  • command: an action that needs no terminal input. Background completion is available only in this mode.

The legacy Yazi, home, projects and downloads adapters default to window mode. An explicit row mode takes precedence.

For an optional Yazi window that you can return to:

set -g @tmux-popups-yazi-enabled 'on'
set -g @tmux-popups-yazi-reuse 'session'

Reuse is off by default. session selects the live tool window in the invoking session. directory also requires the exact invoking directory to match. Reuse applies only to window mode; a reused process keeps its original environment and working directory.

Direct and menu launches capture the invoking client, session, window, pane and directory. See the context contract for the exported TMUX_POPUPS_* variables.

Keep failures readable

The default close policy is always: the view closes when the tool exits. Retain a failure with on-success, or every exit with never:

set -g @tmux-popups-yazi-enabled 'on'
set -g @tmux-popups-yazi-close 'on-success'

Retained policies need Python 3 and apply to popup or window mode. The recovery view shows the application’s exit status:

  • r starts the entry again.
  • c or Enter closes the view.
  • w, from a popup, starts the entry again in a new window.

Retry starts a new process with the original invoking context. It does not move the old live process or recover an application session. Close and relaunch to pick up changes to the server environment. Ctrl-C cancels and closes the launch.

Troubleshooting

Run these from the plugin checkout, inside the affected tmux server:

scripts/doctor.sh

Doctor reports selected options, registry sources, dependency status, conflicts and the proposed binding plan. Ordinary diagnosis leaves the shared cache, effective bindings and ownership unchanged.

Missing shortcut

Check for an existing prefix binding: the default conflict policy skips it. Change the shortcut or deliberately choose another policy, then reload through tmux-popups.tmux. Duplicate shortcuts inside the registry remain validation errors under every policy.

Input trouble in a popup

Run a bounded input check in the affected popup or window:

scripts/doctor.sh --input-check 10

Type tmux-popups and press Enter. The check prints received bytes, TERM and the tmux version; it needs an attached terminal. The duration can be 1–30 seconds. Ctrl-C cancels. This check does not qualify every application’s terminal queries or provider behavior.

Invalid registry or stale cache

Fix the file and line reported by doctor. To validate and explain a candidate before applying it, use:

scripts/generate-config.sh
scripts/apply-config.sh --explain "${XDG_CACHE_HOME:-$HOME/.cache}/tmux-popups/generated.conf"

Generation validates and publishes the cache; explanation does not apply the keys. Source your tmux config if options changed, then run ./tmux-popups.tmux to generate and reconcile bindings. Read the full troubleshooting guide before filing an issue.

Update & rollback

For TPM, use Prefix + U and select tmux-popups. For a manual installation, record the current Git revision and save your config and local registry before updating. Preserve any uncommitted work.

The migration and rollback guide has the complete save, fetch, reload and return-to-revision commands. Older revisions may not understand newer fields or options.

Reload through the plugin entrypoint. Sourcing generated.conf directly bypasses binding conflict and restoration policies.

Personal registries and scripts outside the checkout are left alone by plugin updates. Existing tool processes keep their old environment until closed and relaunched.

More

Report a reproducible problem on Gitea with the relevant doctor output and terminal, tmux and application versions. Remove private paths, arguments and credentials before sharing logs.

No separate contributing guide or security policy is published in this repository. Development and pull requests go to the canonical Gitea source; issue and contribution pages may require a Gitea account. Reading links use the public GitHub mirror.