web-dev-qa-db-ja.com

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を押します)。それでも、「キーバインドC-t」が表示されます
  • PREFIX ?を押して、新しいキーバインドがまだリストにあることを確認します
  • tmuxを終了する
  • tmuxに入る
  • 元のキーバインドが再び機能するかどうかを確認します(PREFIX C-tを押します)。これで時計が再び表示されます。
  • PREFIX ?を押して、新しいキーバインドがリストから削除されたことを確認します

私の質問:tmuxにロードされたすべての構成を「忘れて」から.tmux.confをロードするように指示する方法はありますか?

35
Niels Bom

tmux(1)のマニュアルページによれば、unbind-key -aはあなたが探しているものです。

tmuxは、すべてのセッションが閉じられたときにのみ終了するサーバーを実行し、キーバインディングはサーバーごとであることに注意してください。したがって、バインディングを作成すると、すべてのクライアントデタッチで永続的になります。

つまり、unbind-key -a構成ファイルの最上部にあり、config reloadで必要な処理が行われます-すべてのバインドを解除して、最初からバインドを開始します。または-変更が小さい場合-変更したいものだけをバインド解除します。

21
peterph

ピーターによる正しい解決策

したがって、@ peterphはunbind-key -aである正しい答えを出し、次のことを行います:(man tmux)

-aが存在する場合、すべてのキー割り当てが削除されます。

実行可能な解決策

(私にとって)問題は、「すべて」は実際にはすべてを意味するということです。 tmuxに付属するキーバインドを含むunbind-key -aコマンドを実行すると、tmuxには即座にキーバインドがなくなるため、コマンドモードに入ることも、基本的に何もすることができなくなります。

これに対する私の(醜い)修正は次のとおりです。

  • すべてのキーバインドを削除し、tmuxがデフォルトで持っているすべてのキーバインドを再バインドする.tmux.reset.confを作成します
  • .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キーテーブルで機能する可能性があるように見えましたが、新しいキーテーブルを追加することはできません。

16
Niels Bom

現在、キーのバインディングをデフォルトにリセットする直接的な方法はありません。デフォルトのバインディング(key_bindings_init()内)の初期化はtmuxサーバーが最初に起動したときに(server_start()内で)一度行われ、単一をリセットするメカニズムはありませんキー。

構成ファイルをソースとして、以前に構成ファイルから削除されたカスタムバインディングによってオーバーライドされたデフォルトバインディングを再確立するという目的のシナリオでは、考案した方法は妥当です(残念ながら冗長です):unbind-key -a 、次にすべての「デフォルト」バインディングを再確立し、カスタムバインディングを確立します(一部は「デフォルト」バインディングをオーバーライドする場合があります)。

サーバーの現在のバインディングは、list-keysコマンドで抽出できます*;これは、提案された.tmux.reset.confファイルを生成/維持するのに役立ちますが、currentバインディングではなくdefaultバインディングを抽出する方法が必要です。

* list-keysの出力が現在直接使用できない状況がいくつかあります。セミコロンのバインディングは、セミコロンがtmuxコマンドセパレータとして解釈されないように、バックスラッシュでエスケープする必要があります。 single引用符内で二重引用符を使用する引数を持っていた(デフォルトのバインディングはこのようなものではありません)double qoutes内で二重引用符として出力されます。

デフォルトのバインディングを取得するには、list-keys出力をキャプチャできるように、最小限の構成(つまり、カスタムバインディングなし)の一時サーバーが必要です。実行できるtmuxサーバーの数に制限はありませんが、サーバーごとに異なるソケットパス名を使用する必要があります。 -Lおよび-Stmuxオプションを使用して、ソケット名($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

Notetmuxコマンドセパレータにしたいので、シェルがシェルコマンドセパレータとして扱わないようにするには、セミコロンをエスケープまたは引用符で囲む必要があります。

維持するセッションがないため、list-keysコマンドの実行が終了すると、サーバーは自動的に終了します。

したがって、このようなコマンドを使用して、.tmux.reset.confファイルを一時的に削除することを心配することなく(デフォルトのバインディングのみを表示するため)、既存のサーバーをシャットダウンすることなく、.tmux.confの大部分を生成できます。


run-Shellコマンドが同期的である場合、静的ファイル(source-file)を使用する代わりに、このような呼び出しを構成ファイル(次に、.tmux.reset.confで処理する一時ファイルにキャプチャする)に埋め込むことができます。これにより、現在のバージョンのtmuxのデフォルトのバインディングを常に使用できます(デフォルトのバインディングは時々変更されます)。悲しいかな、run-Shellコマンドの完了は現在、後続のコマンドに対して非同期です(run-Shellコマンドの後に来るコマンドは、通常、run-Shellによって生成されたプロセスが終了する前に実行されます)。

7
Chris Johnsen

デフォルトのキーバインディングから.tmux.reset.confを自動的に生成するbashスクリプトへの他のすべての回答のロールアップを次に示します。

#!/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
6
Richard Cook

私は尋ねました 上流 彼らはそれを修正することを望んでいないようです(誰かが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の回答 は依然としてエスケープ問題を引き起こしました。

4
timotheecour

他の回答も参考にしてください。状況の説明に優れています。私はここに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
Steven Lu

これは、tmux 2.1のエスケープ問題を修正するための微調整バージョン Richard Cookの回答 です。

#!/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
2
MilesF