Иногда случается такое, что возможностей стандартного буфера обмена становится недостаточно для комфортного выполнения определенного рода задач. И это несмотря на то, что X сервер имеет в себе стандартно два буфера обмена. Один, который мы всегда используем, нажимая на CTRL+C/V, и второй, который заполняется сразу по факту выделения текста и доступен по нажатии средней кнопки мышки. Сегодня мы сделаем себе такой буфер обмена, который будет работать с последовательной «стопкой» данных, вызываемых по очереди.


Если ты ищешь готовое решение (программу менеджера буфера обмена) — обратись к статье:

Менеджер буфера обмена CopyQ в Ubuntu


В качестве вступления скажу напишу, что для работы сегодняшней моей задумки, тебе понадобится одно дополнительное приложение, не установленное в дистрибутиве по умолчанию. Это утилита xvkbd — виртуальная клавиатура для X, умеющая принимать коды клавиш для нажатия в качестве аргумента командной строки без запуска самой графической клавиатуры.

Установим xvkbd:

sudo apt-get install xvkbd

Отлично, а теперь напишем парочку скриптов на bash, которые в последствии повесим на горячие клавиши. Но сначала я расскажу о принципе работы данных скриптов. Идея в том, чтобы выделить текст, нажать один раз комбинацию клавиш получить в буфере обмена первое сохранение. Нажав второй раз с другим выделенным текстом эту же комбинацию — получить второе сохранение в буфер. Третье нажатие — третье сохранение и т.д. А потом, когда нужно вставить эти куски текста — нажимаем другую комбинацию клавиш и получаем последний скоприованный текст, далее предпоследний и т.д. пока «стопка» не опустеет. Выглядит это примерно так:

Копируем фразу «Привет всем от maddot.ru» по словам справа налево:

КопированиеТекст в буфере
1maddot.ru
2от
3всем
4Привет

Теперь при вставки текста последовательно и по одному будет вставляться каждый слой «стопки» с конца:

  • Привет
  • всем
  • от
  • maddot.ru

Итак, вернемся к написанию пары скриптов, а именно скрипт «копирования» и скрипт «вставки» (Можно и один с IF или CASE и аргументом командной строки, но это на твое, дорогой читатель, усмотрение).
Обрати внимание, что в скриптах у меня указан каталог ~/Tools/clip/ — именно в нем у меня и расположены данные скрипты, можешь расположить их так-же — это удобно, у меня для подобных целей ~/Tools и служит. Так же скрипт создает для своей работы файлы в этом же каталоге — значит у него должны быть права на запись в нем.

Первый скрипт «копирования», назовем его clip.sh :

#!/bin/bash

touch ~/Tools/clip/step.db
step=$(cat ~/Tools/clip/step.db)
[ ${#step} == 0 ] && echo 0 > ~/Tools/clip/step.db && step=0
thisStep=$(echo "1+$step" | bc)
touch ~/Tools/clip/$thisStep.clip
clip=$(xclip -o)
echo "$clip" > ~/Tools/clip/$thisStep.clip
echo $thisStep > ~/Tools/clip/step.db

Логика проста: «трогаем файл» сохранения порядковых номеров — если его нет, то он создастся. Записываем в него 0, если он только создан. Создаем файл с именем в виде порядкового номера слоя в стопке и пишем в него текущий выделенный текст. Повышаем порядковый номер в первом файле. В скрипте «вставки» логика такая же, но наоборот и вместо создания новых файлов будет происходить удаление «отработанных».

Второй скрипт «вставки», назовем его pase.sh :

#!/bin/bash

touch ~/Tools/clip/step.db
step=$(cat ~/Tools/clip/step.db)
[ ${#step} == 0 ] && echo 0 > ~/Tools/clip/step.db && exit
[ $step == 0 ] && exit
thisStep=$(echo "$step-1" | bc)
thisText=$(cat ~/Tools/clip/$step.clip)
echo "$thisText" | xclip -selection clipboard
rm ~/Tools/clip/$step.clip
echo $thisStep > ~/Tools/clip/step.db
xvkbd -xsendevent -text '\[Shift_L]\[Insert]'

xbkbd в данном случае нам понадобился, чтобы сымитировать нажатие Shift+Insert (вставка текста).

Почти все готово! Сохрани файлы скриптов каталог ~/Tools/clip:
~/Tools/clip/clip.sh
~/Tools/clip/pase.sh
И назнач на горячие клавиши их выполнение. Я назначил копирование на WIN+C (Meta+C/Super+C) а вставку на WIN+V (аналогично, толко с V) — получилось вполне удобно.
Назначить клавиши можно в настройках->клавиатура->Комбинации клавиш.

Добавление комбинации в Xubuntu: