重新加载 tmux 配置不会解除绑定键(绑定键是累积的)

Nie*_*Bom 35 keyboard-shortcuts tmux

我一直在尝试不同的 tmux 键绑定设置,我注意到以下几点:

如果我重新加载我的 tmux 配置(从 tmux 中),我曾经加载的键绑定将保持加载状态。清理它的唯一方法(我知道)是退出所有 tmux 会话并重新启动。所以看起来 tmux 会记住所有以前加载的键绑定,并且只会在重新开始时或通过显式解除绑定来删除它们。

要重新创建这个:

  • 打开终端(A)
  • 启动 tmux
  • 检查键绑定是否显示时钟(按PREFIX C-t
  • PREFIX ?以查看列表中的键绑定
  • 编辑 ~/.tmux.conf
  • 添加键绑定 ( bind C-t display "Keybinding C-t")
  • 重新加载 tmux 配置 ( PREFIX : source-file ~/.tmux.conf)
  • 检查键绑定是否有效(按PREFIX C-t
  • 按下PREFIX ?以查看列表中的新键绑定
  • ~/.tmux.conf再次编辑
  • 删除键绑定(所以删除bind C-t display "Keybinding C-t"
  • 重新加载 tmux 配置 ( PREFIX : source-file ~/.tmux.conf)
  • 检查键绑定是否有效(按PREFIX C-t),它仍然显示“键绑定Ct”
  • 按下PREFIX ?以查看新的键绑定仍在列表中
  • 退出 tmux
  • 输入 tmux
  • 检查原始键绑定是否再次起作用(按PREFIX C-t),它现在应该再次显示时钟
  • 按下PREFIX ?以查看新的键绑定已从列表中删除

我的问题:有没有办法指示 tmux“忘记”所有加载的配置然后加载.tmux.conf

pet*_*rph 22

根据tmux(1)手册页,unbind-key -a就是您要查找的内容。

请注意,tmux运行的服务器只有在所有会话都关闭后才会退出,并且键绑定是针对每个服务器的。因此,一旦您创建了一个绑定,它将在所有客户端分离中保持不变。

也就是说,放在unbind-key -a配置文件的最顶部,并在配置重新加载时它应该做你想做的 - 解除所有绑定并从头开始绑定。或者 - 如果您的修改较小 - 仅取消绑定您想要更改的内容。


Nie*_*Bom 18

正确的解决方案(彼得

所以@peterph 给出了正确的答案,unbind-key -a它执行以下操作:(man tmux)

如果存在 -a,则删除所有键绑定。

一个可行的解决方案

问题(对我而言)是“全部”实际上意味着全部。包括 tmux 附带的键绑定。如果您unbind-key -a立即执行命令 tmux,则根本不再有任何键绑定,因此您甚至无法进入命令模式或执行任何操作。

我对此的(相当丑陋的)修复如下:

  • 创建一个.tmux.reset.conf删除所有键绑定然后重新绑定所有 tmux 默认情况下的键绑定
  • 在您的顶部重置的源 .tmux.conf

我的.tmux.conf

# always load the reset file first
source-file ~/.tmux.reset.conf
Run Code Online (Sandbox Code Playgroud)

我的.tmux.reset.conf

# First remove *all* keybindings
unbind-key -a
# Now reinsert all the regular tmux keys
bind-key C-b send-prefix
bind-key C-o rotate-window
bind-key C-z suspend-client
bind-key Space next-layout
bind-key ! break-pane
bind-key " split-window
bind-key # list-buffers
bind-key $ command-prompt -I #S "rename-session '%%'"
bind-key % split-window -h
bind-key & confirm-before -p "kill-window #W? (y/n)" kill-window
bind-key ' command-prompt -p index "select-window -t ':%%'"
bind-key ( switch-client -p
bind-key ) switch-client -n
bind-key , command-prompt -I #W "rename-window '%%'"
bind-key - delete-buffer
bind-key . command-prompt "move-window -t '%%'"
bind-key 0 select-window -t :0
bind-key 1 select-window -t :1
bind-key 2 select-window -t :2
bind-key 3 select-window -t :3
bind-key 4 select-window -t :4
bind-key 5 select-window -t :5
bind-key 6 select-window -t :6
bind-key 7 select-window -t :7
bind-key 8 select-window -t :8
bind-key 9 select-window -t :9
bind-key : command-prompt
bind-key ; last-pane
bind-key = choose-buffer
bind-key ? list-keys
bind-key D choose-client
bind-key L switch-client -l
bind-key [ copy-mode
bind-key ] paste-buffer
bind-key c new-window
bind-key d detach-client
bind-key f command-prompt "find-window '%%'"
bind-key i display-message
bind-key l last-window
bind-key n next-window
bind-key o select-pane -t :.+
bind-key p previous-window
bind-key q display-panes
bind-key r refresh-client
bind-key s choose-session
bind-key t clock-mode
bind-key w choose-window
bind-key x confirm-before -p "kill-pane #P? (y/n)" kill-pane
bind-key { swap-pane -U
bind-key } swap-pane -D
bind-key ~ show-messages
bind-key PPage copy-mode -u
bind-key -r Up select-pane -U
bind-key -r Down select-pane -D
bind-key -r Left select-pane -L
bind-key -r Right select-pane -R
bind-key -r M-1 select-layout even-horizontal
bind-key -r M-2 select-layout even-vertical
bind-key -r M-3 select-layout main-horizontal
bind-key -r M-4 select-layout main-vertical
bind-key -r M-5 select-layout tiled
bind-key -r M-n next-window -a
bind-key -r M-o rotate-window -D
bind-key -r M-p previous-window -a
bind-key -r M-Up resize-pane -U 5
bind-key -r M-Down resize-pane -D 5
bind-key -r M-Left resize-pane -L 5
bind-key -r M-Right resize-pane -R 5
bind-key -r C-Up resize-pane -U
bind-key -r C-Down resize-pane -D
bind-key -r C-Left resize-pane -L
bind-key -r C-Right resize-pane -R
Run Code Online (Sandbox Code Playgroud)

看起来这可能适用于 tmux 键表(据我所知),但您不能添加新的键表。

  • `tmux -f /dev/null -L temp start-server \; list-keys` 将有效地生成默认值(尽管您需要在其绑定的分号前添加反斜杠)。 (2认同)

Chr*_*sen 7

目前没有直接的方法可以将键的绑定重置为其默认值;默认绑定 (in key_bindings_init())的初始化在tmux服务器第一次启动 (in server_start())时完成一次,并且没有重置单个密钥的机制。

对于您要采购你的配置文件,以重新建立一个默认绑定以前由自定义绑定已被从您的配置文件中删除重写的行为所需的场景,你设计的方法是合理的(但不幸的详细): unbind-key -a,然后重新建立所有“默认”绑定,然后建立您的自定义绑定(其中一些可能会覆盖“默认”绑定)。

可以使用list-keys命令*提取服务器的当前绑定;这可以帮助生成/维护您建议的.tmux.reset.conf文件,但您需要一种方法来提取默认绑定,而不是当前绑定。

* 在某些情况下,list-keys当前不能直接使用的输出:分号的绑定需要用反斜杠对其分号进行转义,以防止其被解释为tmux命令分隔符,以及任何具有在引号内使用双引号的参数的绑定引号(没有一个默认绑定是这样的)将作为双引号内的引号出现。

要获得默认绑定,您需要一个具有最少配置(即没有自定义绑定)的临时服务器,以便您可以捕获其list-keys输出。您可以运行的tmux服务器数量没有限制,但每个服务器必须使用不同的套接字路径名;the-L-S tmux选项可用于指定套接字名称(在$TMPDIR/tmux-$UID或完整套接字路径名。因此,要与名为 的套接字上的新服务器通信(或启动)temp,您可以使用以下命令:

tmux -L temp …
Run Code Online (Sandbox Code Playgroud)

为了确保它不使用你的.tmux.conf,你-f用来告诉它读取/dev/null(一个总是空的特殊文件):

tmux -f /dev/null -L temp …
Run Code Online (Sandbox Code Playgroud)

注意:这不会阻止处理/etc/tmux.conf, 如果这样的文件存在;这个“系统配置文件”的路径是硬编码的,没有绕过它的选项(缺少修补代码)。

通常,您需要一个new-session命令来实际启动服务器,但我们不需要任何会话,只需要一个初始化的服务器来查询。该start-server命令就是这样做的:在不创建任何会话的情况下启动服务器。

tmux -f /dev/null -L temp start-server …
Run Code Online (Sandbox Code Playgroud)

现在,我们只需要附加我们的“查询”命令(list-keys在这种情况下):

tmux -f /dev/null -L temp start-server \; list-keys
Run Code Online (Sandbox Code Playgroud)

注意:分号需要转义或引用以防止 shell 将其视为 shell 命令分隔符,因为我们希望它是tmux命令分隔符。

由于没有会话要维护,服务器将在运行完list-keys命令后自动退出。

因此,您可以使用这样的命令来生成大部分文件,.tmux.reset.conf而不必担心临时删除.tmux.conf文件(让您只看到默认绑定),也无需关闭任何现有服务器。


如果run-shell命令是同步的,您可以在您的配置文件中嵌入这样的调用(捕获到一个临时文件,然后您将使用该文件进行处理source-file),而不是拥有一个静态文件(您的.tmux.reset.conf)。这将使您始终使用当前tmux版本中的默认绑定(默认绑定偶尔会更改)。唉,run-shell命令的完成当前与后续命令是异步的(命令之后的run-shell命令通常会在产生的进程run-shell有机会完成之前运行)。


Ric*_*ook 6

这是将所有其他答案汇总到 bash 脚本中,该脚本将.tmux.reset.conf根据默认键绑定自动生成:

#!/bin/bash
tmux -f /dev/null -L temp start-server \; list-keys | \
  sed -r \
  -e "s/bind-key(\s+)([\"#~\$])(\s+)/bind-key\1\'\2\'\3/g" \
  -e "s/bind-key(\s+)([\'])(\s+)/bind-key\1\"\2\"\3/g" \
  -e "s/bind-key(\s+)([;])(\s+)/bind-key\1\\\\\2\3/g" \
  -e "s/command-prompt -I #([SW])/command-prompt -I \"#\1\"/g" \
  > ~/.tmux.reset.conf
Run Code Online (Sandbox Code Playgroud)

嵌入式sed命令行负责从list-keys. 这可能需要针对您的系统的具体情况进行一些调整。

在您的.tmux.conf文件中,在定义您自己的键绑定之前,只需取消绑定所有键并获取此文件:

unbind-key -a
source-file ~/.tmux.reset.conf
Run Code Online (Sandbox Code Playgroud)


Ste*_* Lu 5

另请参阅此处的其他答案,因为他们很好地解释了情况。我这里有我的tmux 1.8兼容的 tmux.reset.conf,在复制输出后我必须对其进行一些修改tmux -f /dev/null -L temp start-server \; list-keys。特别是,有几件事必须引用。

# First remove *all* keybindings
unbind-key -a
# Now reinsert all the regular tmux keys
bind-key C-b send-prefix
bind-key C-o rotate-window
bind-key C-z suspend-client
bind-key Space next-layout
bind-key ! break-pane
bind-key '"' split-window
bind-key '#' list-buffers
bind-key '$' command-prompt -I "#S" "rename-session '%%'"
bind-key % split-window -h
bind-key & confirm-before -p "kill-window #W? (y/n)" kill-window
bind-key "'" command-prompt -p index "select-window -t ':%%'"
bind-key ( switch-client -p
bind-key ) switch-client -n
bind-key , command-prompt -I "#W" "rename-window '%%'"
bind-key - delete-buffer
bind-key . command-prompt "move-window -t '%%'"
bind-key 0 select-window -t :0
bind-key 1 select-window -t :1
bind-key 2 select-window -t :2
bind-key 3 select-window -t :3
bind-key 4 select-window -t :4
bind-key 5 select-window -t :5
bind-key 6 select-window -t :6
bind-key 7 select-window -t :7
bind-key 8 select-window -t :8
bind-key 9 select-window -t :9
bind-key : command-prompt
bind-key \; last-pane
bind-key = choose-buffer
bind-key ? list-keys
bind-key D choose-client
bind-key L switch-client -l
bind-key [ copy-mode
bind-key ] paste-buffer
bind-key c new-window
bind-key d detach-client
bind-key f command-prompt "find-window '%%'"
bind-key i display-message
bind-key l last-window
bind-key n next-window
bind-key o select-pane -t :.+
bind-key p previous-window
bind-key q display-panes
bind-key r refresh-client
bind-key s choose-tree
bind-key t clock-mode
bind-key w choose-window
bind-key x confirm-before -p "kill-pane #P? (y/n)" kill-pane
bind-key z resize-pane -Z
bind-key { swap-pane -U
bind-key } swap-pane -D
bind-key '~' show-messages
bind-key PPage copy-mode -u
bind-key -r Up select-pane -U
bind-key -r Down select-pane -D
bind-key -r Left select-pane -L
bind-key -r Right select-pane -R
bind-key M-1 select-layout even-horizontal
bind-key M-2 select-layout even-vertical
bind-key M-3 select-layout main-horizontal
bind-key M-4 select-layout main-vertical
bind-key M-5 select-layout tiled
bind-key M-n next-window -a
bind-key M-o rotate-window -D
bind-key M-p previous-window -a
bind-key -r M-Up resize-pane -U 5
bind-key -r M-Down resize-pane -D 5
bind-key -r M-Left resize-pane -L 5
bind-key -r M-Right resize-pane -R 5
bind-key -r C-Up resize-pane -U
bind-key -r C-Down resize-pane -D
bind-key -r C-Left resize-pane -L
bind-key -r C-Right resize-pane -R
Run Code Online (Sandbox Code Playgroud)


小智 5

这是Richard Cook 的答案的调整版本,用于修复 tmux 2.1 上的转义问题

#!/bin/bash
tmux -f /dev/null -L temp start-server \; list-keys | \
    sed -r \
    -e "s/(bind-key.*\s+)([\"#~\$])(\s+)/\1\'\2\'\3/g" \
    -e "s/(bind-key.*\s+)([\'])(\s+)/\1\"\2\"\3/g" \
    -e "s/(bind-key.*\s+)([;])(\s+)/\1\\\\\2\3/g" \
    -e "s/(command-prompt -I )#([SW])/\1\"#\2\"/g" \
    -e "s/(if-shell -F -t = )#([^ ]+)/\1\"#\2\"/g" \
    > ~/.tmux.reset.conf                              
Run Code Online (Sandbox Code Playgroud)

将以下行添加到开头.tmux.conf

unbind-key -a
source-file ~/.tmux.reset.conf
Run Code Online (Sandbox Code Playgroud)