Более глубокое погружение в Tmux и Vim
8 марта 2022 г.Недавно я писал о нескольких [преимуществах использования tmux] (https://www.bugsnag.com/blog/benefits-of-using-tmux). Преимущества, о которых я говорил, не зависят от выбора текстового редактора. Но если вы пользователь vim, преимущества tmux становятся еще шире. Один из моих любимых аспектов tmux заключается в том, что он раскрывает потенциал более мощной среды разработки на основе vim, позволяя vim и оболочке чувствовать себя как единый сплоченный инструмент.
В этом посте мы рассмотрим несколько способов настройки tmux и vim, которые помогут сделать больше с меньшим набором текста и переключением контекста. Настройка tmux и vim для получения именно того поведения, которое вы хотите, часто требует много времени, но, на мой взгляд, оно того стоит. За последние несколько лет совместного использования tmux и vim я нашел несколько советов и плагинов, которые действительно выделяются. Этот пост представляет собой набор тех важных советов, которые стали неотъемлемой частью моего рабочего процесса разработки.
Если вы только начинаете работать с tmux и vim, обратитесь к соответствующему разделу для чтения, чтобы найти ссылки на некоторые ресурсы, которые помогут вам быстро освоиться.
Перемещение по vim и tmux
Бесшовная навигация
В качестве общей цели я хочу иметь возможность использовать движения в стиле vim и шаблоны редактирования текста, независимо от того, нахожусь ли я в vim или в какой-либо другой панели tmux.
В vim мы используем splits, чтобы разделить текущий вид, что позволяет нам редактировать несколько файлов рядом или даже для редактирования нескольких областей одного файла без необходимости прокрутки. Точно так же [панели] tmux (https://www.sourceallies.com/2009/11/vim-splits-an-introduction/) позволяют нам разделить наше окно, чтобы мы могли запускать и просматривать несколько команд и программ на основе терминала в в то же время.
Я постоянно использую vim splits, поэтому возможность эффективно перемещаться между ними имеет решающее значение. По умолчанию, если вы хотите перейти от одного разделения к другому, vim требует, чтобы вы нажали ctrl-W
, а затем одну из клавиш направления (например, h, j, k, l). Это не так эффективно, как кажется. может быть, особенно для такой общей операции.
Чтобы решить эту проблему, как и многие пользователи vim, я отредактировал файл .vimrc
, чтобы упростить навигацию по разбиениям, чтобы я мог переключаться между разбиениями vim, используя ctrl-j
, ctrl-k
и т. д. Это уже отличная эффективность. победить. С tmux на картинке мы можем использовать vim-tmux-navigator, чтобы не только настроить эти привязки клавиш vim, но и настроить аналогичные клавиши привязки для навигации по панели tmux. Это позволяет нам использовать ctrl-<direction>
для перемещения в любом месте нашего окна tmux, независимо от того, прыгаем ли мы между разделами vim или панелями tmux.
Настройка поведения навигации tmux
Вы можете захотеть настроить эти привязки навигационных клавиш в программах, отличных от vim.
Например, в последнее время я довольно часто использую нечеткий поиск командной строки [fzf] (https://github.com/junegunn/fzf). По умолчанию fzf поддерживает ctrl-k
и ctrl-j
для перемещения вверх и вниз по списку поисковых совпадений. К сожалению, это не сработает, если вы используете [предлагаемые] (https://github.com/christoomey/vim-tmux-navigator#add-a-snippet) привязки клавиш vim-tmux-navigator в вашем .tmux .conf
, которые выглядят следующим образом:
```javascript
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\S+\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n Ch if-shell "$ is_vim" "отправить ключи Ch" "выбрать панель -L"
bind-key -n Cj if-shell "$is_vim" "отправить ключи Cj" "выбрать панель -D"
bind-key -n C-k if-shell "$ is_vim" "отправить ключи C-k" "select-pane -U"
bind-key -n C-l if-shell "$ is_vim" "отправить ключи C-l" "select-pane -R"
bind-key -n C-\ if-shell "$is_vim" "отправить ключи C-\" "select-pane -l"
Эта часть конфигурации работает путем добавления условной логики к привязкам клавиш ctrl-<направление>
. Когда используется одна из этих команд перемещения, она проверяет, работает ли на текущей панели tmux vim. Если это так, будет отправлена соответствующая команда разделения vim. В противном случае отправляется соответствующая команда навигации панели tmux.
Используя немного другой подход, мы можем добавить логику, чтобы tmux обрабатывал fzf так же, как он обрабатывает vim, отправляя fzf свои собственные внутренние команды навигации, а не команды навигации панели tmux.
```javascript
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\S+\/)?g?(view|n?vim?x?)(diff)?$'"
is_fzf="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\S+\/)?fzf$'"
bind -n C-h run "($is_vim && tmux send-keys C-h) || \
панель выбора tmux -L"
bind -n C-j run "($is_vim && tmux send-keys C-j) || \
($is_fzf && tmux send-keys C-j) ||\
панель выбора tmux -D"
bind -n C-k run "($is_vim && tmux send-keys C-k) || \
($is_fzf && tmux send-keys C-k) || \
панель выбора tmux -U"
bind -n C-l run "($is_vim && tmux send-keys C-l) || \
панель выбора tmux -R"
bind-key -n C-\if-shell "$is_vim" "отправить ключи C-\" "select-pane -l"
Используя этот общий шаблон в вашем .tmux.conf
, вы можете дополнительно настроить поведение vim-tmux-navigator, чтобы он хорошо работал с любыми утилитами командной строки, которые используют навигацию в стиле vim.
Ниже показано, как вы можете перемещаться по разделителям vim, панелям tmux и результатам fzf, используя ctrl-<direction>
.
Стоит отметить, что вам не нужно делать это только для того, чтобы использовать vim-tmux-navigator и fzf вместе. В дополнение к ctrl-j
и ctrl-k
, fzf поддерживает ctrl-n
и ctrl-p
для навигации по результатам поиска. У него даже есть опция --bind
для установки пользовательских привязок клавиш fzf. Но, если вы специально хотите максимизировать универсальность привязок ctrl-j
, ctrl-k
и т. д. в нескольких приложениях, работающих в tmux, этот шаблон поможет.
Более похожая на vim оболочка
И Tmux, и bash поддерживают режимы vi, что может сделать вашу оболочку более похожей на ваш редактор. Это здорово, потому что это означает, что при переходе с панели vim на панель оболочки вам не нужно делать такое большое переключение контекста. Многие из тех же шаблонов для перемещения и работы с текстом все еще могут применяться.
Вы можете использовать [режим vi] tmux (https://blog.sanctum.geek.nz/vi-mode-in-tmux/), чтобы сделать режим копирования tmux более похожим на vim. В этом режиме вы можете использовать знакомые команды vim для прокрутки, поиска, выделения и копирования текста.
Точно так же вы можете попробовать bash [режим редактирования vi] (https://catonmat.net/bash-vi-editing-mode-cheat-sheet). Возможность использовать движения в стиле vi и команды сопоставления символов для быстрого редактирования команд оболочки действительно хороша. Внезапно написание команд оболочки в bash и строк кода в vim становится намного более похожим. Кроме того, если вы обнаружите, что редактируете сложную команду оболочки и хотите по-настоящему перейти в vim, просто войдите в обычный режим и нажмите v
. Это вернет вас в vim, где вы сможете закончить редактирование своей команды, запись этого файла вернет вас в оболочку и выполнит команду.
Пользователи vim часто переназначают пользовательские клавиши для выхода, поэтому мы можем избегать достижения каждый раз, когда переходим от вставки к обычному режиму. Например, я использую последовательность «kj», чтобы вывести меня из режима вставки. Чтобы режим vi в bash был удобным, важно иметь возможность использовать привычное сопоставление для перехода из режима вставки в обычный режим в командной строке.
Это можно настроить в вашем файле ~/.inputrc
. В моем случае, чтобы заставить kj
работать, я добавил следующее:
```javascript
установить режим редактирования vi
настройки ви
$если режим=ви
установить раскладку клавиатуры vi-insert
"kj" # переназначение escape
$endif
Упростить разделение vim и создание панели tmux
Разделение и панели являются основополагающими концепциями и должны быть очень просты в использовании. Мы уже рассмотрели стандартизацию того, как мы перемещаемся между разделениями и панелями, но как насчет их создания в первую очередь?
Я не большой поклонник настроек tmux по умолчанию для работы с панелями по нескольким причинам. Во-первых, если вы уже знакомы с терминологией разделения vim, слова «горизонтальный» и «вертикальный» будут означать противоположное тому, что вы ожидаете, когда речь идет о панелях tmux. И, во-вторых, команды по умолчанию (<Prefix>%
и <Prefix>"
) для создания разбиений tmux никогда не казались мне интуитивно понятными.
Я использую следующее в своем .tmux.conf
:
```javascript
связать | разделенное окно -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
Прелесть этого в том, что он позволяет вам продолжать думать о разделениях и панелях с точки зрения ориентации разделителя, точно так же, как вы думали бы о разделении vim. С этими привязками <Prefix>|
добавляет вертикальный разделитель панели (как вертикальное разделение в vim), а <Prefix>-
добавляет горизонтальный. Если я правильно помню, я впервые увидел эти привязки, рекомендованные в книге Tmux: [Productive Mouse-FreeDevelopment] (https://pragprog.com/book/bhtmux/tmux), которая полна отличных советов по tmux и действительно заслуживает прочтения. .
В vim я в основном использую вертикальное разделение.
Поэтому я установил следующее в своем .vimrc
, что означает, что в обычном режиме создание нового вертикального разделения так же просто, как нажать vv
.
```javascript
" vv для создания нового вертикального разделения
карта nnore
Разделение и панели — отличные функции, поэтому самое главное — найти привязки клавиш, которые сделают их быстрыми и интуитивно понятными для вас.
Быстро запускайте команды оболочки, не выходя из vim
Используя то, что мы уже рассмотрели, теперь у нас есть возможность быстро создавать панели tmux и перемещаться между ними, запуская команды там, где мы хотим. Как это ни просто, иногда предпочтительнее создать панель и запустить в ней команду, вообще не выходя из vim.
Я использую vimux и связанные с ним плагины для запуска команд терминала изнутри vim.
Основные команды Vimux
Одной из основных особенностей vimux является возможность запуска произвольной команды оболочки из vim. После установки vimux вы можете получить доступ к командной строке из vim, запустив : VimuxPromptCommand
. Затем вы можете сразу начать вводить команду оболочки. Нажатие ввода запустит команду на панели tmux в текущем окне. При необходимости vimux создаст новую панель для запуска команды.
Вводить :VimuxPromptCommand
каждый раз, когда вы хотите запустить команду, не лучший вариант, поэтому рекомендуется добавить сопоставление к вашему .vimrc
, как показано ниже:
```javascript
" Запросить команду для запуска
map
Теперь в обычном режиме вы сможете ввести <Leader>vp
, чтобы вызвать подсказку и ввести команды, как показано здесь.
Это уже полезно, особенно для запуска тестов, сборок или сценариев обработки данных. Во многих случаях, особенно для тестов, вы обнаружите, что хотите запустить команду оболочки, внести некоторые изменения в код, а затем снова запустить команду оболочки.
```javascript
" Запустить последнюю команду, выполненную VimuxRunCommand
map
Теперь из обычного режима <Leader>vl
повторно запустит самую последнюю команду vimux. Это действительно сияет, когда дело доходит до запуска тестов.
При запуске тестов с помощью vimux
Vimux особенно полезен, когда у вас есть неудачный тест, который вы пытаетесь исправить. Рабочий процесс выглядит следующим образом:
- Найдите неудачный тест, прочитайте его и запустите.
- Внесите изменения в код приложения, чтобы пройти тест
- Повторно запустите последний тест (т. е. последнюю команду vimux), используя
<Leader>vl
- Повторяйте шаги 2 и 3, пока тест не будет пройден.
Используя этот рабочий процесс, можно более эффективно пройти неудачный тест, даже не покидая vim. Быстрый перезапуск последней тестовой команды особенно полезен.
По возможности рассмотрите возможность использования vimux [плагина для конкретной платформы] (https://github.com/preservim/vimux#plugins для конкретной платформы). Они обеспечивают поддержку запуска текущего сфокусированного теста в тестовом файле, запуска всех тестов в текущем файле и т. д.
Быстрое копирование вывода vimux
Допустим, вы хотите прокрутить или скопировать часть вывода с панели vimux. Вы можете использовать ctrl-<direction>
для перехода от vim к панели vimux, затем вы должны войти в режим копирования tmux, используя <prefix>
. Это немного сложно. К счастью, vimux предлагает ярлык для этого рабочего процесса.
Добавьте следующее в ваш .vimrc
:
```javascript
" Осмотрите панель бегуна
map
Теперь <Leader>vi
— это все, что вам нужно, чтобы перейти из vim в панель vimux, уже в режиме копирования. Отсюда вы можете использовать движения в стиле vi, как упоминалось ранее, для перемещения, выбора текста и копирования его в буфер обмена. .
Получение лучшего представления о выводе vimux
Иногда, особенно при просмотре тестового вывода на экране ноутбука, чтение длинных строк в маленькой области может быть немного громоздким. Существует множество способов эффективного изменения размера панелей с помощью tmux, но в этом случае я обнаружил, что функция масштабирования vimux очень помогает. Если вы раньше не использовали масштабирование, это функция tmux, которая максимизирует активную панель, чтобы заполнить пространство всего окна tmux. Когда вы закончите масштабирование, вы вернетесь к предыдущему расположению панелей, которое у вас было раньше. Дополнительную информацию о масштабировании tmux можно найти [здесь] (https://blog.sanctum.geek.nz/zooming-tmux-panes/). Я сопоставил vz с командой vimux, которая будет увеличивать панель запуска tmux.
```javascript
"Увеличить панель бегуна tmux
<лидер>vz :VimuxZoomRunner
Теперь вы можете запустить свои тесты с помощью одной команды vimux и, если вам нужно, увеличить результаты с помощью <Leader>vz
. Как правило, в этот момент, чтобы выйти из режима масштабирования, вам нужно использовать <Prefix>z
tmux, и это будет работать нормально. Но если вы используете vim-tmux-navigator, как указано выше, вы также можете использовать команды ctrl-<direction>
для выхода из режима масштабирования.
Быстрее с аккордами
Я часто использую команды vimux. Настолько, что использование команд с префиксом лидера, как я описал выше (например, <Leader>vl
), стало казаться неэффективным. \~3 нажатия клавиш — это слишком много для действия, которое стало таким важным в моем рабочем процессе vim.
На практике я настроил vim chords для обычных случаев использования, таких как запуск одного теста, запуск всех тестов в файле, повторный запуск последней команды и т. д. Если вы еще не пробовали аккорды, очень рекомендую. Каждый раз, когда ведущая клавиша начинает ощущаться больше как лежачий полицейский, чем как ярлык, я начинаю спрашивать, не использовать ли мне аккорд. Аккорды Vim могут быть сопоставлены с любой функциональностью, которая вам нравится, но лично я использую их почти исключительно для привязок vimux.
Вот базовый пример, показывающий простой рабочий процесс исправления неудачного теста. Это объединяет несколько элементов, обсуждавшихся до сих пор:
- Тест изначально запускается с использованием аккорда, сопоставленного с методом тестирования [vimux-ruby] (https://github.com/pgr0ss/vimux-ruby-test) RunRubyFocusedTest. Аккорд фактически представляет собой одно нажатие клавиши.
- Разделенная навигация vim выполняется с помощью
ctrl-l
- Последующие тестовые запуски выполняются с использованием другого аккорда, который повторно запускает последнюю команду vimux.
Последние мысли
За последние несколько лет tmux и vim вместе с этими настройками и практиками сформировали для меня основу действительно приятной среды разработки. В этом посте рассматриваются лишь некоторые из многих возможных способов настройки tmux и vim, чтобы получить еще больше от обоих. Основополагающий принцип здесь заключается в стремлении к эффективности, а именно: когда это целесообразно, мы должны уменьшить количество нажатий клавиш и когнитивную нагрузку, необходимую для выполнения обычных частей работы. Независимо от того, используете ли вы vim и tmux или нет, стоит рассмотреть цель этих советов, поскольку они применимы к вашим собственным инструментам разработки. Надеюсь, вы найдете этот процесс таким же увлекательным, как и я.
Большое спасибо Bram Moolenaar, Chris Toomey, Ben Mills и Junegunn Choi за их вдумчивые комментарии к более ранним версиям этого поста и, что более важно, за их неоценимый вклад в работу с открытым исходным кодом.
Оригинал