Recarregamento da configuração do tmux que não desvincula as chaves (a chave de ligação é cumulativa)

33

Eu tenho experimentado diferentes configurações de ligação de teclas do tmux e notei o seguinte:

Se eu recarregar minha configuração do tmux (de dentro do tmux), as combinações de teclas que eu carreguei permanecerão carregadas. A única maneira (eu sei) de limpar isso é sair de todas as sessões do tmux e reiniciar. Portanto, parece que o tmux se lembra de todas as combinações de teclas carregadas anteriormente e as remove apenas em um novo começo ou desabotoando-as explicitamente.

Para recriar isso:

  • abrir um terminal (A)
  • iniciar tmux
  • verifique se a combinação de teclas mostra um relógio (pressione PREFIX C-t)
  • pressione PREFIX ?para ver a combinação de teclas na lista
  • editar ~/.tmux.conf
  • adicione uma combinação de teclas ( bind C-t display "Keybinding C-t")
  • recarregar a configuração do tmux ( PREFIX : source-file ~/.tmux.conf)
  • verifique se a combinação de teclas funciona (pressione PREFIX C-t)
  • pressione PREFIX ?para ver a nova combinação de teclas na lista
  • edite ~/.tmux.confnovamente
  • remova a combinação de teclas (remova bind C-t display "Keybinding C-t")
  • recarregar a configuração do tmux ( PREFIX : source-file ~/.tmux.conf)
  • verificar se a combinação de teclas funciona (pressione PREFIX C-t), ainda exibe "Keybinding Ct"
  • pressione PREFIX ?para ver que a nova combinação de teclas ainda está na lista
  • exit tmux
  • digite tmux
  • verificar se a combinação de teclas original funciona novamente (pressione PREFIX C-t), agora deve exibir um relógio novamente
  • pressione PREFIX ?para ver se a nova combinação de teclas foi removida da lista

Minha pergunta: existe uma maneira de instruir o tmux para "esquecer" todas as configurações carregadas e depois carregar .tmux.conf?

Niels Bom
fonte

Respostas:

19

De acordo com a tmux(1)página de manual, unbind-key -aé o que você está procurando.

Observe que tmuxexecuta um servidor que será encerrado apenas quando todas as sessões estiverem fechadas e as ligações de teclas por servidor. Portanto, depois de criar uma ligação, ela será persistente em todos os desanexos do cliente.

Dito isto, coloque unbind-key -ano topo do seu arquivo de configuração e, no recarregamento da configuração, faça o que você deseja - desvincule tudo e comece a vincular do zero. Ou - se suas modificações forem menores - desative apenas o que você deseja alterar.

peterph
fonte
Sim e já afirmei isso na minha pergunta. Mas, em vez de "redefinir" todas as chaves possivelmente vinculadas manualmente, eu gostaria que o tmux fosse reiniciado com uma "lista limpa" e recarregado o arquivo de configuração.
Niels Bom
@NielsBom verificar resposta atualizada por favor
peterph
Você está correto, unbind-key -aremove todos os atalhos de teclado. Marcarei sua resposta como correta, mas, para o bem de outros espectadores, também adicionarei o "hack" que apliquei para corrigir um problema unbind-key -a.
Niels Bom
Veja minha resposta para minha solução.
Niels Bom
16

