Отримання 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'

він нічого не робить, тому я припускаю, що розділене вікно не любить << в команді оболонки.

Якісь ідеї?

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


2
Не забудьте переглянути нижченаведену відповідь 2014 року, яка є нещодавнішою, ніж деякі інші. Він рекомендує плагін tmux yank, який працює дуже добре.
dmonopoly

Для відповіді, що є актуальною для Tmux 2.4 (вийшов у квітні 2017 року) та 2.6 див. Мою відповідь
Jason Axelson

Відповіді:


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широко доступну інформацію
горе

@Grief Хороша ідея. У цьому випадку використання 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 перестає реагувати на будь-які комбінації клавіш. Будь-яке рішення для цього?
skrat

41

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

Це формує відповідь Алекса і використовує речі, які тоді не існували.

Якщо ви користуєтеся домашньою мовою (а якщо ні, то чому б ні?), Ви можете просто зробити це:

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

Щоб вставити щось з картону Mac, використовуйте <tmux-key> Control-v.


2
Ця відповідь чудова. Я використовував, tmux show-bufferякі викликали проблеми із загортанням рядків, tmux save-buffer -вирішили це
event_jr

Що робить -в кінці tmux save-buffer -?
hekevintran

Випромінює у save-bufferвідкладення. Ви можете замінити -ім'я файлу, і воно збережеться там. Це заважає писати (і чистити) файл.
док

1
З ОС 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
Працює чудово і є найпростішим рішенням згустку.
Naseer

2
Не працює для мене під Linux, однак це робить: unix.stackexchange.com/a/131074/13601
Себастьян

1
Що стосується ОС X 10.10, вона, здається reattach-to-user-namespace, не є необхідною.
Кріс

працює на el capitan
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"
Jason Axelson

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"

використання буфера збереження замість буфера шоу дає реальні дані без даних, як показано з розривами рядків, коли ви знаходитесь у розбиттях.

Я також використовую це для початку вибору / копіювання в режимі копіювання 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

  • -rВ 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/…
відключити

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, і видалення тимчасового файлу відсутнє. Тоді це питання щодо xselvs 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
користувач

@user sedкоманда, яку ви показуєте, не збігається з тією, яку я написав ... Це те, що ви написали у своєму .tmux.conf?
ПлазмаБінтуронг

Я просто скопіював і вставив ваш код.
користувач

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

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 з tmux версії 2.2 або новішої версії буде працювати наступне:

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.