A LazyVim-style which-key popup for tmux. Press a trigger key to open a discoverable, keyboard-driven command menu with nested groups, breadcrumb navigation, and Nord-themed colors.
- Discoverable keybindings - see all available commands at a glance
- Nested groups - organize commands hierarchically (git, window, session, etc.)
- Breadcrumb navigation - always know where you are in the menu tree
- Nord color theme - clean, readable color scheme using 24-bit true color
- JSON configuration - easy to customize, extend, and share
- Five action types - shell commands (with optional auto-execute), tmux commands, external scripts, popups, and nested groups
- Single-keystroke input - no Enter key required, instant response
- tmux >= 3.3 (for
display-popupsupport) jq(for JSON parsing)- A terminal with true color (24-bit) support
With TPM (recommended)
Add to your ~/.tmux.conf:
set -g @plugin 'Nucc/tmux-which-key'Then press prefix + I to install.
Clone the repository:
git clone https://github.com/Nucc/tmux-which-key.git ~/.tmux/plugins/tmux-which-keyAdd to your ~/.tmux.conf:
run-shell ~/.tmux/plugins/tmux-which-key/which-key.tmuxReload tmux:
tmux source-file ~/.tmux.confPress prefix + Space (default) to open the which-key popup.
- Press a key to execute the corresponding command or enter a group
- Escape to go back one level or close the menu
- Backspace to go back one level or close the menu
Groups are indicated by a + prefix and shown in cyan. Pressing a group key opens its submenu with a breadcrumb showing your navigation path.
Set these in your ~/.tmux.conf before loading the plugin:
| Option | Default | Description |
|---|---|---|
@which-key-trigger |
Space |
Key binding (after prefix) to open the menu |
@which-key-config |
(auto-detected) | Path to a custom JSON config file |
@which-key-popup-height |
16 |
Popup height in lines |
@which-key-popup-width |
100 |
Popup width in characters |
@which-key-popup-bg |
#2E3440 |
Popup background color |
@which-key-popup-fg |
#4C566A |
Popup border/foreground color |
@which-key-popup-x |
C |
Popup X position (C = centered) |
@which-key-popup-y |
S |
Popup Y position (S = status line) |
Example:
set -g @which-key-config '~/.config/tmux-which-key/config.json'
set -g @which-key-popup-height '20'
set -g @which-key-popup-width '120'
set -g @plugin 'Nucc/tmux-which-key'By default the plugin binds prefix + Space. You can override this with @which-key-trigger, or create your own binding entirely in ~/.tmux.conf.
To bind Ctrl-Space directly (no prefix needed):
# Disable the default prefix binding
set -g @which-key-trigger 'None'
# Bind Ctrl-Space directly (-n = no prefix)
bind-key -n C-Space run-shell 'tmux display-popup -E -h 16 -w 100 -x C -y S -S "fg=#4C566A" -s "bg=#2E3440" "~/.tmux/plugins/tmux-which-key/scripts/which-key.sh #{pane_id}"'To use a custom config with a manual binding:
bind-key -n C-Space run-shell 'tmux display-popup -E -h 16 -w 100 -x C -y S -S "fg=#4C566A" -s "bg=#2E3440" "~/.tmux/plugins/tmux-which-key/scripts/which-key.sh --config ~/.config/tmux-which-key/config.json #{pane_id}"'The plugin looks for a config file in this order:
- Path set via
@which-key-configtmux option $XDG_CONFIG_HOME/tmux-which-key/config.json(usually~/.config/tmux-which-key/config.json)~/.tmux-which-key.json- Plugin's built-in
configs/default.json
To create your own config:
mkdir -p ~/.config/tmux-which-key
cp ~/.tmux/plugins/tmux-which-key/configs/default.json ~/.config/tmux-which-key/config.jsonThen edit ~/.config/tmux-which-key/config.json to your liking.
The config file is a JSON object with a top-level items array. Each item has:
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | yes | Single character that triggers this item |
type |
string | yes | One of: group, action, tmux, script, popup |
description |
string | yes | Label shown in the menu |
command |
string | for non-groups | Command to execute |
items |
array | for groups | Nested items in this group |
immediate |
boolean | no | For action type: also press Enter after pasting (default: false) |
| Type | Behavior | Example |
|---|---|---|
group |
Opens a submenu with nested items | Navigate to git commands |
action |
Sends text to the active pane (as if typed). With "immediate": true, also presses Enter. |
git status |
tmux |
Executes a tmux command directly | split-window -h |
script |
Runs a shell script via tmux run-shell |
~/scripts/my-script.sh |
popup |
Opens command in a temporary display-popup at the pane's working directory. Closes on exit or Escape. |
lazygit |
{
"items": [
{
"key": "g",
"type": "group",
"description": "git",
"items": [
{ "key": "s", "type": "action", "command": "git status", "description": "Status", "immediate": true },
{ "key": "c", "type": "action", "command": "git commit", "description": "Commit" },
{ "key": "g", "type": "popup", "command": "lazygit", "description": "Lazygit" }
]
},
{
"key": "w",
"type": "group",
"description": "window",
"items": [
{ "key": "v", "type": "tmux", "command": "split-window -h -c '#{pane_current_path}'", "description": "Split vertical" },
{ "key": "s", "type": "tmux", "command": "split-window -v -c '#{pane_current_path}'", "description": "Split horizontal" }
]
},
{ "key": "r", "type": "tmux", "command": "source-file ~/.tmux.conf \\; display-message 'Config reloaded'", "description": "Reload config" },
{ "key": "h", "type": "popup", "command": "htop", "description": "System monitor" },
{ "key": "d", "type": "script", "command": "~/scripts/deploy.sh", "description": "Deploy" }
]
}The built-in default config provides ~75 commands organized into 8 groups plus standalone items. Press prefix + Space to open the root menu:
| Key | Type | Description |
|---|---|---|
p |
group | Pane - split, navigate, zoom, swap, resize, and more |
w |
group | Window - create, kill, rename, find, navigate, move |
s |
group | Session - create, detach, choose, rename, kill, switch |
b |
group | Buffer - list, paste, choose, save/load, copy mode |
l |
group | Layout - cycle layouts and select presets |
C |
group | Client - list, choose, detach, refresh, lock |
o |
group | Options - show/set options, environment, messages |
g |
group | Git - status, diff, log, push, pull, branches, fetch, add, commit, rebase |
: |
tmux | Command prompt |
r |
tmux | Reload tmux config |
? |
tmux | List all keybindings |
c |
action | Clear screen |
t |
tmux | Clock mode |
d |
tmux | Display panes |
| Key | Description | Key | Description |
|---|---|---|---|
v |
Split vertical | s |
Split horizontal |
h/j/k/l |
Navigate panes | z |
Zoom toggle |
x |
Kill pane | o |
Last pane |
! |
Break to window | J |
Join pane |
m/M |
Mark/unmark pane | {/} |
Swap up/down |
c |
Clear history | q |
Capture to buffer |
p |
Respawn pane | r |
+Resize (subgroup) |
| Key | Description | Key | Description |
|---|---|---|---|
n |
New window | x |
Kill window |
r |
Rename | f |
Find window |
l |
Last window | . |
Next window |
, |
Previous window | w |
Choose window |
m |
Move window | s |
Swap window |
R |
Rotate panes |
| Key | Description | Key | Description |
|---|---|---|---|
n |
New session | d |
Detach |
s |
Choose session | w |
Choose tree |
r |
Rename | k |
Kill session |
l |
List sessions | L |
Lock session |
( |
Previous session | ) |
Next session |
| Key | Description | Key | Description |
|---|---|---|---|
l |
List buffers | p |
Paste |
c |
Choose buffer | d |
Delete buffer |
s |
Save to file | L |
Load from file |
v |
Show buffer | y |
Copy mode |
C |
Capture pane |
| Key | Description | Key | Description |
|---|---|---|---|
n |
Next layout | p |
Previous layout |
1 |
Even horizontal | 2 |
Even vertical |
3 |
Main horizontal | 4 |
Main vertical |
5 |
Tiled |
| Key | Description | Key | Description |
|---|---|---|---|
l |
List clients | c |
Choose client |
d |
Detach | D |
Detach other |
r |
Refresh | s |
Suspend |
L |
Lock |
| Key | Description | Key | Description |
|---|---|---|---|
g |
Show global options | w |
Show window options |
e |
Show environment | s |
Set global option |
c |
Customize mode | m |
Show messages |
k |
List commands |
MIT