A solução correta (de Peter

Então, @peterph deu a resposta correta, que é unbind-key -aa seguinte: (man tmux)

Se -a estiver presente, todas as ligações de teclas serão removidas.

Uma solução viável

O problema (para mim) é que "tudo" na verdade significa tudo. Incluindo os atalhos de teclado, o tmux vem com . Se você executar o unbind-key -acomando tmux instantaneamente, não terá mais nenhuma combinação de teclas, portanto você não poderá nem entrar no modo de comando ou fazer qualquer coisa basicamente.

Minha (bastante feia) correção para isso é a seguinte:

  • crie um .tmux.reset.confque remova todas as combinações de teclas e depois religue todas as que o tmux possui por padrão
  • fonte que redefinir na parte superior do seu .tmux.conf

Meu .tmux.conf:

# always load the reset file first
source-file ~/.tmux.reset.conf

Meu .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

Parecia que isso poderia ter funcionado com as tabelas-chave do tmux (até onde eu sei), mas você não pode adicionar novas tabelas-chave.

Niels Bom
fonte
1
É provável que você possa gerar rapidamente o equivalente ao seu .tmux.reset.confexecutando tmux list-keysem uma sessão "limpa".
Jw013
2
tmux -f /dev/null -L temp start-server \; list-keysefetivamente gerará os padrões (embora você precise adicionar uma barra invertida antes do ponto e vírgula em sua ligação).
31412 Chris Chrissen
@ ChrisJohnsen Você poderia elaborar no servidor de inicialização em uma resposta separada?
Niels Bom
7

Atualmente, não há uma maneira direta de redefinir a ligação de uma chave ao padrão; a inicialização das ligações padrão (in key_bindings_init()) é feita uma vez quando o servidor tmux é iniciado pela primeira vez (in server_start()) e não há mecanismo para redefinir uma única chave.

Para o seu cenário desejado onde deseja que o ato de terceirização de seu arquivo de configuração para restabelecer uma ligação que anteriormente foi substituído por uma ligação que já foi excluído do seu arquivo de configuração personalizado padrão, o método que desenvolveram é razoável (embora infelizmente detalhado): unbind-key -a, restabeleça todas as ligações "padrão" e estabeleça suas ligações personalizadas (algumas das quais podem substituir uma ligação "padrão").

As ligações atuais de um servidor podem ser extraídas com o list-keyscomando * ; isso pode ajudar a gerar / manter o .tmux.reset.confarquivo proposto , mas você precisa de uma maneira de extrair as ligações padrão , não as ligações atuais .

* Existem algumas situações em que a saída de list-keysnão é diretamente utilizável no momento: a ligação para ponto-e-vírgula precisa que seu ponto-e-vírgula escape com uma barra invertida para impedir que seja interpretado como um separador de comandos do tmux e quaisquer ligações que tivessem argumentos que usassem aspas duplas dentro de um único aspas (nenhuma das ligações padrão é assim) sairá como aspas duplas dentro de qoutes duplos .

Para obter as ligações padrão, você precisa de um servidor temporário com uma configuração mínima (ou seja, sem ligações personalizadas) para poder capturar sua list-keyssaída. Não há limite para o número de servidores tmux que você pode executar, mas cada um deve usar um nome de caminho de soquete diferente; as opções -Le -S tmux podem ser usadas para especificar um nome de soquete (no $TMPDIR/tmux-$UIDnome do caminho ou no soquete completo. Portanto, para conversar (ou iniciar) um novo servidor em um soquete chamado temp, você usaria o seguinte:

tmux -L temp …

Para garantir que ele não use o seu .tmux.conf, use -f-o para ler /dev/null(um arquivo especial que está sempre vazio):

tmux -f /dev/null -L temp …

Nota : isso não impede o processamento de /etc/tmux.conf, se esse arquivo existir; o caminho para esse "arquivo de configuração do sistema" é codificado e não há opção para ignorá-lo (com exceção do patch do código).

Normalmente, você precisa de um new-sessioncomando para realmente iniciar o servidor, mas não queremos nenhuma sessão, apenas um servidor inicializado para consulta. O start-servercomando faz exatamente isso: inicia um servidor sem criar nenhuma sessão.

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

Agora, precisamos apenas adicionar nosso comando "query" ( list-keysneste caso):

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

Nota : o ponto-e-vírgula precisa ser escapado ou citado para impedir que o shell o trate como um separador de comandos do shell, pois queremos que ele seja um separador de comandos do tmux .

Como não há sessões a serem mantidas, o servidor será encerrado automaticamente após concluir a execução do list-keyscomando.

Portanto, você pode usar um comando como este para gerar a maior parte do arquivo .tmux.reset.confsem precisar se preocupar em remover temporariamente o .tmux.confarquivo (para ver apenas as ligações padrão) e sem precisar desligar os servidores existentes.


Se o run-shellcomando fosse síncrono, você poderia incorporar uma chamada como essa em seu arquivo de configuração (capturando em um arquivo temporário com o qual você processaria source-file) em vez de ter um arquivo estático (seu .tmux.reset.conf). Isso permitiria que você sempre use as ligações padrão da sua versão atual do tmux (as ligações padrão mudam ocasionalmente). Infelizmente, run-shellatualmente a conclusão do comando é assíncrona em relação aos comandos subseqüentes (os comandos que vêm depois de um run-shellcomando geralmente são executados antes que o processo gerado run-shelltenha a chance de terminar).

Chris Johnsen
fonte
6

Aqui está um rollup de todas as outras respostas em um script bash que será gerado automaticamente a .tmux.reset.confpartir das ligações de teclas padrão:

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

A sedlinha de comando incorporada cuida de escapar de várias partes da saída list-keys. Isso pode precisar de alguns ajustes para as especificidades do seu sistema.

No seu .tmux.confarquivo, basta desvincular todas as chaves e originar esse arquivo antes de definir suas próprias associações de teclas:

unbind-key -a
source-file ~/.tmux.reset.conf
Richard Cook
fonte
4

Consulte também as outras respostas aqui, pois elas explicam bem a situação. Eu tenho aqui o meu tmux 1.8 compatível com o tmux.reset.conf, que eu tive que fazer várias modificações depois de copiar a tmux -f /dev/null -L temp start-server \; list-keyssaída. Em particular, várias coisas tiveram que ser citadas.

# 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
Steven Lu
fonte
4

Eu perguntei a montante que eles parecem dispostos a corrigi-lo (a menos que alguém envie um PR).

Aqui está o meu escape manual tmux list-keys, obtido através de uma nova instância do servidor com

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

(graças a respostas anteriores)

## 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

A descrição acima está no github para que você possa fazer:

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

NOTA: De alguma forma, a resposta de Richard Cook ainda produzia problemas de escape.

timotheecour
fonte
Bem-vindo ao unix.SE! Muitas vezes somos cautelosos com links simples, então colei diretamente aqui (mas mantive o link para referência). Essa é a maneira preferida por aqui. Links morrem (eu sei, é github! Mas ainda pode morrer em algum momento). De qualquer forma, é uma boa resposta (+1). Talvez pudesse ser melhor se você conseguisse corrigir o problema com o código sed de Richard. Ele tem um ano e o tmux tem o mau hábito de não ser 100% compatível com versões anteriores.
grochmal
2

Aqui está uma versão aprimorada da resposta de Richard Cook para corrigir problemas de escape no 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                              

Adicione as seguintes linhas ao início de .tmux.conf

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