Вопрос или проблема
Я использую tmux с клавишами vi, и копирование/вставка работает нормально, если вы выделяете одну строку текста или у вас только одно окно. Когда я хочу выделить блок текста (несколько строк, но не всю ширину), я сталкиваюсь с проблемами. Если у меня открыто несколько окон vim, то выделяется текст из всех них, а мне нужно выделить текст только в одном окне. То есть, как в визуальном выделении в vim.
Это возможно сделать?
Убедитесь, что вы проверили нижнюю часть этого поста для необходимых привязок, которые нужно добавить в ваш файл .tmux.conf.
Я предполагаю, что ваша клавиша префикса — C-a:
- C-a означает: нажмите Ctrl + A
- C-a [ означает: нажмите Ctrl + A, затем нажмите [
Чтобы сделать прямоугольное выделение текста от (1,1) до (2,2) в tmux:
- Перейдите в режим копирования: C-a [
- Переместите курсор к середине строки
- Нажмите C-v
- Нажмите пробел
- Перемещайте выделение с помощью jkhl
- Как только вам понравится ваше выделение, нажмите Enter (или y, если у вас есть
привязка в вашем конфиге). - Вы можете вставить последний буфер копирования с помощью: C-a ]
Заметьте, что нажатие пробел необходимо для прямоугольного выделения.
Чтобы выделять строки, как вы это делаете обычно, перейдите в режим копирования и нажмите v, выделите с помощью клавиш jkhl и нажмите y.
У меня есть эти привязки в моем .tmux.conf:
Перед версией 2.4 (20 апреля 2017):
setw -g mode-keys vi
bind-key -t vi-copy 'v' begin-selection # Начать выделение в режиме копирования.
bind-key -t vi-copy 'C-v' rectangle-toggle # Начать выделение в режиме копирования.
bind-key -t vi-copy 'y' copy-selection # Копировать выделение в режиме копирования.
После версии 2.4:
setw -g mode-keys vi
bind-key -T copy-mode-vi 'v' send -X begin-selection # Начать выделение в режиме копирования.
bind-key -T copy-mode-vi 'C-v' send -X rectangle-toggle # Начать выделение в режиме копирования.
bind-key -T copy-mode-vi 'y' send -X copy-selection # Копировать выделение в режиме копирования.
Важно отвязать стандартную привязку rectangle-toggle:
unbind-key -t vi-copy v # Перед версией 2.4
unbind-key -T copy-mode-vi v
Иначе новая привязка ‘C-v’ не будет работать.
Примечание: чтобы иметь один .tmux.conf
, который будет работать на всех версиях, смотрите этот вопрос.
Вы можете выделить визуальный блок, как в vi — просто наберите v
перед началом выделения. В руководстве это называется “Переключение прямоугольника”.
Как указывает Ларс, v
действительно выполняет то, что вы запрашиваете, переключаясь между режимом прямоугольного выделения и режимом выделения всей строки. пробел
и enter
используются соответственно для начала нового выделения и его копирования. Войдите в режим копирования, используя вашу клавишу префикса, за которой следует [
, и вставьте ваше скопированное выделение в любое окно tmux, используя ]
.
Это также сбивало меня с толку, поскольку v
в vim работает так же, как пробел
в tmux, для начала выделения.
Ввод :list-keys -T copy-mode-vi
в tmux покажет полную таблицу команд в режиме копирования.
bind-key -t vi-copy C-b page-up
bind-key -t vi-copy C-c cancel
bind-key -t vi-copy C-e scroll-down
bind-key -t vi-copy C-f page-down
bind-key -t vi-copy C-h cursor-left
bind-key -t vi-copy Enter copy-selection
bind-key -t vi-copy C-y scroll-up
bind-key -t vi-copy Escape clear-selection
bind-key -t vi-copy Space begin-selection
bind-key -t vi-copy $ end-of-line
bind-key -t vi-copy , jump-reverse
bind-key -t vi-copy / search-forward
bind-key -t vi-copy 0 start-of-line
bind-key -t vi-copy 1 start-number-prefix
bind-key -t vi-copy 2 start-number-prefix
bind-key -t vi-copy 3 start-number-prefix
bind-key -t vi-copy 4 start-number-prefix
bind-key -t vi-copy 5 start-number-prefix
bind-key -t vi-copy 6 start-number-prefix
bind-key -t vi-copy 7 start-number-prefix
bind-key -t vi-copy 8 start-number-prefix
bind-key -t vi-copy 9 start-number-prefix
bind-key -t vi-copy : goto-line
bind-key -t vi-copy ; jump-again
bind-key -t vi-copy ? search-backward
bind-key -t vi-copy B previous-space
bind-key -t vi-copy D copy-end-of-line
bind-key -t vi-copy E next-space-end
bind-key -t vi-copy F jump-backward
bind-key -t vi-copy G history-bottom
bind-key -t vi-copy H top-line
bind-key -t vi-copy J scroll-down
bind-key -t vi-copy K scroll-up
bind-key -t vi-copy L bottom-line
bind-key -t vi-copy M middle-line
bind-key -t vi-copy N search-reverse
bind-key -t vi-copy T jump-to-backward
bind-key -t vi-copy W next-space
bind-key -t vi-copy ^ back-to-indentation
bind-key -t vi-copy b previous-word
bind-key -t vi-copy e next-word-end
bind-key -t vi-copy f jump-forward
bind-key -t vi-copy g history-top
bind-key -t vi-copy h cursor-left
bind-key -t vi-copy j cursor-down
bind-key -t vi-copy k cursor-up
bind-key -t vi-copy l cursor-right
bind-key -t vi-copy n search-again
bind-key -t vi-copy q cancel
bind-key -t vi-copy t jump-to-forward
bind-key -t vi-copy v rectangle-toggle
bind-key -t vi-copy w next-word
bind-key -t vi-copy BSpace cursor-left
bind-key -t vi-copy NPage page-down
bind-key -t vi-copy PPage page-up
bind-key -t vi-copy Up cursor-up
bind-key -t vi-copy Down cursor-down
bind-key -t vi-copy Left cursor-left
bind-key -t vi-copy Right cursor-right
bind-key -t vi-copy C-Up scroll-up
bind-key -t vi-copy C-Down scroll-down
Поскольку ни одно из других ответов не дает оптимального решения проблемы, я не против некромантии.
Существует способ сделать выбор блока так, как это делается в Vim, не нажимая пробел. Просто простой Ctrl-V, запомненный вашими мышечными воспоминаниями.
Это требует редактирования вашего .tmux.conf (но использование vi-mode уже делает это) и я не уверен, работает ли это для tmux < 2.4.
Добавьте это в ваш .tmux.conf, чтобы воспроизвести привязки выбора и зачеркивания Vim:
# включить vi-режим
set-window-option -g mode-keys vi
# привязки клавиш
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle \; send -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
# закомментируйте предыдущую строку и раскомментируйте следующую, чтобы зачеркивать на X буфер обмена
# bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"
Войдите в режим выделения и перейдите к тому месту, где хотите начать выделение. Теперь v
начинает обычное (по символам, по строкам) выделение, <C-v>
начинает прямоугольное выделение, а V
(shift-v) начинает линейное выделение. Независимо от типа выделения, y
зачеркивает в буфер вставки tmux (или X буфер обмена; смотрите комментарии к коду выше).
То же самое, что и в Vim.
Вот решение для пользователей macOS
- prefix+[, чтобы войти в режим копирования
- перейдите к началу или концу выделения текста с помощью стрелочных клавиш
- нажмите пробел, чтобы начать выделение, иногда control+space
- переместитесь к противоположному концe текста, чтобы скопировать с помощью стрелочных клавиш
- нажмите return, чтобы скопировать выделенный текст в
tmux
буфер обмена, иногда control+w или esc+w или alt+w - в той же сессии
tmux
вставьте с помощью prefix+], чтобы вставить вvim
, используйте prefix+] вvim
режиме вставки
ПРАВКА: После проверки исходного кода я полностью переписал свой ответ.
Я изначально думал, что это невозможно, потому что не мог заставить это работать, но другие ответы правы относительно v
как правильной клавиши для этого, но не очевидно, как это использовать, особенно если вы привыкли к vim.
Кроме того, это бы не работало для меня, потому что я привязал v
к begin-selection
– думаю, я, вероятно, слепо скопировал эту идею откуда-то еще, чтобы подражать способу vim начинать выбор по символам, не зная, что это вызовет проблемы с выбором блоков.
$ tmux -V
tmux 1.9a
$ tmux list-keys -t vi-copy | grep " v "
bind-key -t vi-copy v begin-selection # подавлял мой режим выбора блоков
Как только я убрал эту привязку (закомментировав строку в моем .tmux.conf
и перезапустив tmux), это начало работать, но это по-прежнему довольно запутанно, потому что это совсем не то же самое, что и в vim.
При стандартных привязках это должно работать следующим образом:
- Убедитесь, что у вас tmux работает с
setw -g mode-keys vi
в вашем.tmux.conf
. - наберите
C-a [
, чтобы начать режим копирования - переместите курсор к месту, где вы хотите начать выделение
- нажмите
v
- нажмите
Space
, чтобы начать выделение - переместите курсор, и вы увидите прямоугольное выделение
- вы можете снова нажать
v
, чтобы переключить выделение обратно в режим выбора по символам или наоборот.
Вам не нужно набирать v
перед тем, как нажимать Space
. Вы можете начать выбор поsymbol’ам с Space
сначала и нажать v
потом, чтобы переключиться в режим прямоугольного выделения.
Это довольно отличается от vim, так как в tmux вам нужно ввести два символа: Space
и v
, чтобы попасть в режим прямоугольного выделения. В vim вам нужно ввести только Ctrl-V
.
Также в vim v
начинает выбор по символам, а не по блокам.
К сожалению, в tmux, похоже, нет режима выбора по строкам (Shift-v
в vim).
ПРАВКА: Похоже, что версия Tmux 2.0 предоставляет режим выбора по строкам с Shift-v
(хотя я еще не пробовал!).
Поскольку все предложенные решения полагаются на привязки клавиш tmux в конфигурации, и поэтому требуется перезапуск всех активных сеансов tmux, есть “горячее” решение. Вы можете сделать прямоугольное выделение, не покидая tmux.
Как сделать прямоугольное выделение в tmux без перезапуска:
Я предполагаю, что ваша клавиша префикса — Ctrl+B.
Начните как обычно:
- Перейдите в режим копирования: Ctrl+B, затем [
- Переместите курсор к середине строки
Следующие шаги специфичны для прямоугольного выделения:
- Нажмите Ctrl+B, затем : (: может на самом деле быть Shift+;), чтобы ввести командную строку.
- Введите в зависимости от версии tmux (как упоминалось в ответе Эмира и нескольких других):
- tmux >= 2.4:
send -X rectangle-toggle
- tmux < 2.4:
rectangle-toggle
- tmux >= 2.4:
Затем нажмите Enter, чтобы выполнить команду. Строка командного ввода исчезнет.
Теперь продолжайте, как обычно:
- Нажмите Ctrl+Space
- Переместите выделение стрелками
- Скопируйте в буфер с помощью Alt+W
Команда rectangle-toggle
выполняется однократно, поэтому ваше следующее выделение останется полнострочным, если вы не вызовете rectangle-toggle
перед тем, как снова выбрать.
Я начал с этого ответа, но не был доволен, пока это не заработало точно как в vim:
set-option -g mode-keys vi
bind-key -T copy-mode-vi v {
if-shell -F "#{selection_present}" {
if-shell -F "#{rectangle_toggle}" {
send-keys -X rectangle-off
} {
send-keys -X clear-selection
}
} {
send-keys -X begin-selection
}
}
bind-key -T copy-mode-vi C-v {
if-shell -F "#{selection_present}" {
if-shell -F "#{rectangle_toggle}" {
send-keys -X clear-selection
} {
send-keys -X rectangle-on
}
} {
send-keys -X begin-selection
send-keys -X rectangle-on
}
}
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
Чтобы скопировать и зачеркивать точно так же, как это делает vim, я настроил tmux следующим образом
set-option -g mode-keys vi
bind-key -T copy-mode-vi 'v' send -X rectangle-off \; send -X begin-selection # Начать выделение в режиме копирования
bind-key -T copy-mode-vi 'C-v' send -X rectangle-on \; send -X begin-selection # Начать выделение в режиме копирования
bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel # Копировать выбор в режиме копирования
bind-key -T copy-mode-vi Escape {
if-shell -F "#{selection_present}" {
# true
send-keys -X clear-selection
} {
# false
send-keys -X cancel
}
}
Теперь Escape
также будет очищать выделение и выходить из режима копирования 🙂
ПРИМЕЧАНИЕ: некоторые ответы используют rectangle-toggle
неправильно. Это буквально переключает состояние, которое зависит от текущего состояния rectangle-toggle
, так как оно всегда устанавливает его в противоположное. Лучше явно указывать rectangle-on
или rectangle-off
. У меня были странные ситуации, когда другие команды меняли переключатель, и это вызывало противоположное поведение для выделений v
и C-v
.
Ответ или решение
Использование режима копирования tmux для выделения текстовых блоков
tmux – это мощный терминальный мультиплексор, который позволяет пользователям работать с множеством терминальных окон в одной сессии. При использовании tmux с vi-подобными клавиатурными сокращениями, многие пользователи сталкиваются с проблемой выделения текста, особенно если требуется выбрать блок текста, состоящий из нескольких строк, но не охватывающий всю ширину.
Проблема выделения текста в tmux
Выделяя текст в tmux с помощью стандартных конфигураций, можно легко выбрать одну строку или ограниченное количество строк, однако возникает проблема, когда требуется предоставить выбор текста именно в пределах одной панели или одного окна, не захватывая другие окна, что вызывает путаницу. Это аналогично режиму выделения в vim, где вы можете контролировать, что именно выделяете.
Решение проблемы
Для корректного выделения текстового блока в tmux с использованием клавиатурных сокращений vi, можно воспользоваться следующими шагами:
-
Вход в режим копирования:
- Нажмите
Ctrl
+A
(или другую настроенную вами клавишу префикса), а затем[
(открывающая квадратная скобка) для входа в режим копирования.
- Нажмите
-
Начало выделения:
- Переместите курсор на нужное место.
- Нажмите
v
для начала обычного выделения илиC-v
(Ctrl+V) для выделения в rectangular (прямоугольном) режиме.
-
Выбор текста:
- Для rectangular (прямоугольного) выделения: после нажатия
C-v
, нажмитеSpace
, чтобы начать выделение. Затем перемещайте курсор с помощью клавишh
,j
,k
,l
(или стрелочных клавиш) для увеличения выделенной области. - Для обычного выделения: просто переместите курсор после нажатия
v
.
- Для rectangular (прямоугольного) выделения: после нажатия
-
Копирование выделенного текста:
- После того как вы выделили нужный блок текста, нажмите
Enter
(илиy
, если у вас настроена соответствующая привязка) для копирования выделенного текста в буфер tmux.
- После того как вы выделили нужный блок текста, нажмите
-
Вставка скопированного текста:
- Вставьте скопированный текст в любое окно tmux, нажав
Ctrl
+A
, а затем]
.
- Вставьте скопированный текст в любое окно tmux, нажав
Настройки конфигурации tmux
Чтобы убедиться, что у вас есть все необходимые настройки для работы с режимом копирования, вам следует внести соответствующие изменения в файл конфигурации .tmux.conf
. Пример конфигурации:
set-window-option -g mode-keys vi
bind-key -T copy-mode-vi v send -X begin-selection
bind-key -T copy-mode-vi C-v send -X rectangle-toggle
bind-key -T copy-mode-vi y send -X copy-selection-and-cancel
Также важно отключить некоторые стандартные привязки, которые могут конфликтовать:
unbind-key -T copy-mode-vi v
Заключение
Выделение текстовых блоков в tmux может показаться сложным на первый взгляд, но следуя обозначенным шагам и адаптировав настройки конфигурации, вы сможете эффективно использовать этот инструмент для работы с текстом так же, как в vim. Используя сочетания клавиш и режимы выделения, вы получите полный контроль над выделением текста в пределах одной панели tmux, что значительно упростит работу с несколькими окнами и двигателями выполнения команд.