Przeładuj konfigurację tmux nie usuwając kluczy (klucz dostępu jest kumulatywny)

33

Eksperymentowałem z różnymi ustawieniami klawiszy Tmux i zauważyłem, co następuje:

Jeśli ponownie załaduję konfigurację tmux (z poziomu tmux), skróty, które kiedyś załadowałem, pozostaną załadowane. Jedynym sposobem (wiem o tym), aby to wyczyścić, jest zamknięcie wszystkich sesji Tmux i ponowne uruchomienie. Wygląda więc na to, że tmux zapamiętuje wszystkie wcześniej załadowane skróty klawiszowe i usunie je dopiero od nowa lub przez jawne ich odblokowanie.

Aby odtworzyć to:

  • otwórz terminal (A)
  • uruchom tmux
  • sprawdź, czy skrót klawiszowy pokazuje zegar (naciśnij PREFIX C-t)
  • naciśnij, PREFIX ?aby zobaczyć skrót klawiszowy na liście
  • edytować ~/.tmux.conf
  • dodaj skrót klawiszowy ( bind C-t display "Keybinding C-t")
  • przeładuj tmux config ( PREFIX : source-file ~/.tmux.conf)
  • sprawdź, czy działa skrót klawiszowy (naciśnij PREFIX C-t)
  • naciśnij, PREFIX ?aby zobaczyć nowe skrót klawiszowy na liście
  • edytuj ~/.tmux.confponownie
  • usuń przypisanie klawiszy (więc usuń bind C-t display "Keybinding C-t")
  • przeładuj tmux config ( PREFIX : source-file ~/.tmux.conf)
  • sprawdź, czy klawisz działa (naciśnij PREFIX C-t), nadal wyświetla „Ct klawiszowania ”
  • naciśnij, PREFIX ?aby zobaczyć, że nowe klawisze są nadal na liście
  • wyjdź z tmux
  • wpisz tmux
  • sprawdź, czy oryginalne klawisze działają ponownie (naciśnij PREFIX C-t), teraz powinien ponownie wyświetlić zegar
  • naciśnij, PREFIX ?aby zobaczyć, że nowe przypisanie klawiszy zostało usunięte z listy

Moje pytanie: czy istnieje sposób, aby pouczyć tmux, aby „zapomniał” wszystkie załadowane konfiguracje, a następnie załadował .tmux.conf?

Niels Bom
źródło

Odpowiedzi:

19

Według tmux(1)strony man, unbind-key -ajest to, czego szukasz.

Pamiętaj, że tmuxdziała serwer, który zakończy działanie dopiero po zamknięciu wszystkich sesji, a powiązania klawiszy zostaną przypisane do poszczególnych serwerów. Dlatego po utworzeniu powiązania będzie ono trwałe dla wszystkich odłączeń klienta.

To powiedziawszy, umieść unbind-key -ana samym początku pliku konfiguracyjnego, a przy ponownym ładowaniu config powinien zrobić to, co chcesz - rozpiąć wszystko i rozpocząć wiązanie od zera. Lub - jeśli modyfikacje są mniejsze - odznacz tylko to, co chcesz zmienić.

Peter
źródło
Tak i już to stwierdziłem w swoim pytaniu. Ale zamiast „resetowania” wszystkich ewentualnie powiązanych kluczy ręcznie chciałbym, aby tmux zrestartował się z „czystym kontem”, a następnie ponownie załadował plik konfiguracyjny.
Niels Bom,
@NielsBom sprawdź zaktualizowaną odpowiedź, proszę
Peter
Masz rację, unbind-key -ausuwa wszystkie skróty klawiszowe. Oznaczę twoją odpowiedź jako poprawną, ale ze względu na innych widzów dodam również „hack”, który zastosowałem w celu rozwiązania problemu unbind-key -a.
Niels Bom,
Zobacz moją odpowiedź na moje rozwiązanie.
Niels Bom,
16

