Три года назад хабраюзер imitsuran (Андрей Сурнин) опубликовал забавный пост Исправление раскладки клавиатуры а-ля Punto Switcher на bash и в нем полезный скрипт для тех, кто не хочет связываться с программами-аналогами Punto Switcher (Xneur и т.п.).
Скрипт успешно работал в Росинке-9 (читай: в Gnome 2 и с bash-4.1), а потом, в системах с Mate/Cinnamon (c bash-4.2 и 4.3), перестал.
Недавно, подчищая свою директорию ~/.bin, включенную в PATH, от накопившегося за несколько лет хлама, я вспомнил об этом скрипте и решил посмотреть, нельзя ли его починить, поскольку мой метод "слепой печати" в точности такой, как описал Андрей, необходимые для скрипта утилиты мне и без того нужны, и с Xneur я тоже связываться не хочу.
Починка оказалась очень простой: в строке
if [ "$(xsel)" = "" || "$(xsel)" = " " ]; then exit 1; fi
нужно одинарные квадратные скобки заменить на двойные:
if [[ "$(xsel)" = "" || "$(xsel)" = " " ]]; then exit 1; fi
и скрипт заработает.
Поправленный вариант скрипта, подробно прокомментированный (в основном использованы комментарии Андрея Сурнина), я приведу ниже, под спойлером, а сейчас еще одно замечание.
Note: Комбинация Alt + q у меня оказалась конфликтной (подозреваю, что "виноват" Diodon) и в некоторых ситуациях приводила не к изменению раскладки, а к замене выделенного на текущее содержимое буфера обмена. Я не стал париться, а просто заменил ее на Alt + z, которая, к счастью, оказалась свободной в основных гуишных редакторах-печаталках, и к тому же удобной.
Поэтому в ~/.xbindkeysrc было записано
# Изменяем раскладку выделенного текста:
"~/.bin/punto.sh"
alt + z
а всё остальное закомментировано.
Скрипт показать
#!/bin/bash
##################################
# punto.sh
# Скрипт Андрея Сурнина отсюда: http://habrahabr.ru/blogs/shells/120502/
# "Исправление раскладки клавиатуры а-ля Punto Switcher на bash"
# Поправлено в мае 2014
# требуются xsel, xvkbd и xbindkeys.
#################################
if [[ "$(xsel)" = "" || "$(xsel)" = " " ]]; then exit 1; fi # прервет выполнение скрипта, если ничего не выделено или выделен пробел.
BOOFER=$(xsel -b) # заносит в переменную «BOOFER» результат работы команды xsel -b.
xsel | sed "y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ[]{};':",./<>?@#$^&`~фисвуапршолдьтщзйкыегмцчняФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯхъХЪжэЖЭбюБЮ№ёЁ/фисвуапршолдьтщзйкыегмцчняФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯхъХЪжэЖЭбю.БЮ,"№;:?ёЁabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ[]{};':",.<>#`~/" | xsel -b -i
# xsel берет выделенный текст и передает его по конвейеру потоковому текстовому редактору sed. Именно он и производит замену символов.
# Команда y (sed "y/abcdef...) заменяет символ из первого шаблона на соответствующий ему символ из
# второго шаблона(sed «y/abcdefg.../фисвуап...; sed „y/abcdefg.../фисвуап...). Результат работы sed'а передается все той же утилите xsel, но теперь с опциями -b и -i.
# Мы уже знаем что опция -b указывает, что работать надо с буфером клавиатуры, а вот опция -i говорит утилите, что этот буфер нужно переписать.
# Таким образом наш исправленный текст попадает в буфер обмена.
#Теперь исправленный текст нам нужно вставить вместо исходного варианта, в этом нам поможет xvkbd. Это виртуальная клавиатура
# для X Window System, xvkbd также может отправлять символы, переданные в качестве аргумента командной строки, в другие приложения.
xvkbd -xsendevent -text "[Control_L][v]"
# Этой командой мы имитируем нажатие Ctrl+V, то есть вставляем содержимое буфера обмена вместо выделенного текста.
# И теперь остается только вернуть в буфер обмена то, что было там до нашего вмешательства.
echo -n "$BOOFER" | xsel -b -i
# Теперь нужно назначить для скрипта хоткей. Я выбрал сочетание клавиш Alt+Z, вы можете назначить любое другое. Хоткей я назначал с помощью xbindkeys.
# Открываем в домашней директории файл .xbindkeysrc и добавляем в него следующие строки:
# "/путь/к/скрипту.sh"
# alt + z
# Сохраняем, выполняем в консоли:
# xbindkeys
# Все, теперь можно исправлять раскладку текста выделив его и нажав Alt+z.