Получение tmux для копирования буфера в буфер обмена


118

Я пытаюсь найти достойный способ скопировать то, что у меня есть в буфере tmux, в буфер обмена. Я пробовал пару разных вещей, как

bind-key p select-pane -t 2 \; split-window 'xsel -i -b' \; paste-buffer

что делает меня довольно близко, все, что мне нужно сделать, это нажать control-d после того, как я выполню префикс p.

Я пытался исправить это, делая

bind-key p select-pane -t 2 \; split-window 'xsel -i -b << HERE\; tmux paste-buffer\; echo HERE'

Но это просто не работает. На самом деле, если я соединю это до просто

bind-key p select-pane -t 2 \; split-window 'xsel -i -b << HERE'

он ничего не делает, поэтому я предполагаю, что split-window не нравится << в команде оболочки.

Есть идеи?

Изменить: Вы можете пропустить, select-pane -t 2если хотите, это не очень важно. Я просто использую конкретный макет, а панель 2 - это та, которую я предпочитаю разделять, когда я делаю что-то еще, чтобы по умолчанию в мои привязки включались разбиения.


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

Ответ, актуальный для Tmux 2.4 (выпущен в апреле 2017 г.) и 2.6, см. В моем ответе
Джейсон Аксельсон,

Ответы:


26

Здесь документы нужны новые строки. Например, в сценарии оболочки вы можете написать

cat <<EOF >somefile; echo  done
file contents
EOF

Я не думаю, что tmux позволяет вам размещать там новые строки, и даже если бы это было так, это не было бы хорошим подходом. Что, если сами данные содержатся в HEREодной строке (например, потому что вы копируете свою .tmux.conf)?

Я предлагаю записать содержимое буфера во временный файл. Непроверенные:

bind-key p save-buffer ~/.tmux-buffer \; run-shell "xsel -i -b <~/.tmux-buffer && rm ~/.tmux-buffer"

Если вы используете эту команду в двух отдельных экземплярах tmux, возникает условие гонки. Я не знаю, как это решить.


Спасибо, отлично работает, состояние гонки меня не беспокоит, я использую только 1 сеанс.
Digital Powers

Чтобы избежать состояния гонки, я бы предложил использовать тот, mktempкоторый широко доступен
Горе

@ Горе Хорошая идея. В этом случае использование PID процесса tmux также будет работать и, вероятно, будет проще в организации ( $PPIDв оболочке, запускаемой tmux). Но как вы получаете имя файла переменной (как бы оно ни создавалось) в аргумент save-buffer? Я думаю, save-buffer - | …как и в ответе Граувольфа , который вообще избавляется от временного файла?
Жиль

Вы правы, моя вина, это было бы невозможно.
Горе

93

Это должно работать:

# move x clipboard into tmux paste buffer
bind C-p run "tmux set-buffer \"$(xclip -o)\"; tmux paste-buffer"
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i"

1
Так оно и есть. Это намного приятнее, чем использование временного файла, спасибо. Он даже автоматически справляется с несколькими одновременными сеансами благодаря TMUXпеременным окружения.
Жиль

22
Лучшей инструкцией для этого C-pбудет: bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"- нет проблем с кавычками или командной строки.
Что

8
Есть ли у tmux ловушка для копирования выделения в буфер обмена copy-mode?
Ehtesh Choudhury

1
xclip -oопция не сработала для меня, поэтому я перешел наbind C-c run "tmux save-buffer - | xclip -selection c"\; display-message "Buffer copied to clipboard"
Pawka

6
Каждый раз, когда я делаю копию таким образом, tmux перестает отвечать на любые сочетания клавиш. Любое решение для этого?
скрат

41

Более простое решение для Mac OS-X

Это основывается на ответе Алекса и использует вещи, которых не было в то время.

Если вы используете homebrew (а если нет, то почему не так?), То вы можете просто сделать это:

brew install reattach-to-user-namespace

Тогда в вашем ~/.tmux.conf:

set-option -g default-command "reattach-to-user-namespace -l zsh" # or bash...
bind C-c run "tmux save-buffer - | reattach-to-user-namespace pbcopy"
bind C-v run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"

Чтобы скопировать буфер из tmux (вы уже должны были что-то скопировать с помощью tmux) в монтажную панель Mac, используйте <tmux-key> Control-c. Теперь он будет доступен для Command-vилиpbpaste

