Перезавантаження конфігурації tmux не розв’язує ключі (прив'язка-ключ є сукупною)


33

Я експериментував з різними налаштуваннями прив’язки клавіш tmux і помітив наступне:

Якщо я перезавантажую конфігурацію tmux (зсередини tmux), клавіші, які я колись завантажував, залишаються завантаженими. Єдиний спосіб (який я знаю) очистити це - це закрити всі сеанси tmux та перезапустити. Таким чином, схоже, що tmux запам'ятовує всі раніше завантажені клавіатурні вкладиші та видалить їх лише на новому запуску або шляхом явного їх розв’язування.

Щоб відтворити це:

  • відкрити термінал (A)
  • запустити tmux
  • перевірити, чи на клавіатурі показано годинник (натисніть PREFIX C-t)
  • натисніть, PREFIX ?щоб побачити прив'язку клавіш у списку
  • редагувати ~/.tmux.conf
  • додати палітурку ( bind C-t display "Keybinding C-t")
  • перезавантажити tmux config ( PREFIX : source-file ~/.tmux.conf)
  • перевірте, чи працює палітурка клавіш (натисніть PREFIX C-t)
  • натисніть, PREFIX ?щоб побачити нове введення клавіш у списку
  • редагувати ~/.tmux.confще раз
  • видаліть палітурку клавіш (тому видаліть bind C-t display "Keybinding C-t")
  • перезавантажити tmux config ( PREFIX : source-file ~/.tmux.conf)
  • перевірте, чи працює палітурка клавіш (натисніть PREFIX C-t), на ній все ще відображається "Клавіша Ct"
  • натисніть, PREFIX ?щоб побачити, що нове в'язання клавіш все ще є в списку
  • вихід tmux
  • введіть tmux
  • перевірте, чи спрацьовує оригінальна клавіша знову (натисніть PREFIX C-t), тепер вона повинна знову відображати годинник
  • натисніть, PREFIX ?щоб побачити, що нове введення клавіш було видалено зі списку

Моє запитання: чи є спосіб доручити tmux "забути" всі завантажені конфігурації і потім завантажити .tmux.conf?

Відповіді:


19

За даними tmux(1)сторінки людини, unbind-key -aце те, що ви шукаєте.

Зауважте, що tmuxзапускається сервер, який завершиться лише після закриття всіх сеансів, а прив'язка ключів - до кожного сервера. Отже, щойно ви створите прив'язку, вона буде стійкою для всіх клієнтських загонів.

Сказавши це, поставте unbind-key -aв самий верхній частині вашого конфігураційного файлу, і при перезавантаженні конфігурації він повинен робити все, що вам завгодно - відв’яжіть все і почніть прив’язувати з нуля. Або - якщо ваші модифікації менші - скасуйте лише те, що ви хочете змінити.


Так, і я це вже заявив у своєму питанні. Але замість "скидання" всіх можливо пов'язаних клавіш вручну, я хотів би, щоб tmux перезапустився з "чистого аркуша", а потім перезавантажив файл конфігурації.
Нільс Бом

@NielsBom перевірити оновлену відповідь будь ласка
peterph

Ви маєте рацію, unbind-key -aвидаляє всі клавіші. Я відзначу вашу відповідь правильною, але заради інших глядачів я також додам "хак", який я застосував, щоб вирішити проблему unbind-key -a.
Нільс Бом

Дивіться мою відповідь на моє рішення.
Нільс Бом

16

Правильне рішення (за Петром

Тож @peterph дав правильну відповідь, яка полягає unbind-key -aв наступному: (man tmux)

Якщо -a присутній, всі ключові прив’язки видаляються.

Працездатне рішення

Проблема (для мене) полягає в тому, що "все" насправді означає все. Включаючи вкладиші клавіш, до яких входить tmux . Якщо ви виконуєте unbind-key -aкоманду tmux миттєво, більше не має ніяких клавішних зв’язків, тому ви навіть не можете входити в командний режим або робити щось в основному.

Моє (досить потворне) виправлення для цього полягає в наступному:

  • створіть, .tmux.reset.confщо видаляє всі зв'язки клавіш, а потім відновить усі ті, які має tmux за замовчуванням
  • джерело, яке скидається у верхній частині вашого .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 (наскільки я можу сказати), але ви не можете додавати нові таблиці ключів.


1
Цілком ймовірно, що ви можете швидко генерувати еквівалент свого .tmux.reset.conf, запустивши tmux list-keysв "чистий" сеанс.
jw013

2
tmux -f /dev/null -L temp start-server \; list-keysефективно генерує параметри за замовчуванням (хоча вам потрібно додати зворотну косу риску перед крапкою з комою в її прив'язці).
Кріс Джонсен

@ChrisJohnsen Чи можете ви окремо відповісти на стартовий сервер?
Нільс Бом

7

Наразі немає прямого способу відновити прив’язку ключа до його за замовчуванням; ініціалізація прив'язки за замовчуванням (in key_bindings_init()) робиться один раз, коли tmux- сервер вперше запускається (in server_start()), і немає механізму для скидання одного ключа.

Для потрібного сценарію , в якому ви хочете акт пошуку файлу конфігурації , щоб відновити значення за замовчуванням прив'язки , який раніше був перевизначений звичаї зв'язування , який з тих пір був видалений з файлу конфігурації, метод , який ви розробили розумно (хоча , до жаль , багатослівний): unbind-key -a, потім відновіть всі прив’язки "за замовчуванням", а потім встановіть власні прив'язки (деякі з яких можуть замінити прив'язку "за замовчуванням").

Поточні прив'язки сервера можуть бути вилучені list-keysкомандою * ; це може допомогти генерувати / підтримувати запропонований .tmux.reset.confфайл, але вам потрібен спосіб витягнути прив'язки за замовчуванням , а не поточні прив’язки.

* Є деякі ситуації, коли вихідний list-keysмомент наразі не використовується безпосередньо: прив’язка для крапки з комою потрібна, щоб його крапка з комою була усунена зворотною косою рисою, щоб запобігти інтерпретації її як розділювач команд tmux , а також будь-які прив'язки, які мали аргументи, які використовували подвійні лапки всередині одиничного лапки (жодна з прив’язок за замовчуванням не є такою) вийдуть у вигляді подвійних лапок всередині подвійних котирувань .

Щоб отримати прив'язки за замовчуванням, вам потрібен тимчасовий сервер з мінімальною конфігурацією (тобто відсутні спеціальні прив’язки), щоб ви могли захопити його list-keysвихід. Немає обмеження в кількості серверів tmux, які можна запустити, але кожен повинен використовувати інше ім'я шляху socket; параметри -Lі -S tmux можуть використовуватися для вказування імені сокета (у $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

Примітка : крапку з комою потрібно уникати або цитувати, щоб оболонка не розглядала її як роздільник команд оболонки, оскільки ми хочемо, щоб вона була роздільником команд tmux .

Оскільки немає сеансів для підтримки, сервер автоматично завершиться після завершення виконання list-keysкоманди.

Таким чином, ви можете використовувати таку команду, щоб генерувати основну частину вашої, .tmux.reset.confне турбуючись про тимчасове видалення .tmux.confфайлу (щоб ви могли бачити лише прив’язки за замовчуванням) та без необхідності закривати будь-які існуючі сервери.


Якщо run-shellкоманда була синхронною, ви можете вбудувати подібний виклик у свій файл конфігурації (захоплення у тимчасовий файл, який ви потім оброблятимете source-file), а не статичний файл (ваш .tmux.reset.conf). Це дозволить вам завжди використовувати прив'язки за замовчуванням з вашої поточної версії tmux (прив'язки за замовчуванням періодично змінюються). На жаль, завершення run-shellкоманди в даний час є асинхронним щодо наступних команд (команди, що надходять після run-shellкоманди, зазвичай виконуються до того, як процес, породжений яким run-shellбув шанс закінчити).


6

Ось збірка всіх інших відповідей у ​​скрипт bash, який автоматично генерується .tmux.reset.confіз прив'язки клавіш за замовчуванням:

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

4

Будь ласка, також зверніться до інших відповідей тут, оскільки вони добре роз’яснюють ситуацію. У мене є мій 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

Я попросив вище за течією, вони здаються не бажаючими виправити це (якщо хтось не подає 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

ПРИМІТКА. Якимсь чином відповідь Річарда Кука все ще викликала проблеми, що залишаються.


Ласкаво просимо на unix.SE! Ми часто остерігаємось простих посилань, тому я вставив його прямо сюди (але зберіг посилання для довідки). Ось найкращий шлях тут. Посилання вмирають (я знаю, це github! Але все-таки воно може загинути в якийсь момент). Так чи інакше, це хороша відповідь (+1). Можливо, може бути і краще, якби вам вдалося виправити проблему з кодом sed Richard. Це рік, і tmux має погану звичку бути невідповідним на 100%.
грочмал

2

Ось виправлена ​​версія відповіді Річарда Кука, щоб виправити проблеми, що виникають на 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                              

Додайте наступні рядки до початку .tmux.conf

unbind-key -a
source-file ~/.tmux.reset.conf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.