tmux режим копирования – выбрать текстовый блок

Вопрос или проблема

Я использую 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

  1. prefix+[, чтобы войти в режим копирования
  2. перейдите к началу или концу выделения текста с помощью стрелочных клавиш
  3. нажмите пробел, чтобы начать выделение, иногда control+space
  4. переместитесь к противоположному концe текста, чтобы скопировать с помощью стрелочных клавиш
  5. нажмите return, чтобы скопировать выделенный текст в tmux буфер обмена, иногда control+w или esc+w или alt+w
  6. в той же сессии 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.

При стандартных привязках это должно работать следующим образом:

  1. Убедитесь, что у вас tmux работает с setw -g mode-keys vi в вашем .tmux.conf.
  2. наберите C-a [, чтобы начать режим копирования
  3. переместите курсор к месту, где вы хотите начать выделение
  4. нажмите v
  5. нажмите Space, чтобы начать выделение
  6. переместите курсор, и вы увидите прямоугольное выделение
  7. вы можете снова нажать 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.

Начните как обычно:

  1. Перейдите в режим копирования: Ctrl+B, затем [
  2. Переместите курсор к середине строки

Следующие шаги специфичны для прямоугольного выделения:

  1. Нажмите Ctrl+B, затем : (: может на самом деле быть Shift+;), чтобы ввести командную строку.
  2. Введите в зависимости от версии tmux (как упоминалось в ответе Эмира и нескольких других):
    • tmux >= 2.4: send -X rectangle-toggle
    • tmux < 2.4: rectangle-toggle

Затем нажмите Enter, чтобы выполнить команду. Строка командного ввода исчезнет.

Теперь продолжайте, как обычно:

  1. Нажмите Ctrl+Space
  2. Переместите выделение стрелками
  3. Скопируйте в буфер с помощью 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, можно воспользоваться следующими шагами:

  1. Вход в режим копирования:

    • Нажмите Ctrl+A (или другую настроенную вами клавишу префикса), а затем [ (открывающая квадратная скобка) для входа в режим копирования.
  2. Начало выделения:

    • Переместите курсор на нужное место.
    • Нажмите v для начала обычного выделения или C-v (Ctrl+V) для выделения в rectangular (прямоугольном) режиме.
  3. Выбор текста:

    • Для rectangular (прямоугольного) выделения: после нажатия C-v, нажмите Space, чтобы начать выделение. Затем перемещайте курсор с помощью клавиш h, j, k, l (или стрелочных клавиш) для увеличения выделенной области.
    • Для обычного выделения: просто переместите курсор после нажатия v.
  4. Копирование выделенного текста:

    • После того как вы выделили нужный блок текста, нажмите Enter (или y, если у вас настроена соответствующая привязка) для копирования выделенного текста в буфер tmux.
  5. Вставка скопированного текста:

    • Вставьте скопированный текст в любое окно tmux, нажав Ctrl+A, а затем ].

Настройки конфигурации 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, что значительно упростит работу с несколькими окнами и двигателями выполнения команд.

Оцените материал
Добавить комментарий

Капча загружается...