Чтобы вставить что-нибудь из Macboard, используйте <tmux-key> Control-v.


2
Этот ответ превосходен. Я использовал, tmux show-bufferкоторый вызвал проблемы tmux save-buffer -переноса строк, решил это.
event_jr

Что делает -в конце tmux save-buffer -делать?
Хекевинтран

Выдает на стандартный save-bufferвывод. Вы можете заменить -имя файла, и оно сохранит его там. Это мешает вам писать (и очищать) файл.
то

1
Начиная с OS X 10.10, присоединение к пространству имен больше не требуется. Практически в каждом руководстве и документации, касающейся tmux и OS X, упоминается об этом, потому что копирование и вставка не были легко возможны пару лет назад. В эти дни это (главным образом) работает из коробки.
Рафаэль Бугаевский

40

Команда copy-pipeбыла добавлена ​​начиная с версии 1.8. Он копирует выделение в буфер tmux и передает его команде. Теперь нет необходимости в привязке префикса. Вот пример:

bind -t vi-copy y copy-pipe "xclip"

# For OS X users:
bind -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

Теперь, когда у вас есть выделенный текст copy-mode, yскопируйте этот текст в буфер tmux, а также в буфер обмена ОС. Однако, это не поможет, если вы хотите получить текст из буфера обмена в буфер tmux.


1
Работает отлично и является самым простым решением из множества.
Насер

2
У меня не работает под Linux, но этот работает: unix.stackexchange.com/a/131074/13601
Себастьян Бласк

1
Начиная с OS X 10.10, это reattach-to-user-namespaceне является необходимым.
Крис

работает на Эль Капитане
olleh

2
Это больше не работает для Tmux 2.4, который был выпущен 20 апреля 2017 года. Вместо этого вам нужно использовать bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip"и для OS X:bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy"
Джейсон Аксельсон

16

Возможно, вы захотите попробовать плагин tmux-yank . Это позволяет копировать прямо в системный буфер обмена (OS X и Linux) и некоторые другие полезности, такие как восстановление текущей строки оболочки.


7
Это отличное, чистое решение, и его следует рассматривать больше, так как это гораздо более свежий ответ, чем другие. Спасибо, что поделился!
dmonopoly

9

После попытки другого решения, вот моя окончательная настройка:

# move x clipboard into tmux paste buffer
bind C-p run "xclip -o | tmux load-buffer -
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i -selection clipboard"

использование save-buffer вместо show-buffer дает реальные данные без данных, как показано с переносами строк, когда вы находитесь в разбиениях.

Я также использую это, чтобы начать выделение / копирование в режиме копирования tmux:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy 'y' copy-selection

Я предполагаю, что можно было бы объединить выделенную копию с клавишей 'y' и переместить ее в буфер обмена x.


Я пытался объединить обе команды, как вы упоминали, безуспешно. Есть идеи как это сделать?
Рафаэль Вега

9

Вот попытка дать исчерпывающий ответ.

Сначала немного истории

Когда этот вопрос впервые был задан (июнь 2011 г.), копирование текста из Tmux в буфер обмена должно было выполняться в два этапа: сначала скопируйте выделенный текст в буфер Tmux, а затем скопируйте текст из буфера Tmux в системный буфер обмена.

В версии 1.8 (март 2013 г.) copy-pipeбыла добавлена ​​команда, которая позволяет копировать выделенный текст прямо в системный буфер обмена (или в другое место назначения).

Затем в версии 2.4 (апрель 2017 г.) ключевые таблицы были значительно изменены, в результате чего многие ответы на этой странице устарели.

Отвечая на оригинальный вопрос

Linux :

bind-key C-y run-shell "tmux save-buffer - | xclip -i -r > /dev/null" \; display-message "Copied tmux buffer to selection"
bind-key C-Y run-shell "tmux save-buffer - | xclip -i -r -selection clipboard > /dev/null" \; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer"

Mac :

Если вы используете homebrew, вы должны установить reattach-to-user-namespace, выполнив следующую команду в терминале:

brew install reattach-to-user-namespace

Затем в вашем ~ / .tmux.conf:

bind-key C-y run-shell "tmux save-buffer - | reattach-to-user-namespace pbcopy" \; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "reattach-to-user-namespace pbpaste | tmux load-buffer - ; tmux paste-buffer"

Более короткий метод (скопируйте и вставьте выделение прямо из буфера обмена в tmux> 2.4 и обратно)

Примечание: есть две версии для Linux, потому что Linux имеет основной и дополнительный буфер обмена (также известный как выбор).

Linux :

bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip -r" \; display-message "Copied to selection"
bind-key -T copy-mode-vi Y send-keys -X copy-pipe "xclip -r -selection clipboard" \; display-message "Copied to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - && tmux paste-buffer"

Mac :

bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy" \; display-message "Copied to clipboard"

Настройка этих команд

  • Если вы не хотите, чтобы команда сообщала вам, что она сделала в строке состояния, просто удалите display-message(а также то, \;что стоит перед ней).

  • Если вы используете режим копирования в стиле Emacs вместо vi, замените любой экземпляр на copy-mode-viпростоcopy-mode

  • Если вы работаете в Linux , и вы хотите использовать xselвместо xclipзамены xclip -rс xsel -i -pи xclip -oсxsel -o -p

  • Значение -rin xclip -rявляется необязательным, оно удаляет последний символ новой строки. Это полезно для копирования команд, тогда, когда вы вставите их, они не будут немедленно выполнены.

  • Если вы туннелируете по SSH, вам следует обратиться к https://unix.stackexchange.com/a/354581/14252.

Рекомендации:


Эта команда bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer"все еще действует? дляtmux>2.4
alpha_989

7

Мне не нравятся дополнительные нажатия клавиш, поэтому я хотел что-то более амбициозное. Войдите в режим копирования с помощью [, выделите нужный текст, а затем нажмите], чтобы скопировать текст в буфер обмена.

Кроме того , tmux любит включать новые строки в выражениях , которые обруч (и как ни странно эти новые строки находятся в неправильном месте! Они не там , где выражение наматывается на экране). Поэтому я хотел, чтобы C-] скопировал выражение, удалив символы новой строки.

На tmux 1.6 я попробовал это:

bind [ copy-mode
bind -t vi-copy ] run "tmux send-keys Enter; tmux show-buffer | xclip -i -selection clipboard;"
bind -t vi-copy C-] run "tmux send-keys Enter; tmux show-buffer | perl -pe 's/\n//' | xclip -i -selection clipboard;"

но это не сработало, потому что tmux не рад связывать сложные вещи с таблицей vi-copy. Так что в итоге я сделал это вместо:

bind [ copy-mode \;                                                        \
    bind -n ] run                                                          \
    "tmux send-keys Enter;                                                 \
     tmux show-buffer | xclip -i -selection clipboard;                     \
     tmux unbind -n C-];                                                   \
     tmux unbind -n ]" \;                                                  \
    bind -n C-] run                                                        \
    "tmux send-keys Enter;                                                 \
     tmux show-buffer | perl -pe 's/\n//' | xclip -i -selection clipboard; \
     tmux unbind -n C-];                                                   \
     tmux unbind -n ]"

Это приводит к странным вещам (] или C-] будут забавными при следующем использовании, но только один раз), если вы выйдете из режима копирования другим способом, кроме] или C-]. Это можно исправить с помощью некоторых дополнительных привязок, которые я себе представляю, но это делает то, что я хочу большую часть времени.


stackoverflow.com/a/10954274/69663 отмечает, что есть связанный отчет об ошибке по ограничениям bind-key на sourceforge.net/tracker/…
unhammer

4

В Arch Wiki есть решение, использующее xclip:

# move tmux copy buffer into x clipboard
bind-key C-y save-buffer /tmp/tmux-buffer \; run-shell "cat /tmp/tmux-buffer | xclip"

https://wiki.archlinux.org/index.php/Tmux


2
Tmux безопасно создает save-bufferфайл в общем каталоге? В противном случае его вставка /tmp- это дыра в безопасности. Это бесполезное использование cat, и удаление временного файла отсутствует. Тогда это вопрос xselпротив xclip, которые здесь эквивалентны, и у вас есть мое (независимо написанное) решение.
Жиль

1
Спасибо, Жиль. Я обновлю вики, чтобы отразить ваши очки.
jasonwryan

4

Решение для Mac OS X. Выполните следующие 2 шага:

  1. Используйте обходной путь Криса Джонсена: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard

  2. Добавьте этот код в вашу конфигурацию tmux (~ / .tmux.conf)

