动机

在 Neovim 里用惯了 which-key,按完前缀弹出个菜单提醒快捷键,对记忆负担小。想在 tmux 里也搞一套。

社区有几个方案:

  • tmux-which-key —— 功能最接近 Neovim 的 which-key,YAML 配置层级菜单,基于 tmux 的 display-menu
  • tmux-menus —— 预设菜单集合,覆盖常用操作。
  • tmux 原生 display-menu —— tmux 3.0+ 内置,不用插件,自己写绑定就能弹菜单。

插件方案要先装 tpm,我这边 tpm 都还没装,且配置文件里没几行,直接用原生 display-menu 最省事。

基本用法

bind Space display-menu -T "#[align=centre]Menu" -x C -y C \
  "New window"  c  "new-window" \
  "Split horizontal"  -  "split-window -v" \
  "Kill pane"  x  "kill-pane"

每行三个参数:显示文本、快捷字符、执行命令。prefix + Space 弹出菜单。

  • -T 标题,#[align=centre] 是 style 标记让标题居中
  • -x C -y C 位置居中
  • 空字符串 "" 作为"项"是分隔线

菜单里按对应字母直接选,也能用 j/k 或方向键上下移动,回车确认,qEsc 关闭。

完整菜单配置

分三块:pane 操作、window 操作、session 操作,外加几个常用模式项。

bind Space display-menu -T "#[align=centre]Menu" -x C -y C \
  "Split horizontal"  - "split-window -v" \
  "Split vertical"    | "split-window -h" \
  "Zoom pane"         z "resize-pane -Z" \
  "Break to window"   b "break-pane" \
  "Swap with next"    "}" "swap-pane -D" \
  "Swap with prev"    "{" "swap-pane -U" \
  "Rotate panes"      o "rotate-window" \
  "Even horizontal"   = "select-layout even-horizontal" \
  "Even vertical"     + "select-layout even-vertical" \
  "Main layout"       m "select-layout main-vertical" \
  "Kill pane"         x "kill-pane" \
  "" \
  "New window"        c "new-window" \
  "Next window"       n "next-window" \
  "Previous window"   p "previous-window" \
  "Choose window"     w "choose-tree -Zw" \
  "Rename window"     , "command-prompt -I '#W' 'rename-window %%'" \
  "Swap window left"  "<" "swap-window -t -1 ; previous-window" \
  "Swap window right" ">" "swap-window -t +1 ; next-window" \
  "Kill window"       X "kill-window" \
  "" \
  "Choose session"    s "choose-tree -Zs" \
  "New session"       S "command-prompt -p 'Session name:' 'new-session -s %%'" \
  "Rename session"    R "command-prompt -I '#S' 'rename-session %%'" \
  "" \
  "Copy mode"         "[" "copy-mode" \
  "Paste"             "]" "paste-buffer" \
  "Clock"             t "clock-mode"

几个项说明:

  • choose-tree -Zw / choose-tree -Zs —— tmux 内置的 window/session 选择器,-Z 是 zoom 全屏显示
  • break-pane —— 把当前 pane 抽出成独立 window
  • swap-pane -D/-U —— 和下一个/上一个 pane 交换位置
  • command-prompt -I '#W' 'rename-window %%' —— 弹出命令行,预填当前 window 名,输入新名回车替换
  • "" 做分组分隔线

自定义菜单导航键

tmux 3.4+ 支持 menu key-table,可以在菜单里自定义按键。比如想要 Emacs 风格的 Ctrl-n/Ctrl-p 上下移动:

bind -T menu C-n send -X menu-down
bind -T menu C-p send -X menu-up

内置的 j/k、方向键、数字/字母快捷键都仍然可用。

实测用 j/k 足够顺手,最后没留这两行。

输入法冲突

菜单里的单字符快捷键(xcw 等)在中文输入法下会被吞当拼音。两个解决方向:

  1. 菜单键改用数字或符号,避开字母 —— 损失助记性
  2. 在 prefix 触发时自动切到 ABC —— 一劳永逸

推荐第二种,具体做法见 tmux 输入法自动切换

小结

tmux 的 display-menu 够用了,没必要上插件:

  • 零依赖,配置文件里就能写
  • 层级菜单靠分隔线视觉分组就够,真要多级可以嵌套 display-menu 命令
  • 按键冲突、颜色、对齐都能控制

下次想加新操作,往菜单里追加一行就行。