Rechargement des clés non-déliantes de la configuration de tmux (bind-key est cumulative)

33

J'ai expérimenté différents paramètres de liaison de clés tmux et j'ai remarqué ce qui suit:

Si je recharge ma configuration tmux (à partir de tmux), les liaisons de touches que j'avais chargées une fois resteront chargées. Le seul moyen (à ma connaissance) de nettoyer cela est de quitter toutes les sessions tmux et de redémarrer. Il semble donc que tmux se souvienne de toutes les liaisons de clé précédemment chargées et ne les supprimera que lors d’un nouveau départ ou en les annulant explicitement.

Pour recréer ceci:

  • ouvrir un terminal (A)
  • démarrer tmux
  • vérifier si le raccourci clavier affiche une horloge (appuyez sur PREFIX C-t)
  • appuyez sur PREFIX ?pour voir le raccourci clavier dans la liste
  • modifier ~/.tmux.conf
  • ajouter un raccourci clavier ( bind C-t display "Keybinding C-t")
  • recharger tmux config ( PREFIX : source-file ~/.tmux.conf)
  • vérifier si le raccourci clavier fonctionne (presse PREFIX C-t)
  • appuyez sur PREFIX ?pour voir le nouveau raccourci clavier dans la liste
  • éditer à ~/.tmux.confnouveau
  • enlever le raccourci clavier (donc enlever bind C-t display "Keybinding C-t")
  • recharger tmux config ( PREFIX : source-file ~/.tmux.conf)
  • vérifier si le raccourci clavier fonctionne (appuyer PREFIX C-t), il affiche toujours "Keybinding Ct"
  • appuyez sur PREFIX ?pour voir que le nouveau raccourci clavier est toujours dans la liste
  • quitter tmux
  • entrez tmux
  • vérifier si le raccourci clavier fonctionne à nouveau (appuyer PREFIX C-t), il devrait maintenant afficher à nouveau une horloge
  • appuyez sur PREFIX ?pour voir que le nouveau raccourci clavier a été retiré de la liste

Ma question: y a-t-il un moyen de demander à tmux de "oublier" toutes les configurations chargées puis de les charger .tmux.conf?

Niels Bom
la source

Réponses:

19

Selon la tmux(1)page de manuel, unbind-key -ac’est ce que vous recherchez.

Notez que vous tmuxexécutez un serveur qui ne se ferme que lorsque toutes les sessions sont fermées et que les liaisons de clé sont effectuées par serveur. Par conséquent, une fois que vous créez une liaison, elle sera persistante sur tous les détachements de clients.

Cela dit, mettez unbind-key -atout en haut de votre fichier de configuration, et lors du rechargement de la configuration, il devrait faire ce que vous voulez - dissocier tout et commencer à se lier à partir de zéro. Ou, si vos modifications sont plus petites, dissociez uniquement ce que vous souhaitez modifier.

Peterph
la source
Oui et je l'ai déjà dit dans ma question. Mais au lieu de "réinitialiser" manuellement toutes les clés éventuellement liées, j'aimerais que tmux redémarre avec une "table rase", puis recharge le fichier de configuration.
Niels Bom
@ NielsBom vérifier la réponse mise à jour s'il vous plaît
peterph
Vous avez raison, le unbind-key -asupprime tous les raccourcis clavier. Je marquerai votre réponse comme correcte, mais, dans l’intérêt des autres téléspectateurs, j’ajouterai également le "hack" que j’ai appliqué pour résoudre un problème unbind-key -a.
Niels Bom
Voir ma réponse pour ma solution.
Niels Bom
16

