La recarga de la configuración de tmux no desvincula las claves (la clave de vinculación es acumulativa)

33

He estado experimentando con diferentes configuraciones de combinación de teclas tmux y he notado lo siguiente:

Si vuelvo a cargar mi configuración de tmux (desde tmux), las combinaciones de teclas que cargué una vez permanecerán cargadas. La única manera (que sé) de limpiar esto es cerrar todas las sesiones de tmux y reiniciar. Por lo tanto, parece que tmux recuerda todas las asociaciones de teclas cargadas previamente y solo las eliminará en un nuevo comienzo o desvinculándolas explícitamente.

Para recrear esto:

  • abrir una terminal (A)
  • iniciar tmux
  • compruebe si la combinación de teclas muestra un reloj (presione PREFIX C-t)
  • presione PREFIX ?para ver la combinación de teclas en la lista
  • editar ~/.tmux.conf
  • agregar una combinación de teclas ( bind C-t display "Keybinding C-t")
  • recargar tmux config ( PREFIX : source-file ~/.tmux.conf)
  • compruebe si la combinación de teclas funciona (presione PREFIX C-t)
  • presione PREFIX ?para ver la nueva combinación de teclas en la lista
  • editar de ~/.tmux.confnuevo
  • eliminar la combinación de teclas (eliminar bind C-t display "Keybinding C-t")
  • recargar tmux config ( PREFIX : source-file ~/.tmux.conf)
  • compruebe si la combinación de teclas funciona (presione PREFIX C-t), todavía muestra "Keybinding Ct"
  • presione PREFIX ?para ver que la nueva combinación de teclas todavía está en la lista
  • salir de tmux
  • ingrese tmux
  • compruebe si la combinación de teclas original funciona de nuevo (presione PREFIX C-t), ahora debería mostrar un reloj nuevamente
  • presione PREFIX ?para ver que la nueva combinación de teclas se ha eliminado de la lista

Mi pregunta: ¿hay alguna manera de indicarle a tmux que "olvide" todas las configuraciones cargadas y luego las cargue .tmux.conf?

Niels Bom
fuente

Respuestas:

19

Según la tmux(1)página del manual, unbind-key -aes lo que estás buscando.

Tenga en cuenta que tmuxejecuta un servidor que solo saldrá una vez que se cierren todas las sesiones, y las asociaciones de teclas son por servidor. Por lo tanto, una vez que cree un enlace, será persistente en todas las separaciones de clientes.

Dicho esto, colóquelo unbind-key -aen la parte superior de su archivo de configuración y, cuando vuelva a cargar la configuración, debe hacer lo que desee: desenlazar todo y comenzar a enlazar desde cero. O, si sus modificaciones son más pequeñas, desvincula solo lo que desea cambiar.

Peterph
fuente
Sí, y ya lo dije en mi pregunta. Pero en lugar de "restablecer" todas las claves posiblemente vinculadas manualmente, me gustaría que tmux se reinicie con una "pizarra limpia" y luego vuelva a cargar el archivo de configuración.
Niels Bom
@NielsBom verifique la respuesta actualizada por favor
peterph
Tienes razón, unbind-key -aelimina todas las combinaciones de teclas. Marcaré su respuesta como correcta, pero por el bien de otros espectadores también agregaré el "hack" que he aplicado para solucionar un problema unbind-key -a.
Niels Bom
Vea mi respuesta para mi solución.
Niels Bom
16

