Pull to refresh

Небольшой лайфхак с редактированием буфера обмена

VIM *Emacs *
Я часто сталкиваюсь с такой ситуацией: пишу себе спокойно текст в чем-то (скажем, письмо в веб-интерфейсе гмейла), и вдруг, в какой-то момент возникает необходимость что-то переделать… и случается раздражение. Случается оно от того что редактирование в браузере (да и много где еще) не предполагает некоторых привычных для программиста удобств, вроде автоматической замены, регулярных выражений и макросов. При этом, вроде бы и не сложно скопировать текст в буфер и отредактировать его в правильном редакторе (Vim, Emacs, ...), но очень уж не хочется отрываться от контекста и совершать какие-то телодвижения, отвлекающие от текущей задачи… И вот, я уже расставляю отступы (нумерую список, заменяю слово, ...) вручную — результат достигнут, да и времени потрачено совсем не много, но осадочек остался…

Знакомая ситуация? Если ответ «да», в вашей операционной системе работает bash и ваша первая ассоциация к слову «редактор» это не «Microsoft Office» значит нам есть что обсудить под катом :)


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

Самый очевидный путь решения этой задачи — просто автоматизировать ту часть последовательности действий, которая без изменений повторяется из раза в раз. У нас таких последовательностей целых две: одна в начале перехода во внешний редактор — выделить, скопировать в буфер, открыть внешний редактор, вставить; вторая в конце — скопировать в буфер отредактированное, закрыть внешний редактор, вставить текст на старое место.

Но для начала, в связи с тем что мы собираемся автоматизировать работу с буфером обмена…

Несколько замечаний о буфере обмена в X Window System.


(Вначале я упомянул что сгодится любая система в которой работает bash, и это правда. Так что, если у вас мак и особенности X Window System вам параллельны — смело пропускайте эту часть)

Во-первых, помните что клипбоард в X Window реализован очень специфично. У нас есть как минимум 3 буфера обмена — primary, secondary и собственно clipboard. В primary попадает все что вы выделите мышью, и «выпадает» по нажатию средней кнопки мыши, clipboard — это как правило Ctrl-V / Ctrl-C. Зачем нужен secondary не знает никто.

(Ходят слухи, что, на самом деле, X Windows настолько крута, что в ней вообще может быть сколько угодно буферов обмена, и secondary — всего лишь еще один из бесконечного ряда. Я затрудняюсь даже предположить зачем это нужно.)

Во-вторых, полезно понимать, что в каждый момент времени содержимое буфера обмена привязано к окну из которого оно было извлечено. Наверняка, эта привязка открывает много замечательных возможностей, но все они, на мой взгляд, сводятся на нет одним отвратительным неудобством: содержимое клипбоарда исчезает если закрыть программу из которой оно было скопировано.

С учетом этих особенностей, для стабильной и предсказуемой работы с буфером обмена в линуксе я очень рекомендую пользоваться каким-нибудь «клипбоард менеджером». В состав KDE входит вполне юзабельный klipper, а пользователям Гнома я бы посоветовал утилитку parcellite (народ еще хвалит diodon, особенно те у кого Ubuntu + Unity, но я сам не пробовал). Каким бы менеджером вы не пользовались, очень полезно привыкнуть вызывать историю буфера обмена по нажатию Ctrl-Alt-C или другого сочетания клавиш. Да, и кстати, будьте осторожны с опцией «синхронизовать клипбоарды» — после ее включения, любое выделение текста будет «затирать» текущее содержимое буфера обмена, даже если вы осознанно и явно туда что-то добавили с помощью Ctrl-C.

Собственно, рецепт


Итак, для достижения наших целей нам потребуются: (1) средство, позволяющее глобально привязать выполнение произвольной команды к нажатию волшебной кнопки и (2) небольшой скриптик собственного сочинения.

Что касается привязки к клавиатурным событиям — решений множество, но я не вижу причин не воспользоваться средствами встроенными в систему (и KDE и Gnome предлагают свои редакторы «быстрых клавиш»).

Сам же скрипт, к которому мы будем привязывать событие может выглядеть так:
  1. #!/bin/bash
  2. tmp="$(mktemp)"  # создать временный файл
  3. xclip -sel clip -o > "$tmp"  # скопировать содержимое клипбоарда в созданный файл
  4. gvim -f  "$tmp"  # открыть файл в нужном редакторе (gvim - в качестве примера)
  5. cat "$tmp" | xclip -sel clip  # скопировать содержимое файла обратно в клипбоард
  6. rm "$tmp"  # удалить временный файл
При этом, выбор конкретных утилит, конечно, может отличаться. Например, не только xclip умеет работать с буфером обмена из командной строки — вместо xclip можно использовать утилиту xsel либо менеджер клипбоарда, а если у вас мак и OS X, то там есть команды pbcopy / pbpaste.

Теперь дело за малым — сохранаяем скрипт в ~/bin/editclip, привязываем его к нажатию на F12 (или любому другому сочетанию клавиш) — готово! Мы можем в любой момент, в любом «левом» редакторе выделить нужный фрагмент, нажать «Ctrl-C, F12» и фрагмент откроется в нужной программе, после закрытия которой, достаточно будет нажать Ctrl-V и отредактированный текст встанет на место.

На последок еще один небольшой совет касательно X Window. К сожалению, выделение текста не является здесь внутренним делом программы. Если вы выделили текст в одном окне, а потом переключились в другое и выделили текст снова, то в исходном окне выделение может слететь (upd: а может и не слететь — в комментариях подсказывают что этому эффекту особенно подвержены проги на gtk). Это очень неприятно, потому что нам приходится либо, редактируя текст во внешнем редакторе, всячески избегать выделения (что противоестественно), либо смириться с тем что простое нажатие Ctrl-V в конце не всегда будет заменять старый фрагмент на отредактированный.

Чтобы обойти это неудобство, я, обычно вызываю внешний редактор с помощью «Ctrl-X, F12» — при этом исходный фрагмент текста сразу удаляется и нажатие Ctrl-V в финале вставляет на его место отредактированную версию.

Вот и все. Надеюсь этот трюк пригодится кому-нибудь.
Tags:
Hubs:
Total votes 63: ↑57 and ↓6 +51
Views 10K
Comments Comments 28