La bonne solution (par Peter

Alors, @peterph a donné la bonne réponse, unbind-key -aà savoir: (man tmux)

Si -a est présent, toutes les liaisons de clé sont supprimées.

Une solution réalisable

Le problème (pour moi) est que "tout" signifie en réalité tout. Y compris les raccourcis clavier fournis avec tmux . Si vous exécutez la unbind-key -acommande, tmux ne dispose plus d'aucune liaison de clé instantanément, vous ne pouvez donc même pas entrer en mode commande ou faire quoi que ce soit.

Ma solution (plutôt moche) pour ceci est la suivante:

  • créer un .tmux.reset.confqui supprime tous les raccourcis clavier, puis rebinds tous ceux que tmux a par défaut
  • source qui réinitialise au sommet de votre .tmux.conf

Mon .tmux.conf:

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

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

On aurait dit que cela aurait pu fonctionner avec les tables de clés tmux (pour autant que je sache), mais vous ne pouvez pas ajouter de nouvelles tables de clés.

Niels Bom
la source
1
Il est probable que vous puissiez générer rapidement l'équivalent de votre .tmux.reset.confen exécutant tmux list-keysune session "propre".
jw013
2
tmux -f /dev/null -L temp start-server \; list-keysgénérera effectivement les valeurs par défaut (bien que vous deviez ajouter une barre oblique inverse avant le point-virgule dans sa liaison).
Chris Johnsen
@ ChrisJohnsen Pourriez-vous svp élaborer sur le serveur de démarrage dans une réponse distincte?
Niels Bom
7

Il n'existe actuellement aucun moyen direct de réinitialiser la liaison d'une clé à sa valeur par défaut. l'initialisation des liaisons par défaut (in key_bindings_init()) est effectuée une fois lorsque le serveur tmux démarre (in server_start()), et il n'existe aucun mécanisme permettant de réinitialiser une clé unique.

Pour le scénario souhaité dans lequel vous voulez que l'acte de sourcing de votre fichier de configuration rétablisse une liaison par défaut précédemment remplacée par une liaison personnalisée qui a depuis été supprimée de votre fichier de configuration, la méthode que vous avez conçue est raisonnable (bien que malheureusement prolixe): unbind-key -a , puis rétablissez toutes les liaisons «par défaut», puis établissez vos liaisons personnalisées (dont certaines peuvent remplacer une liaison «par défaut»).

Les liaisons actuelles d'un serveur peuvent être extraites avec la list-keyscommande * ; cela peut aider à générer / maintenir votre .tmux.reset.conffichier proposé , mais vous avez besoin d’un moyen d’extraire les liaisons par défaut , pas les liaisons actuelles .

* Il y a des situations où la sortie list-keysest pas directement utilisable: la liaison pour virgule a besoin de son point - virgule échappé avec une barre oblique inverse pour l' empêcher d'être interprété comme un tmux séparateur de commande, et toutes les liaisons qui ont des arguments qui ont utilisé des guillemets doubles à l' intérieur unique les guillemets (aucune des liaisons par défaut ne sont comme celle-ci) apparaîtront sous forme de guillemets doubles à l'intérieur doubles à l' doubles qoutes.

Pour obtenir les liaisons par défaut, vous avez besoin d'un serveur temporaire avec une configuration minimale (c'est-à-dire sans liaisons personnalisées) afin de pouvoir capturer sa list-keyssortie. Il n’existe aucune limite quant au nombre de serveurs tmux que vous pouvez exécuter, mais chacun doit utiliser un chemin de socket différent; les -Let -S tmux options peuvent être utilisées pour spécifier un nom de socket (en $TMPDIR/tmux-$UIDcheminServeur socket complet Donc, pour parler (ou commencer) un nouveau serveur sur un socket nommé. temp, vous pouvez utiliser ceci:

tmux -L temp …

Pour vous assurer qu'il n'utilise pas votre .tmux.conf, vous utilisez -fpour lui dire de lire /dev/null(un fichier spécial toujours vide):

tmux -f /dev/null -L temp …

Remarque : cela n’empêche pas le traitement des/etc/tmux.conf , si un tel fichier existe; le chemin d'accès à ce «fichier de configuration système» est codé en dur et il n'y a pas d'option pour le contourner (à moins de corriger le code).

Normalement, vous avez besoin d'une new-sessioncommande pour démarrer le serveur, mais nous ne voulons pas de sessions, mais simplement d'un serveur initialisé à interroger. La start-servercommande ne fait que cela: démarre un serveur sans créer de session.

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

Maintenant, il suffit d’ajouter notre commande «query» ( list-keysdans ce cas):

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

Remarque : le point-virgule doit être échappé ou cité pour empêcher le shell de le traiter comme un séparateur de commandes shell, car nous souhaitons que ce soit un séparateur de commandes tmux .

Comme il n'y a pas de session à gérer, le serveur se ferme automatiquement une fois l'exécution de la list-keyscommande terminée .

Vous pouvez donc utiliser une commande comme celle-ci pour générer l'essentiel de votre travail .tmux.reset.confsans avoir à vous soucier de la suppression temporaire de votre .tmux.conffichier (pour vous permettre de voir uniquement les liaisons par défaut) et sans avoir à arrêter aucun serveur existant.


Si la run-shellcommande était synchrone, vous pouvez intégrer un appel comme celui-ci dans votre fichier de configuration (capture dans un fichier temporaire que vous traiteriez ensuite source-file) au lieu d'avoir un fichier statique (votre .tmux.reset.conf). Cela vous permettrait de toujours utiliser les liaisons par défaut de votre version actuelle de tmux (les liaisons par défaut changent de temps en temps). Hélas, l'achèvement de la run-shellcommande est actuellement asynchrone par rapport aux commandes suivantes (les commandes après l' run-shellexécution d' une commande sont généralement exécutées avant que le processus généré par run-shellait eu la chance de se terminer).

Chris Johnsen
la source
6

Voici un résumé de toutes les autres réponses dans un script bash généré automatiquement à .tmux.reset.confpartir des raccourcis clavier par défaut:

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

La sedligne de commande intégrée permet d’échapper aux différentes parties de la sortie list-keys. Cela peut nécessiter quelques ajustements pour les spécificités de votre système.

Dans votre .tmux.conffichier, dissociez simplement toutes les clés et sourcez ce fichier avant de définir vos propres combinaisons de touches:

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

Veuillez également vous référer aux autres réponses ici, car elles expliquent bien la situation. J'ai ici mon tmux.reset.conf compatible 1.8, que j'ai dû faire plusieurs modifications après avoir copié la tmux -f /dev/null -L temp start-server \; list-keyssortie. En particulier, plusieurs choses devaient être citées.

# 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
la source
4

J'ai demandé en amont qu'ils ne semblaient pas disposés à le réparer (à moins que quelqu'un ne présente un PR).

Voici mon échappé manuellement tmux list-keys, obtenu via une nouvelle instance de serveur avec

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

(merci aux réponses précédentes)

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

Ce qui précède est sur github pour que vous puissiez faire:

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

NOTE: D'une manière ou d'une autre, la réponse de Richard Cook produisait toujours des problèmes évidents.

timotheecour
la source
Bienvenue sur unix.SE! Nous nous méfions souvent des liens simples, je les ai donc collés directement ici (mais j'ai gardé le lien pour référence). C'est le moyen préféré ici. Les liens meurent (je sais, c’est github! Mais il se peut qu’il meure à un moment donné). Quoi qu'il en soit, c'est une bonne réponse (+1). Cela pourrait peut-être être mieux si vous parveniez à résoudre le problème avec le code sed de Richard. Cela fait un an et tmux a la mauvaise habitude de ne pas être compatible à 100% avec le passé.
Grochmal
2

Voici une version peaufinée de la réponse de Richard Cook pour résoudre les problèmes qui échappent sous 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                              

Ajouter les lignes suivantes au début de .tmux.conf

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