# paste clipboard into tmux buffer
bind v run-shell "reattach-to-user-namespace -l zsh -c 'tmux set-buffer \\"$(pbpaste)\\"; tmux paste-buffer'"
# put tmux buffer into x clipboard
bind y run-shell "reattach-to-user-namespace -l zsh -c 'tmux show-buffer | pbcopy'"


4

Слегка измененный вариант принятого ответа, который я приготовил.

Я также предпочитаю использовать системный буфер обмена (Ctrl-C, Ctrl-V) в дополнение к primaryстандартному буферу обмена xclip (тот, который вы получаете при выборе мыши и средних щелчках мыши). Для выбора системного буфера обмена необходимо передать -selection clipboardаргумент xclip.

Также при копировании буфера в буфер обмена мне нравится возможность выбирать, какой буфер я хочу скопировать. Это делается с использованием choose-bufferи затем передачей буфера аргумента для save-bufferиспользования -b %%.

# Copy into clipboard
bind C-c choose-buffer "run \"tmux save-buffer -b %% - | xclip -i -selection clipboard\""
# Paste from clipboard
bind C-v run "xclip -o -selection clipboard | tmux load-buffer - ; tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run \"tmux save-buffer -b %% - | xclip -i \""
# Paste from primary
bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"

ОБНОВЛЕНИЕ: почему-то с tmux 1.8 и двумя моими установками openSUSE 12.2, я вижу зависание, когда tmux run-shellвызывается xclipчтение из stdin по каналу. Вместо этого я решил xselпопробовать, и это, кажется, работает. Это эквивалентные привязки клавиш xsel. Я также использовал &&для объединения команд в вставить для большей надежности.

# Copy into clipboard
bind C-c choose-buffer "run \"tmux save-buffer -b '%%' - | xsel -i -b\""
# Paste from clipboard
bind C-v run "xsel -o -b | tmux load-buffer - && tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run \"tmux save-buffer -b '%%' - | xsel -i\""
# Paste from primary
bind C-p run "xsel -o | tmux load-buffer - && tmux paste-buffer"

4

Это мой довольно длинный ответ, который должен решить две основные проблемы с использованием xclip для копирования буфера из удаленного (ssh) сеанса tmux:

1. Не отвечающий xclip

Для меня ответ @ Grauwolf с xclipне работал (делает tmux панель совершенно безразличным). Я узнал, почему на странице Tmux вики Arch :

xclip также может быть использован для этой цели, в отличие от xsel, он лучше работает при печати необработанных битовых потоков, которые не соответствуют текущей локали. Тем не менее, лучше использовать xsel вместо xclip, поскольку xclip не закрывает STDOUT после чтения из буфера tmux. Таким образом, tmux не знает, что задание копирования выполнено, и продолжает ждать завершения xclip, что делает tmux безразличным. Обходной путь - перенаправить STDOUT xclip в / dev / null.

Так что привязка должна быть:

bind-key C-y run "tmux save-buffer - | xclip -i -sel clip > /dev/null"

Теперь это будет работать, если ваша сессия tmux локальная.

2. xclip не может подключиться к X

Если вы используете tmux поверх ssh -X , есть большие шансы, что это не сработает напрямую.

Это потому, что переменная оболочки $DISPLAYдолжна быть установлена ​​правильно.

Комплексное решение

Так что для меня, полный рабочий раствор должен поместить следующие строки по моему ~/.tmux.conf:

set-option -g update-environment "DISPLAY"
bind-key C-y run "export DISPLAY=`tmux show-env | sed -n 's/^DISPLAY=//p'`; tmux save-buffer - | xclip -i -selection clipboard >/dev/null"
# Or more concise:
bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's/^DISPLAY=//p'` >/dev/null

Для вставки из предмета:

bind-key C-p run "xclip -d `tmux show-env | sed -n s/^DISPLAY=//p` -o | tmux load-buffer - && tmux paste-buffer"

Я не до конца понимаю, почему $DISPLAYне правильно установлен во время поиска .tmux.conf, поэтому я должен извлечь его с помощью tmux show-envи sed.

Если у вас tmux> = 1.8, вы можете адаптировать эту команду с помощью copy-pipe:

bind-key -t vi-copy y copy-pipe 'xclip -in -selection clipboard -d `tmux show-env | sed -n s/^DISPLAY=//p` >/dev/null'

