https://github.com/patrickfanella/tmux-popups
Small tmux popup toolkit with a TSV registry, generated bindings, and shell tools.
https://github.com/patrickfanella/tmux-popups
shell shell-script shell-tools tmux tpm tpm-plugin
Last synced: 2 months ago
JSON representation
Small tmux popup toolkit with a TSV registry, generated bindings, and shell tools.
- Host: GitHub
- URL: https://github.com/patrickfanella/tmux-popups
- Owner: PatrickFanella
- License: mit
- Created: 2026-05-02T17:45:07.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-02T18:32:23.000Z (2 months ago)
- Last Synced: 2026-05-02T19:28:43.732Z (2 months ago)
- Topics: shell, shell-script, shell-tools, tmux, tpm, tpm-plugin
- Language: Shell
- Homepage:
- Size: 15.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# tmux-popups
Small tmux popup toolkit with a TSV registry, generated bindings, shared shell helpers, dependency checks, and optional local overrides.
## Features
- `Prefix+d` quick menu generated from registry rows
- Direct bindings generated from the same rows
- Default registry: `popups.tsv`
- Local override registry: `~/.config/tmux-popups/popups.local.tsv`
- Dependency status in help and CLI output
- Doctor script for common tmux/TPM/config problems
- Bash-only implementation; no build step
- Generated config stored at `${XDG_CACHE_HOME:-$HOME/.cache}/tmux-popups/generated.conf`
## Install with TPM
Add to `~/.tmux.conf` or your sourced tmux config:
```tmux
set -g @plugin 'PatrickFanella/tmux-popups'
```
Reload tmux, then press TPM install key (`prefix + I`).
## Install manually
```sh
git clone https://github.com/PatrickFanella/tmux-popups.git ~/.config/tmux/plugins/tmux-popups
```
Then source the plugin entrypoint:
```tmux
run-shell "$HOME/.config/tmux/plugins/tmux-popups/tmux-popups.tmux"
```
Reload tmux:
```sh
tmux source-file ~/.tmux.conf
```
## Local development with TPM
Useful when hacking on the plugin but still letting TPM manage load/update keys.
```sh
git clone https://github.com/PatrickFanella/tmux-popups.git ~/Projects/tools/tmux-popups
mkdir -p ~/.config/tmux/plugins
ln -sfn ~/Projects/tools/tmux-popups ~/.config/tmux/plugins/tmux-popups
```
Keep TPM registration in tmux config:
```tmux
set -g @plugin 'PatrickFanella/tmux-popups'
```
TPM will see `tmux-popups`; the symlink points it at your working tree.
## Default bindings
The default registry includes the full popup set. Some rows need optional tools; dependency status is visible in `Prefix+C-h` and `scripts/list-popups.sh --deps`.
| Key | Popup |
| --- | --- |
| `Prefix+d` | Quick menu |
| `Prefix+C-h` | Popup help + dependency status |
| `Prefix+C-g` | quick chat via [`ocq`](https://github.com/PatrickFanella/ocq) |
| `Prefix+C-o` | opencode |
| `Prefix+C-t` | shell |
| `Prefix+C-n` | daily note |
| `Prefix+C-y` | lazygit |
| `Prefix+C-r` | yazi |
| `Prefix+C-f` | ferrosonic |
| `Prefix+C-b` | tmux key list |
| `Prefix+C-z` | edit `~/.zshrc` |
| `Prefix+C-S-r` | reload tmux config |
Session switching is intentionally left to [`tmux-sessionx`](https://github.com/omerxx/tmux-sessionx). Example:
```tmux
set -g @plugin 'omerxx/tmux-sessionx'
set -g @sessionx-bind 'j'
set -g @sessionx-prefix 'on'
set -g @sessionx-window-height '80%'
set -g @sessionx-window-width '60%'
```
Then `Prefix+j` opens sessionx. If you prefer tmux's built-in picker, copy the `sessions` row from `examples/popups.optional.tsv`.
## Plugin options
Set these before the plugin loads:
```tmux
set -g @tmux-popups-menu-key 'd'
set -g @tmux-popups-reload-key 'C-S-r'
set -g @tmux-popups-default-width '80%'
set -g @tmux-popups-default-height '80%'
set -g @tmux-popups-local-registry '~/.config/tmux-popups/popups.local.tsv'
set -g @tmux-popups-enable-vscode 'on'
set -g @tmux-popups-vscode-command 'code-insiders .'
```
Use `-` in a row's width or height to inherit the default width/height options.
## Registry format
Rows are tab-separated:
```tsv
id direct_key menu_key title width height command
```
| Column | Meaning |
| --- | --- |
| `id` | Unique popup id used by `scripts/run-popup.sh` |
| `direct_key` | Direct tmux binding after prefix, or `-` for none |
| `menu_key` | Key in quick menu, or `-` for none |
| `title` | Popup title |
| `width` | tmux popup width, e.g. `80%`, or `-` for default |
| `height` | tmux popup height, e.g. `80%`, or `-` for default |
| `command` | Plugin-relative script path, or `-` for an interactive shell |
Blank lines and lines beginning with `#` are ignored.
## Local override registry
Default path:
```text
~/.config/tmux-popups/popups.local.tsv
```
The plugin merges:
```text
popups.tsv
+ popups.local.tsv
-> generated bindings
```
If a local row has the same `id` as a default row, the local row overrides it while keeping the original order. New local ids are appended.
Example local override: move chat to another key and use default popup size:
```tsv
chat C-a a quick chat - - scripts/tools/chat.sh
```
Example local-only scratch shell:
```tsv
scratch C-s s scratch shell 80% 80% -
```
Reload tmux after edits:
```sh
tmux source-file ~/.tmux.conf
```
## Create a popup script
Create `scripts/tools/hello.sh`:
```sh
#!/usr/bin/env bash
set -euo pipefail
printf 'Hello from tmux-popups.\n\nPress Enter to close... '
read -r _ || true
```
Make it executable:
```sh
chmod +x scripts/tools/hello.sh
```
Add a row to `popups.tsv` or your local registry:
```tsv
hello - h hello 75% 75% scripts/tools/hello.sh
```
Reload tmux and open it with `Prefix+d`, then `h`.
## Optional examples
Extra rows live in:
```text
examples/popups.optional.tsv
```
Copy rows into your local registry or `popups.tsv`, install matching tools, then reload tmux.
Examples:
```tsv
sessions C-j j sessions 80% 80% scripts/tools/sessions.sh
chat C-g g quick chat 80% 80% scripts/tools/chat.sh
yazi C-r r yazi 80% 80% scripts/tools/yazi.sh
```
`chat` needs [`ocq`](https://github.com/PatrickFanella/ocq).
## List and dependency helpers
```sh
scripts/list-popups.sh --pretty
scripts/list-popups.sh --deps
scripts/list-popups.sh --tsv
scripts/list-popups.sh --deps-tsv
```
`Prefix+C-h` shows the same dependency status inside tmux.
Dependency groups can contain alternatives, e.g. `glow|bat|less` means one of those commands is enough.
## Doctor
Run:
```sh
scripts/doctor.sh
```
It checks:
- tmux availability/version
- plugin root
- default/local registries
- TPM path and local plugin entry
- TPM registration in tmux config
- generated config creation
- `tmux source-file -n` validation
- per-popup dependency status
Warnings are informational. Failures exit nonzero.
## Validate generated config
```sh
scripts/generate-config.sh
tmux source-file -n ~/.cache/tmux-popups/generated.conf
tmux source-file ~/.tmux.conf
```
## CI
GitHub Actions runs:
- `bash -n` on plugin scripts
- ShellCheck
- config generation smoke test
## Optional tools used by default/extra rows
- [`ocq`](https://github.com/PatrickFanella/ocq) for quick OpenCode chat
- `opencode`
- `task` / Taskwarrior
- `nvim`, `vim`, `vi`, or `$EDITOR`
- `tldr`, `man`, `less`
- `khal`, `cal`
- `python3`
- `ssh`, `fzf`
- `cliphist`, `wl-copy`, `wl-paste`
- `newsboat`, `curl`
- `journalctl`, `tail`, `watch`
- `glow`, `bat`
- `lazygit`, `yazi`, `ferrosonic`
## How it works
```text
popups.tsv + optional local registry
-> scripts/list-popups.sh --tsv
-> scripts/generate-config.sh
-> ~/.cache/tmux-popups/generated.conf
-> tmux source-file
```
`scripts/run-popup.sh ` reads the merged registry and executes the matching command inside `display-popup`.
## Files
- `popups.tsv`: default popup registry
- `~/.config/tmux-popups/popups.local.tsv`: optional local overrides
- `examples/popups.optional.tsv`: optional popup row examples
- `tmux-popups.tmux`: TPM/manual entrypoint
- `scripts/list-popups.sh`: merged registry and dependency listing
- `scripts/generate-config.sh`: generates tmux bindings
- `scripts/run-popup.sh`: dispatches popup ids to tool scripts
- `scripts/doctor.sh`: diagnostics
- `scripts/popup-help.sh`: help popup
- `scripts/lib.sh`: shared shell helpers
- `scripts/tools/*.sh`: popup tool implementations
## License
MIT