La solución correcta (por Peter

Entonces @peterph dio la respuesta correcta, que es lo unbind-key -aque hace lo siguiente: (man tmux)

Si -a está presente, se eliminan todas las asociaciones de teclas.

Una solución viable

El problema (para mí) es que "todos" en realidad significa todo. Incluyendo las combinaciones de teclas con las que viene tmux . Si ejecuta el unbind-key -acomando tmux instantáneamente ya no tiene ninguna combinación de teclas, por lo que ni siquiera puede ingresar al modo de comando o hacer algo básicamente.

Mi solución (bastante fea) para esto es la siguiente:

  • crea un .tmux.reset.confque elimina todas las combinaciones de teclas y luego vuelve a unir todas las que tmux tiene por defecto
  • fuente que se restablece en la parte superior de su .tmux.conf

Mi .tmux.conf:

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

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

Parecía que esto podría haber funcionado con las tablas de claves tmux (por lo que puedo decir), pero no se pueden agregar nuevas tablas de claves.

Niels Bom
fuente
1
Es probable que pueda generar rápidamente el equivalente a su .tmux.reset.confejecutando tmux list-keysen una sesión "limpia".
jw013
2
tmux -f /dev/null -L temp start-server \; list-keysgenerará efectivamente los valores predeterminados (aunque debe agregar una barra diagonal inversa antes del punto y coma en su enlace).
Chris Johnsen
@ChrisJohnsen ¿Podría dar más detalles sobre el servidor de inicio en una respuesta separada?
Niels Bom
7

Actualmente no existe una forma directa de restablecer el enlace de una clave a su valor predeterminado; la inicialización de los enlaces predeterminados (in key_bindings_init()) se realiza una vez cuando el servidor tmux se inicia por primera vez (in server_start()), y no existe un mecanismo para restablecer una sola clave.

Para su escenario deseado en el que desea el acto de la compra de componentes del archivo de configuración para restablecer una unión que fue anulada previamente por un enlace que desde entonces ha sido borrado de su archivo de configuración personalizado predeterminado, el método que ideó es razonable (aunque por desgracia detallado): unbind-key -a, luego restablezca todos los enlaces "predeterminados", luego establezca sus enlaces personalizados (algunos de los cuales podrían anular un enlace "predeterminado").

Los enlaces actuales de un servidor se pueden extraer con el list-keyscomando * ; esto puede ayudar a generar / mantener su .tmux.reset.confarchivo propuesto , pero necesita una forma de extraer los enlaces predeterminados , no los enlaces actuales .

* Hay algunas situaciones en las que la salida de list-keysactualmente no se puede usar directamente: el enlace para punto y coma necesita que su punto y coma se escape con una barra diagonal inversa para evitar que se interprete como un separador de comando tmux , y cualquier enlace que tenga argumentos que usen comillas dobles dentro de comillas simples las comillas (ninguno de los enlaces predeterminados son así) aparecerán como comillas dobles dentro de dobles qoutes.

Para obtener los enlaces predeterminados, necesita un servidor temporal con una configuración mínima (es decir, sin enlaces personalizados) para poder capturar su list-keyssalida. No hay límite para la cantidad de servidores tmux que puede ejecutar, pero cada uno debe usar un nombre de ruta de socket diferente; las opciones -Ly -S tmux se pueden usar para especificar un nombre de socket (en $TMPDIR/tmux-$UIDo nombre de ruta de socket completo. Por lo tanto, para hablar (o iniciar) un nuevo servidor en un socket llamado temp, usaría esto:

tmux -L temp …

Para asegurarte de que no usa tu .tmux.conf, usas -fpara decirle que lea /dev/null(un archivo especial que siempre está vacío):

tmux -f /dev/null -L temp …

Nota : esto no impide el procesamiento de /etc/tmux.conf, si existe dicho archivo; la ruta a este "archivo de configuración del sistema" está codificada y no hay opción para omitirla (salvo parchear el código).

Normalmente, necesita un new-sessioncomando para iniciar realmente el servidor, pero no queremos ninguna sesión, solo un servidor inicializado para consultar. El start-servercomando hace exactamente eso: inicia un servidor sin crear ninguna sesión.

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

Ahora, solo necesitamos agregar nuestro comando "query" ( list-keysen este caso):

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

Nota : el punto y coma debe ser escapado o citado para evitar que el shell lo trate como un separador de comandos de shell, ya que queremos que sea un separador de comandos tmux .

Como no hay sesiones que mantener, el servidor se cerrará automáticamente cuando termine de ejecutar el list-keyscomando.

Por lo tanto, puede usar un comando como este para generar la mayor parte de su contenido .tmux.reset.confsin tener que preocuparse por eliminar temporalmente su .tmux.confarchivo (para permitirle ver solo los enlaces predeterminados) y sin tener que cerrar ningún servidor existente.


Si el run-shellcomando fuera síncrono, podría incrustar una llamada como esta en su archivo de configuración (capturar en un archivo temporal con el que luego procesaría source-file) en lugar de tener un archivo estático (su .tmux.reset.conf). Eso le permitiría usar siempre los enlaces predeterminados de su versión actual de tmux (los enlaces predeterminados cambian ocasionalmente). Por desgracia, la finalización del run-shellcomando es actualmente asíncrona con respecto a los comandos posteriores (los comandos que vienen después de un run-shellcomando generalmente se ejecutarán antes de que el proceso generado run-shellhaya tenido la oportunidad de finalizar).

Chris Johnsen
fuente
6

Aquí hay un resumen de todas las otras respuestas en un script bash que se generará automáticamente a .tmux.reset.confpartir de las asociaciones de teclas predeterminadas:

#!/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 sedlínea de comando incorporada se encarga de escapar de varias partes de la salida list-keys. Esto puede necesitar algunos ajustes para los detalles de su sistema.

En su .tmux.confarchivo, simplemente desvincule todas las claves y obtenga este archivo antes de definir sus propias asociaciones de teclas:

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

Consulte también las otras respuestas aquí, ya que hacen un buen trabajo al explicar la situación. Tengo aquí mi tmux 1.8 compatible tmux.reset.conf, que tuve que hacer varias modificaciones después de copiar la tmux -f /dev/null -L temp start-server \; list-keyssalida. En particular, varias cosas tuvieron 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
fuente
4

Le pregunté río arriba que parecen no estar dispuestos a arreglarlo (a menos que alguien envíe un RP).

Aquí está mi escape manual tmux list-keys, obtenido a través de una nueva instancia de servidor con

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

(gracias a respuestas 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

Lo anterior está en github para que pueda hacer:

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 alguna manera, la respuesta de Richard Cook todavía produjo problemas de escape.

timotheecour
fuente
Bienvenido a unix.SE! A menudo desconfiamos de los enlaces simples, así que lo pegué directamente aquí (pero mantuve el enlace como referencia). Esa es la forma preferida por aquí. Los enlaces mueren (lo sé, ¡es github! Pero aún así puede morir en algún momento). De todos modos es una buena respuesta (+1). Tal vez podría ser mejor si lograras solucionar el problema con el código sed de Richard. Tiene un año y tiene la mala costumbre de no ser 100% compatible con versiones anteriores.
grochmal
2

Aquí hay una versión modificada de la respuesta de Richard Cook para solucionar problemas de escape en 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                              

Agregue las siguientes líneas al comienzo de .tmux.conf

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