/home/linux/.tmux.conf:11: invalid or unknown command: bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's[0/0] PLAY=//p'` >/dev/null
пользователь

@ Пользователь, который sedвы показываете, не тот, который я написал ... Это то, что вы написали в своей .tmux.conf?
PlasmaBinturong

Я просто скопировал и вставил ваш код.
пользователь

@ Пользователь, странно. Там может быть много источников ошибок. Сначала проверьте, что ваше цитирование в порядке. Тогда вы знакомы с sed? Команда должна быть: sed -n s/^DISPLAY=//p. В качестве альтернативы можно использовать cut: tmux show-env DISPLAY | cut -d'=' -f2. Также стоит проверить вашу версию tmux.
PlasmaBinturong

3

Я пытаюсь найти достойный способ скопировать то, что у меня есть в буфере tmux, в буфер обмена. Я пробовал пару разных вещей, как

Для привязок в стиле Emacs есть несколько разных опций. (Должен ли стиль Vi быть похожим?) Типичная привязка для выполнения «копирования-выбора» в emacs - это Mw, поэтому было бы очень удобно иметь такую ​​же привязку в tmux.

1 - было бы идеально, но не работает (из-за ограничения tmux?)

unbind-key -t emacs-copy M-w
bind-key -t emacs-copy M-w copy-selection\; \
  run-shell "tmux save-buffer - | xsel --input --clipboard"

2 - Компромисс, который хорошо работает для меня : согласитесь использовать другую привязку клавиш для emacs-copy в tmux. Используйте, например, CMw. (Это связывание, которое будет определено «глобально» - не только в режиме копирования - но и только в режиме копирования)

bind-key -n C-M-w send-keys M-w\; \
 run-shell "tmux save-buffer - | xsel --input --clipboard" 

3

Многие из этих ответов не сработали для моей Ubuntu 14.04 на zsh как есть. Не уверен, что моя оболочка как-то связана с этим, но вот моя рабочая версия использования этой стратегии для копирования и этой стратегии для вставки.

    bind-key -t vi-copy 'v' begin-selection
    bind-key -t vi-copy 'y' copy-pipe "xclip -sel clip -i"
    bind-key ] run-shell "xclip -sel clip -o | tmux load-buffer - ; tmux paste-buffer" 

Некоторые заметки:

  • для copy-pipe мне нужно было указать свой буфер обмена с помощью -sel clip -i. Эта строка объединяет буфер yank to tmux и отправляет его в xclip.
  • чтобы на самом деле вставить его, мне нужно было снова указать, какой буфер обмена с -sel clip -o

Теперь это прекрасно работает для моей установки vim / zsh / tmux.


благодарю вас! -sel clip -iрешает проблему. Хотя я не понимаю, зачем вам снова указывать буфер обмена, чтобы вставить его ( ]у меня стандартно работает)
melekes

1

И улучшенная версия ответа @Leif может быть:

tmux bind-key '[' run "tmux copy-mode;
tmux bind-key -n ']' run \"tmux send-keys Enter; tmux save-buffer - | xclip -i -selection clipboard;
tmux unbind-key -n ']'\";
tmux bind-key -n q run \"tmux unbind -n ']'; tmux send-keys q\";
tmux bind-key -n C-c run \"tmux unbind -n ']'; tmux send-keys C-c\""

Таким образом, не будет никаких последствий, если вы выйдете из режима копирования другим способом, кроме], приведенный выше код обернут в tundle / tmux-yank плагин tmux для копирования текста tmux в системный буфер обмена, он нацелен на tmux> = 1.6 в OS X и Linux.


1

На OS-X с версией 2.2 tmux или позже будет работать следующее:

bind-key -t emacs-copy MouseDragEnd1Pane copy-pipe "pbcopy"
bind-key -t vi-copy MouseDragEnd1Pane copy-pipe "pbcopy"

1

Я использую copyqмногострочный менеджер буфера обмена. (Работает с Windows, OSX, Linux.)

  • Добавьте следующие строки в ~/.tmux.conf:

    set-window-option -g mode-keys vi
    bind C-y run 'out=`tmux save-buffer - ` && copyq add "$out"'
    
  • cygwinтребует copyq.exeразмещения в ~/.bashrc:

    export PATH="$PATH:/cygdrive/c/Program Files (x86)/CopyQ"
    
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.