Press Alt-q to open a centered native popup. Commands come from a small TOML file and reload every time the menu opens.
- Native popup — Herdr owns placement, focus, and dismissal.
- Live configuration — edit the menu without rebuilding or reloading Herdr.
- Flexible commands — run commands in the foreground or detach them immediately.
- Safe installer — preserves existing configuration and refuses key conflicts.
Requires macOS, Herdr 0.7.5 or newer, and a Rust toolchain.
herdr plugin install shadowfax92/herdr-menu
herdr plugin action invoke shadowfax.menu.installThe installer:
- creates the default plugin
config.tomlwhen it is missing; - adds the
alt+qbinding to Herdr's main config; - backs up a changed main config as
config.toml.menu-backup-*; - reloads Herdr.
It preserves an existing menu config and refuses to replace another alt+q binding. Repeating it is a byte-for-byte no-op.
The installed Herdr binding is:
[[keys.command]]
key = "alt+q"
type = "plugin_action"
command = "shadowfax.menu.open"
description = "Open command menu"Open the user-owned config:
menu_config_dir="$(herdr plugin config-dir shadowfax.menu)"
${EDITOR:-nvim} "$menu_config_dir/config.toml"Example:
title = "commands"
width = 64
max_height = 24
[[items]]
key = "h"
label = "hello world"
command = "echo 'hello world'"
[[items]]
key = "l"
label = "list files"
command = "ls"Top-level options:
| Field | Default | Meaning |
|---|---|---|
title |
commands |
Popup title |
width |
64 |
Popup width in terminal cells |
height |
unset | Fixed popup height; disables automatic height sizing |
max_height |
24 |
Maximum automatic height when height is unset |
Shell item options:
| Field | Default | Meaning |
|---|---|---|
type |
shell |
shell or separator |
key |
required | One printable ASCII accelerator; case-sensitive |
label |
required | Text shown in the menu |
command |
required | Shell command string |
mode |
foreground |
foreground or detached |
confirm |
none | Prompt shown before execution |
cwd |
source pane cwd | Absolute path or source-relative path |
A separator contains only type = "separator".
Commands run as $SHELL -lc <command> and inherit Herdr's plugin environment, including HERDR_BIN_PATH. Use that shell's syntax; options for builtins such as read are not portable across shells.
TOML literal strings preserve backslashes. Quote the Herdr path directly instead of escaping the double quotes:
command = '"$HERDR_BIN_PATH" server reload-config'Interactive commands can prompt after the menu releases the terminal. For Fish, use its read -P option:
command = 'read -P "Value: " value; test -z "$value"; or printf "%s\n" "$value"'The config is trusted user code; confirm is a convenience guard, not a security boundary.
| Key | Result |
|---|---|
| configured accelerator | Run that command |
Up / Down |
Move selection |
j / k |
Move when that character is not an accelerator |
Enter |
Run the selected command |
y / Enter |
Accept a confirmation |
n / Esc |
Cancel a confirmation |
Esc / Alt-q |
Close the menu |
Foreground commands own the popup terminal. Success closes the popup; failure returns to the menu with the exit error. Detached commands close the popup after a successful spawn and do not report their eventual status.
A malformed TOML document opens a closable error screen. Invalid individual entries are skipped while valid entries remain available; the popup shows the first warning and logs all warnings. For duplicate accelerators, the first valid item wins.
Herdr CLI operations work as normal shell commands. Herdr does not currently expose a generic API for native [keys] actions such as settings or workspace_picker; the required core contract is documented in TODO.md. The plugin does not emulate it through key injection.
git clone https://github.com/shadowfax92/herdr-menu.git
cd herdr-menu
herdr plugin link .
herdr plugin action invoke shadowfax.menu.installRun the local gate:
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test --locked
cargo build --release --locked