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


33

我一直在尝试不同的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键盘绑定是否有效(按),它仍显示“ Keybinding Ct”
  • 按下PREFIX ?以查看新的绑定仍在列表中
  • 退出tmux
  • 输入tmux
  • 检查原始的键盘绑定是否再次起作用(按PREFIX C-t),现在应该再次显示时钟
  • 按下PREFIX ?以查看新的绑定已从列表中删除

我的问题:有没有一种方法可以指示tmux“忘记”所有已加载的配置,然后再加载.tmux.conf

Answers:


19

根据tmux(1)手册页,这unbind-key -a是您要寻找的。

请注意,tmux该服务器运行的服务器只有在所有会话都关闭且键绑定是每个服务器时才会退出。因此,一旦创建了绑定,它将在所有客户端分离中持久存在。

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


是的,我已经在我的问题中指出了这一点。但是,我希望tmux用“ clean slate”重新启动,然后重新加载配置文件,而不是手动“重置”所有可能绑定的键。
Niels Bom 2012年

@NielsBom检查更新的答案请
peterph

您是正确的,unbind-key -a删除了所有的键绑定。我会将您的答案标记为正确,但是为了其他观众的缘故,我还将添加为解决问题而应用的“ hack” unbind-key -a
Niels Bom 2012年

请参阅我的解决方案答案。
Niels Bom 2012年

16

