Предлагаю легкий и простой вариант решения этой проблемы. Так как самый лучший язык программирования это python, это единственное что я как-то знаю, то будем его использовать.
Итого — нужно перехватить данные из буфера обмена при нажатии «ctrl+v», проверить наличие "\n" и дальше опять «вызвать» «ctrl+v». Делать проверку буфера для всех прикладных программ не совсем логично, и например в gnome-terminal «Paste» назначен по умолчанию на «Shift+Ctrl+V», то я заменил это на «Ctrl+V». Дальше нужно на привычную комбинацию «Shift+Ctrl+V» поставить проверку буфера.
Существует много вариантов это сделать, которые зависят от используемого рабочего окружения. Конкретно в моем случае это
~/.config/openbox/rc.xml
<keyboard> <keybind key="S-C-v"> <action name="Execute"> <command>/home/user/scripts/safe_paste.py</command> </action> </keybind> </keyboard>
Нужно не забыть chmod +x /home/user/scripts/safe_paste.py.
/home/user/scripts/safe_paste.py
#!/usr/bin/env python from paste_it import main main()
/home/user/scripts/paste_it.py
#!/usr/bin/env python import os from subprocess import Popen, PIPE def main(): # берем текущие значение буффера, через вызов xsel sys_exec = Popen('xsel', stdout=PIPE) stdout = sys_exec.stdout.read() #если количество строк в буфера не равно 1, то сообщим об это этом if len(stdout.splitlines()) != 1: n_detected = Popen('notify-send "\\n detected"', shell=True) return False #самое интересно, об этом чуть ниже codes = map(ord, stdout) for code in codes: if code <= 31 or code == 127: bad_code_detected = Popen('notify-send "bad code detected"', shell=True) return False paste = Popen('%s/pasteit &' % os.path.dirname(__file__), shell=True) return stdout if __name__ == '__main__': main()
Разбиение кода на 2 файла даст небольшой прирост производительности, конечно же и можно сразу назначать paste_it.py.
Кроме "\n" к нам в буфер может попасть www.asciitable.com, а именно 0-31 и 127, которые тоже могут вызвать неожиданное поведение терминала, следовательно об это нужно проинформировать.
Дальше надо вызвать «crtl+v» для вставки безопасного текста. Ну а если содержание не безопасно то тут открыть текстовый редактор\выбросить некоторые символы\автоматом убрать "\n", тут уже кому как удобнее, реализация тоже будет не сложной. Лично для меня достаточно знать что я задел при выделении что-то лишние.
Способов вызвать «ctrl+v» из под линукса найдено было много:
- xdotool — на взгляд замечательная вещь — в Centos 6.3 в репах нет, собрать не получилось
- xvkbd — собирается imake’ом (Imake is a deprecated source code configuration and build system), но не собралось
- python-uinput — из пушки по воробьям, эмуляция устройства, hal правило
- python-virtkey — так же не собралось
- xautomation — было в репах, но очень древние и работало ужасно, и залипало ctrl
- под виндовс есть autohotkey, autoit, pywin32
Надо писать самому.
На с\с++ погулив я забил, так как с пол пинка не выйдет.
Было реализовано очень компактное решение на java:
PasteIt.java
import java.awt.AWTException; import java.awt.Robot; import java.awt.event.KeyEvent; public class PasteIt{ public static void main(String[] args) { try { Robot robot = new Robot(); robot.keyPress(KeyEvent.VK_CONTROL); robot.keyPress(KeyEvent.VK_V); robot.delay(20); robot.keyRelease(KeyEvent.VK_V); robot.keyRelease(KeyEvent.VK_CONTROL); } catch (AWTException e) { e.printStackTrace(); } } }
javac PasteIt.java
На не совсем новом ноутбуке вызов этого класса занимал 1-2 сек, было очень не комфортно, но работало.
GCJ выглядит заброшенным, но
gcj -O2 —main=PasteIt PasteIt.java
и был создан бинарник a.out, который я переименовал в pasteit и он работает 0.1 сек.
Теперь я как обычно нажимаю «ctrl+shift+v», и если в буфере что-то не подходящие, то я получу уведомление, так же я могу использовать «ctrl+v» если мне нужно вставить данные без проверки.
Решение получилось не наилучшие, тянущие за собой кучу технологий, но код получился очень компактный и понятный, что легко позволит каждому подстроить всё под себя. Работоспособность получилась вполне нормальная.
Заменив xsel на решения с stackoverflow.com, с помощью mingw так же можно использовать GCJ, но я не совсем уверен в надобности всего этого для использования в powershell\cmd, но для putty может будет полезно.
ссылка на оригинал статьи http://habrahabr.ru/post/165317/
Добавить комментарий