Перезагрузка конфигурации tmux без отмены привязки ключей (bind-key является накопительным)

33

Я экспериментировал с различными настройками связывания ключей tmux и заметил следующее:

Если я перезагружу свой конфиг tmux (изнутри tmux), загруженные мной комбинации клавиш останутся загруженными. Единственный способ (я знаю) очистить это, чтобы выйти из всех сеансов tmux и перезапустить. Таким образом, похоже, что tmux запоминает все ранее загруженные сочетания клавиш и удаляет их только при новом запуске или путем явного снятия привязки.

Чтобы воссоздать это:

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

Мой вопрос: есть ли способ дать tmux команду "забыть" все загруженные конфиги и затем загрузить .tmux.conf?

Нильс Бом
источник

Ответы:

19

Согласно tmux(1)справочной странице, unbind-key -aэто то , что вы ищете.

Обратите внимание, что tmuxзапускается сервер, который будет выходить только после закрытия всех сеансов, и привязки клавиш будут для каждого сервера. Следовательно, как только вы создадите привязку, она будет постоянной для всех клиентских отделений.

Тем не менее, поместите его unbind-key -aв самый верх вашего файла конфигурации, и при перезагрузке конфигурации он должен делать то, что вы хотите - отсоединить все и начать связывание с нуля. Или - если ваши модификации меньше - отмените только то, что вы хотите изменить.

peterph
источник
Да, и я уже сказал это в своем вопросе. Но вместо «сброса» всех возможных связанных ключей вручную я бы хотел, чтобы 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, которые вы можете запустить, не ограничено , но каждый из них должен использовать свой путь к сокету; то -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

Я спросил вверх по течению, они, кажется, не желают это исправить (если кто-то не представит пиар).

Вот мой вручную экранированный 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

ПРИМЕЧАНИЕ. Каким-то образом ответ Ричарда Кука все еще приводил к выходу проблем.

timotheecour
источник
Добро пожаловать в unix.SE! Мы часто опасаемся простых ссылок, поэтому я вставил их прямо сюда (но сохранил ссылку для справки). Это предпочтительный способ здесь. Ссылки действительно умирают (я знаю, это github! Но все же он может умереть в какой-то момент). В любом случае, это хороший ответ (+1). Может быть, будет лучше, если вам удастся решить проблему с кодом sed Ричарда. Это год, и tmux имеет плохую привычку не быть обратно совместимым на 100%.
Grochmal
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
MilesF
источник