Prawidłowe rozwiązanie (autor: Peter

Więc @peterph podał poprawną odpowiedź, która jest unbind-key -anastępująca: (man tmux)

Jeśli występuje -a, wszystkie powiązania klawiszy są usuwane.

Realne rozwiązanie

Problem (dla mnie) polega na tym, że „wszystko” w rzeczywistości oznacza wszystko. Łącznie ze skrótami klawiszowymi, które posiada tmux . Jeśli wykonasz unbind-key -apolecenie, tmux natychmiast nie ma już żadnych skrótów klawiszowych, więc nie możesz nawet przejść do trybu poleceń ani nic innego robić.

Moja (raczej brzydka) poprawka do tego jest następująca:

  • utwórz a, .tmux.reset.confktóry usunie wszystkie skróty klawiszowe, a następnie ponownie powiąże wszystkie te, które domyślnie ma tmux
  • źródło, które resetuje się u góry .tmux.conf

Mój .tmux.conf:

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

Mój .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

Wyglądało na to, że mogło to działać z tabelami kluczy Tmux (o ile mi wiadomo), ale nie można dodawać nowych tabel kluczy.

Niels Bom
źródło
1
Prawdopodobnie możesz szybko wygenerować ekwiwalent swojego .tmux.reset.conf, uruchamiając tmux list-keyssesję „czystą”.
jw013
2
tmux -f /dev/null -L temp start-server \; list-keysskutecznie wygeneruje wartości domyślne (choć trzeba dodać ukośnik odwrotny przed średnikiem w powiązaniu).
Chris Johnsen,
@ChrisJohnsen Czy mógłbyś opracować na serwerze startowym osobną odpowiedź?
Niels Bom,
7

Obecnie nie ma bezpośredniego sposobu, aby zresetować powiązanie klucza z domyślnym; inicjalizacja domyślnych powiązań (in key_bindings_init()) odbywa się raz, gdy serwer tmux uruchamia się po raz pierwszy (in server_start()), i nie ma mechanizmu do resetowania pojedynczego klucza.

W pożądanym scenariuszu, w którym chcesz, aby proces pozyskiwania pliku konfiguracyjnego ponownie ustanowił domyślne powiązanie, które zostało wcześniej zastąpione niestandardowym powiązaniem, które zostało później usunięte z pliku konfiguracyjnego, opracowana metoda jest rozsądna (choć niestety pełna): unbind-key -a , następnie przywróć wszystkie „domyślne” wiązania, a następnie utwórz własne wiązania (niektóre z nich mogą zastąpić „domyślne”).

Bieżące powiązania serwera można wyodrębnić za pomocą list-keyspolecenia * ; może to pomóc w generowaniu / utrzymywaniu proponowanego .tmux.reset.confpliku, ale potrzebujesz sposobu na wyodrębnienie domyślnych powiązań, a nie bieżących .

* Istnieją sytuacje, w których dane wyjściowe list-keysnie są obecnie bezpośrednio użyteczne: wiązanie średnika wymaga, aby jego średnik uciekł odwrotnym ukośnikiem, aby zapobiec interpretacji go jako separatora poleceń tmux oraz wszelkich powiązań, które miały argumenty wykorzystujące podwójne cudzysłowy wewnątrz pojedynczego cytaty (żadne z domyślnych powiązań nie są takie) pojawią się jako podwójne cudzysłowy wewnątrz podwójnego qoutes.

Aby uzyskać domyślne powiązania, potrzebujesz tymczasowego serwera z minimalną konfiguracją (tj. Bez niestandardowych powiązań), abyś mógł przechwytywać jego list-keysdane wyjściowe. Nie ma ograniczeń co do liczby serwerów Tmux , które możesz uruchomić, ale każdy z nich musi używać innej nazwy ścieżki gniazda; te -Li -S tmux opcje mogą być wykorzystane, aby określić nazwę gniazda (w $TMPDIR/tmux-$UIDlub pełną ścieżkę gniazdo tak, to do rozmowy (lub uruchomić) nowy serwer o nazwie gniazda. temp, należy użyć tego:

tmux -L temp …

Aby upewnić się, że nie używa twojego .tmux.conf, możesz -fpowiedzieć mu, aby przeczytał /dev/null(specjalny plik, który jest zawsze pusty):

tmux -f /dev/null -L temp …

Uwaga : nie uniemożliwia to przetwarzania/etc/tmux.conf , jeśli taki plik istnieje; ścieżka do tego „pliku konfiguracji systemu” jest zakodowana na stałe i nie ma możliwości ominięcia go (bez łatania kodu).

Zwykle potrzebujesz new-sessionpolecenia, aby faktycznie uruchomić serwer, ale nie chcemy żadnych sesji, tylko zainicjowany serwer do zapytania. start-serverKomenda właśnie to robi: uruchamia serwer bez tworzenia sesji.

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

Teraz wystarczy dołączyć nasze polecenie „zapytanie” ( list-keysw tym przypadku):

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

Uwaga : średnik musi być poprzedzony znakiem zapytania lub cudzysłowem, aby powłoka nie traktowała go jako separatora poleceń powłoki, ponieważ chcemy, aby był tmux separatorem poleceń .

Ponieważ nie ma żadnych sesji do utrzymania, serwer zakończy działanie automatycznie po zakończeniu działania list-keys polecenia.

Możesz więc użyć takiego polecenia, aby wygenerować większość .tmux.reset.confbez konieczności tymczasowego usuwania .tmux.confpliku (aby zobaczyć tylko domyślne powiązania) i bez konieczności zamykania istniejących serwerów.


Jeśli run-shellpolecenie było synchroniczne, możesz osadzić takie wywołanie w pliku konfiguracyjnym (przechwytywanie do pliku tymczasowego, który następnie przetworzyłbyś source-file) zamiast mieć plik statyczny (twój .tmux.reset.conf). Pozwoliłoby to zawsze używać domyślnych powiązań z bieżącej wersji tmux (domyślne wiązania czasami się zmieniają). Niestety, wykonanie run-shellpolecenia jest obecnie asynchroniczne w odniesieniu do kolejnych poleceń (polecenia, które pojawiają się po run-shellpoleceniu, zwykle są uruchamiane, zanim proces spawnowany run-shellmiał szansę zakończyć).

Chris Johnsen
źródło
6

Oto zestawienie wszystkich innych odpowiedzi w skrypcie bash, który będzie automatycznie generowany .tmux.reset.confz domyślnych powiązań klawiszy:

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

Osadzony sedwiersz poleceń dba o uniknięcie różnych części danych wyjściowych list-keys. Może to wymagać drobnych poprawek ze względu na specyfikę twojego systemu.

W swoim .tmux.confpliku po prostu rozpisz wszystkie klucze i źródłowy plik przed zdefiniowaniem własnych powiązań klawiszy:

unbind-key -a
source-file ~/.tmux.reset.conf
Richard Cook
źródło
4

Proszę również odnieść się do innych odpowiedzi tutaj, ponieważ wykonują dobrą robotę wyjaśniając sytuację. Mam tutaj mój tmux.reset.conf kompatybilny z Tmux 1.8 , który musiałem wprowadzić kilka modyfikacji po skopiowaniu danych tmux -f /dev/null -L temp start-server \; list-keyswyjściowych. W szczególności trzeba było zacytować kilka rzeczy.

# 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
źródło
4

Zapytałem wcześniej, że wydaje się, że nie chcą tego naprawiać (chyba że ktoś prześle PR).

Oto moja ręcznie ocalona tmux list-keys, uzyskana przez nową instancję serwera za pomocą

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

(dzięki poprzednim odpowiedziom)

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

Powyższe znajduje się na github, dzięki czemu możesz:

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

UWAGA: W jakiś sposób odpowiedź Richarda Cooka wciąż powodowała ucieczkę.

timotheecour
źródło
Witamy w unix.SE! Często obawiamy się zwykłych linków, więc wkleiłem go bezpośrednio tutaj (ale zachowałem link w celach informacyjnych). To jest preferowany sposób tutaj. Linki umierają (wiem, że to github! Ale i tak może umrzeć w pewnym momencie). W każdym razie to dobra odpowiedź (+1). Może może być lepiej, jeśli uda Ci się rozwiązać problem z kodem sed Richarda. To jest rok i tmux ma zły nawyk, że nie jest w 100% kompatybilny wstecz.
grochmal
2

Oto poprawiona wersja odpowiedzi Richarda Cooka, aby rozwiązać problemy związane z ucieczką w 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                              

Dodaj następujące wiersze na początku .tmux.conf

unbind-key -a
source-file ~/.tmux.reset.conf
MilesF
źródło