xbindkeys – сочетания в стиле emacs
В связи с тем, что в последнее время очень часто приходиться менять оконный менеджер в связи с различными экспериментами, захотелось немного унифицировать свою систему клавиатурных комбинаций. А точнее – сделать ее отдельной от самого оконного менеджера.
По сути, проблема решилась быстро, достаточно было только установить xbindkeys и настроить в нем нужные сочетания клавиш. Тем самым получаем одни и те же комбинации везде, где только можно, включая обычный twm.
Но захотелось большего! Обычные сочетания клавиш очень ограничены, даже если использовать разные модификаторы. Ограничены потому что большинство комбинаций уже используется в различных программах и потому, что различные операции приходиться использовать на одних и тех же модификаторах.
На мой взгляд, лучше всего данную проблему решает emacs, с его двойными/тройными комбинациями. Начиная, к примеру комбинацию с C-x, мы по сути указываем на использование системной функции (утрирую). А последующее сочетание уже говорит, что конкретно нужно сделать. Таким образом мы получаем просто потрясающее количество клавиатурных комбинаций, которые к тому же проще запоминать, так как есть определенная логика.
Естественно, задумался, как можно организовать подобное в xbindkeys. Где то уже встречал информацию о том, что это возможно. Только вот где? В итоге нашел. Все оказалось довольно просто. Файл конфигурации xbindkeys может быть описан двумя способами: в виде обычного текстового файла и на языке lisp (диалект guile). Вот как раз с помощью guile то все это дело и осуществляется.
Определяются три функции: first-binding, в которой определяются основные одиночные сочетания и присутствует вызов второй функции second-binding, которая отвечает за вторые комбинации в последовательности. Так же необходима функция reset-first-binding для переключения используемых режимов.
Текст моего конфига ~/.xbindkeysrc.scm:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start of xbindkeys guile configuration ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; List of modifier:
;; Release, Control, Shift, Mod1 (Alt), Mod2 (NumLock),
;; Mod3 (CapsLock), Mod4, Mod5 (Scroll).
(define (first-binding)
"First binding"
(xbindkey '(XF86Calculator) "emacsclient -c -a \"\"")
(xbindkey '(Mod1 F2) "dmenu_run")
(xbindkey '(Mod4 F2) "dmenu_run")
(xbindkey '(Print) "scrot -q 10")
(xbindkey '(Mod1 Print) "scrot -q 10 -s")
(xbindkey '(XF86Sleep) "/home/juev/.scripts/off")
(xbindkey '(XF86AudioLowerVolume) "amixer -q set Master 5- unmute")
(xbindkey '(XF86AudioRaiseVolume) "amixer -q set Master 5+ unmute")
(xbindkey '(XF86AudioMute) "amixer -q sset Master toggle")
(xbindkey '(XF86AudioPrev) "mpc prev")
(xbindkey '(XF86AudioPlay) "mpc toggle")
(xbindkey '(XF86AudioNext) "mpc next")
(xbindkey-function '(Mod4 a) second-binding))
(define (reset-first-binding)
"reset first binding"
(ungrab-all-keys)
(remove-all-keys)
(first-binding)
(grab-all-keys))
(define (second-binding)
"Second binding"
(ungrab-all-keys)
(remove-all-keys)
(xbindkey-function 'f
(lambda ()
(run-command "firefox")
(reset-first-binding)))
(xbindkey-function 'c
(lambda ()
(run-command "conkeror")
(reset-first-binding)))
(xbindkey-function 'g
(lambda ()
(run-command "gcalctool")
(reset-first-binding)))
(xbindkey-function 't
(lambda ()
(run-command "thunar")
(reset-first-binding)))
(xbindkey-function 'k
(lambda ()
(run-command "keepassx")
(reset-first-binding)))
(xbindkey-function 'e
(lambda ()
(run-command "emacsclient -c -a \"\"")
(reset-first-binding)))
(xbindkey-function '(control g) reset-first-binding)
(grab-all-keys))
(first-binding)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; End of xbindkeys guile configuration ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Подробно расписывать, как тут и что задается, я не буду, по сути все понятно из текста. И формат вызова функций и прописывание самих комбинаций. Хочу только остановиться на том, какие комбинации тут используются для составных клавиатурных сочетаний.
В функции first-binding прописываются все сочетания, которые будут действовать от однократного нажатия, например, нажатие на Mod4+F2 вызывает программу dmenu_run. Нажатие на Mod4+a вызывает функцию second-binding, в которой прописываются дополнительные сочетания. К примеру нажатие на Mod4+a f запускает огнелис. Если нажимаем на Mod4+a, xbindkeys начинает воспринимать только те комбинации, что прописаны в функции second-binding. Если нужно вернуться к базовому функционалу без использования программ описанных в данной функции, жмем C-g.
Я выбрал комбинацию Mod4+a, потому что она была не занята. Первоначально прописал C-t, как это используется в некоторых менеджерах окон, но столкнулся с тем, что нужно было еще прописывать функцию для передачи сочетания C-t активной программе. Проще оказалось сменить используемую комбинацию.

Вот спасибо, я видел лисповый конфиг когда на жуйке спрашивал о такого рода сочетаниях в xbindkeys. но почему-то не подумал что его надо в ~/.xbindkeysrc.scm а не в ~/.xbindkeysrc =) соответсвенно он у мну не заработал (хотя мож тупо ошибся в конфиге), дальше и ковырять не стал.
Ну теперь, надеюсь, будет без проблем?
вот теперь я решил проблему запуска часто запускаемых программ ! =)
Рад помочь!
Давно перевёл биндинги на WM-независимые благодаря xbindkeys. Но кнопок уже мало осталось, а тут оказывается можно и так сделать!
Спасибо за статью!
А, быть может, Вы знаете какой-нибудь способ перенести эти сочетания на еще более низкий уровень? Или хотябы только поменять назначения клавиш… Например, я для эргономии поменял левые капс и контрол местами, а так же справа капс и энтер(в качестве последнего всегда используется ctrl+j) и сделал много чего еще… Ко всему хорошему всегда быстро привыкаешь и когда приходится работать без иксов отсутсвие этих модификаций вызывает сильный дискомфорт…
Более низкий уровень в иксах – это использование WM, который умеет использовать данные сочетания. Другого способа пока не знаю. А вот поменять местами назначения клавиш, если интересует случай с xorg, то смотрите в сторону xmodmap, тут можно сделать все что угодно и как вам угодно. Если интересует как поменять местами клавиши в консоли, то тут только поможет создание собственной раскладки, это чуть сложнее и менее документировано, чем xmodmap, но вполне осуществимо. Я уже делал собственную раскладку, в которой в консоли вместо капса используется контрол…
xmodmap, настройки своего оконного менеджера – это все я умею, проблема возникает только «когда приходится работать без иксов», создавать свою раскладку – это вариант, хотя и не лучший, но я уже за него взялся. Но все же он не позволит привязывать клавиши и пр… На данный момент, как выход. я в консоли сразу запускаю exec emacs -execute «(shell)»
, но это тоже не то, потому что постоянно обнаруживаются какие-инбудь недостатки этого подхода и раздражающие различия в работе с иксами и без…
Ну тогда просто не знаю, чем еще можно помочь…
А не подскажете, что Вы использовали при создании собственной раскладки работающей в консоли? В иксах, я так понимаю она так же работала?
Консоль и иксы – это разные вещи, раскладка заданная в консоли не работает в иксах и наоборот. По созданию раскладки я описывал здесь
С Вашим примером я, похоже, разобрался, спасибо. А между ними и драйвером нет никакого механизма? Просто это как то не очень хорошо , получается, что в фундаментальной вещи заведомо нужно проделать в два раза больше работы для получения единого результата, при этом при измененни одной раскладки нужн править и другую… Кстати дял консоли Вы знаете какой-нибудь аналог xev для консоли, то утилитак которая выводит подробную инфу о нажатии клавиш т.е. код, имся и пр.?
сори за опечатки…
Насколько я понимаю никакого механизма не предусмотрено. Да, приходиться проводить двойную работу, чтобы сделать единообразно. Увы…
Аналог xev?? Если все правильно помню, что showkey, запущенная с разными параметрами показывает сканкод клавиши…
ок, спасибо
Спасибо за статью, нашел ее для себя полезной. Меня заинтересовало две вещи.
Как определить функции для создания множества префиксов, а не только одного
как это в вашем примере. И второй вопрос, можно ли таким образом биндить
более сложные сочетания аккордов для нажатий, и как этого добиться от
xbindkeys?
Все просто:
Можно конечно и более сложные забиндить, просто вам нужно понять, как задается вложенность в xbindkeys, и от этого уже писать свой конфиг.
Здравствуйте. Пишу свой конфиг по вашему примеру. У меня не выходит. xbindkeys ругаетсяна ошибку, а как их, допущеные ошибки, находить не знаю Поэтому с тем как и вкакой последовательности вкладывать функции у меня четкого представления непоявилось. Будьте добры рассказать о составлении конфига по подробней.
Я думаю для решения вашей проблемы нам будет проще с вами связаться напрямую.
Чуть позже я буду онлайн в jabber или если вам будет так удобнее, отпишусь в почту.