重新加载 tmux 配置而不解除绑定密钥(绑定密钥是累积的)

重新加载 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

答案1

根据tmux(1)手册页,unbind-key -a这就是您正在寻找的内容。

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

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

答案2

正确的解决方案(作者:Peter

所以@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

我的.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

看起来这可以与 tmux 键表一起使用(据我所知),但你不能添加新的键表。

答案3

目前没有直接的方法可以将键的绑定重置为其默认值;默认绑定(in)的初始化key_bindings_init()在以下情况下完成一次:多路复用器服务器首先启动(在server_start()),并且没有重置单个密钥的机制。

对于您想要的场景,您希望获取配置文件的行为来重新建立先前被已从配置文件中删除的自定义绑定覆盖的默认绑定,您设计的方法是合理的(尽管不幸的是冗长)unbind-key -a:然后重新建立所有“默认”绑定,然后建立自定义绑定(其中一些可能会覆盖“默认”绑定)。

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

* 在某些情况下,list-keys当前无法直接使用:分号的绑定需要使用反斜杠转义分号,以防止其被解释为多路复用器命令分隔符,以及任何具有内部使用双引号的参数的绑定单身的引号(没有一个默认绑定是这样的)将在内部以双引号形式出现双倍的引用。

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

tmux -L temp …

为了确保它不使用您的.tmux.conf,您可以-f告诉它读取/dev/null(一个始终为空的特殊文件):

tmux -f /dev/null -L temp …

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

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

tmux -f /dev/null -L temp start-server …

现在,我们只需要附加“查询”命令(list-keys在本例中):

tmux -f /dev/null -L temp start-server \; list-keys

笔记:分号需要转义或加引号,以防止 shell 将其视为 shell 命令分隔符,因为我们希望它成为多路复用器命令分隔符。

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

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


如果run-shell命令是同步的,您可以在配置文件中嵌入这样的调用(捕获到随后将使用的临时文件source-file),而不是使用静态文件(您的.tmux.reset.conf)。这将使您始终使用当前版本的默认绑定多路复用器(默认绑定偶尔会改变)。遗憾的是,该命令的完成run-shell目前相对于后续命令是异步的(命令之后的命令run-shell通常会在其生成的进程run-shell有机会完成之前运行)。

答案4

另请参阅此处的其他答案,因为他们很好地解释了情况。我这里有我的多路复用器 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

相关内容