正确的解决方案(作者:彼得

因此,@ 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关键表一起使用(据我所知),但是您不能添加新的关键表。


1
.tmux.reset.conf通过tmux list-keys在“干净”会话中运行,您可以快速生成与您相​​当的产品。
jw013

2
tmux -f /dev/null -L temp start-server \; list-keys将有效地生成默认值(尽管您需要在绑定的分号之前添加反斜杠)。
克里斯·约翰森

@ChrisJohnsen您能否在一个单独的答案中详细说明启动服务器?
Niels Bom

7

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

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

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

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

为了获得默认绑定,您需要一个配置最少的临时服务器(即没有自定义绑定),以便可以捕获其list-keys输出。您可以运行的tmux服务器的数量没有限制,但是每个服务器必须使用不同的套接字路径名。在-L-S TMUX选项可用于指定套接字名称($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 …

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

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

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

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

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


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


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

嵌入式sed命令行负责转义来自的输出的各个部分list-keys。这可能需要对系统的细节进行一些调整。

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

unbind-key -a
source-file ~/.tmux.reset.conf

4

另请参阅其他答案,因为它们可以很好地说明情况。我在这里有我的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

4

我向上游询问,他们似乎不愿意解决此问题(除非有人提交了PR)。

这是我的手动转义tmux list-keys,通过新的服务器实例获得

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

(由于以前的答案)

## See https://github.com/tmux/tmux/issues/729: How to reset key bindings to default? #729

bind-key    -T prefix C-b              send-prefix
bind-key    -T prefix C-o              rotate-window
bind-key    -T prefix C-z              suspend-client
bind-key    -T prefix Space            next-layout
bind-key    -T prefix !                break-pane
bind-key    -T prefix '"'                split-window
bind-key    -T prefix '#'                list-buffers
bind-key    -T prefix '$'                command-prompt -I '#'S "rename-session '%%'"
bind-key    -T prefix %                split-window -h
bind-key    -T prefix &                confirm-before -p "kill-window #W? (y/n)" kill-window
bind-key    -T prefix "'"                command-prompt -p index "select-window -t ':%%'"
bind-key    -T prefix (                switch-client -p
bind-key    -T prefix )                switch-client -n
bind-key    -T prefix ,                command-prompt -I '#W' "rename-window '%%'"
bind-key    -T prefix -                delete-buffer
bind-key    -T prefix .                command-prompt "move-window -t '%%'"
bind-key    -T prefix 0                select-window -t :=0
bind-key    -T prefix 1                select-window -t :=1
bind-key    -T prefix 2                select-window -t :=2
bind-key    -T prefix 3                select-window -t :=3
bind-key    -T prefix 4                select-window -t :=4
bind-key    -T prefix 5                select-window -t :=5
bind-key    -T prefix 6                select-window -t :=6
bind-key    -T prefix 7                select-window -t :=7
bind-key    -T prefix 8                select-window -t :=8
bind-key    -T prefix 9                select-window -t :=9
bind-key    -T prefix ':'                command-prompt
bind-key    -T prefix \;                last-pane
bind-key    -T prefix =                choose-buffer
bind-key    -T prefix ?                list-keys
bind-key    -T prefix D                choose-client
bind-key    -T prefix L                switch-client -l
bind-key    -T prefix M                select-pane -M
bind-key    -T prefix [                copy-mode
bind-key    -T prefix ]                paste-buffer
bind-key    -T prefix c                new-window
bind-key    -T prefix d                detach-client
bind-key    -T prefix f                command-prompt "find-window '%%'"
bind-key    -T prefix i                display-message
bind-key    -T prefix l                last-window
bind-key    -T prefix m                select-pane -m
bind-key    -T prefix n                next-window
bind-key    -T prefix o                select-pane -t :.+
bind-key    -T prefix p                previous-window
bind-key    -T prefix q                display-panes
bind-key    -T prefix r                refresh-client
bind-key    -T prefix s                choose-tree
bind-key    -T prefix t                clock-mode
bind-key    -T prefix w                choose-window
bind-key    -T prefix x                confirm-before -p "kill-pane #P? (y/n)" kill-pane
bind-key    -T prefix z                resize-pane -Z
bind-key    -T prefix {                swap-pane -U
bind-key    -T prefix }                swap-pane -D
bind-key    -T prefix '~'                show-messages
bind-key    -T prefix PPage            copy-mode -u
bind-key -r -T prefix Up               select-pane -U
bind-key -r -T prefix Down             select-pane -D
bind-key -r -T prefix Left             select-pane -L
bind-key -r -T prefix Right            select-pane -R
bind-key    -T prefix M-1              select-layout even-horizontal
bind-key    -T prefix M-2              select-layout even-vertical
bind-key    -T prefix M-3              select-layout main-horizontal
bind-key    -T prefix M-4              select-layout main-vertical
bind-key    -T prefix M-5              select-layout tiled
bind-key    -T prefix M-n              next-window -a
bind-key    -T prefix M-o              rotate-window -D
bind-key    -T prefix M-p              previous-window -a
bind-key -r -T prefix M-Up             resize-pane -U 5
bind-key -r -T prefix M-Down           resize-pane -D 5
bind-key -r -T prefix M-Left           resize-pane -L 5
bind-key -r -T prefix M-Right          resize-pane -R 5
bind-key -r -T prefix C-Up             resize-pane -U
bind-key -r -T prefix C-Down           resize-pane -D
bind-key -r -T prefix C-Left           resize-pane -L
bind-key -r -T prefix C-Right          resize-pane -R
bind-key    -T root   MouseDown1Pane   select-pane -t = \; send-keys -M
bind-key    -T root   MouseDown1Status select-window -t =
bind-key    -T root   MouseDown3Pane   if-shell -F -t = '#{mouse_any_flag}' "select-pane -t=; send-keys -M" "select-pane -mt="
# Someone also was wondering how to fix here: http://tmux-users.narkive.com/dTFVvLMh/is-it-possible-to-have-a-binding-that-brings-back-mouse-behavior
bind-key    -T root   MouseDrag1Pane   if-shell -F -t = '#{mouse_any_flag}' "if -Ft= '#{pane_in_mode}' 'copy-mode -M' 'send-keys -M' " "copy-mode -M"

bind-key    -T root   MouseDrag1Border resize-pane -M
bind-key    -T root   WheelUpPane      if-shell -F -t = '#{mouse_any_flag}' "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -et=' "
bind-key    -T root   WheelUpStatus    previous-window
bind-key    -T root   WheelDownStatus  next-window

上面是在github上,因此您可以执行以下操作:

curl -L https://raw.githubusercontent.com/timotheecour/dinocode/master/tmux_list_keys_escaped.txt > ~/.tmux.reset.conf
unbind-key -a
source-file ~/.tmux.reset.conf

注意:以某种方式,Richard Cook的回答仍然产生了转义问题。


欢迎使用unix.SE!我们经常对普通链接保持警惕,因此我直接将其粘贴在此处(但保留该链接以供参考)。这是这里的首选方法。链接会死掉(我知道,它是github!但是仍然可能在某个时候死掉)。无论如何,这是一个不错的答案(+1)。如果您设法用Richard的sed代码解决了这个问题,可能会更好。那是一岁,tmux有个不习惯100%向后兼容的坏习惯。
grochmal

2

这是理查德·库克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                              

将以下行添加到 .tmux.conf

unbind-key -a
source-file ~/.tmux.reset.conf
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.