bx программы

Я придумал несколько программ. Напишу их как-нибудь потом, пока что напишу про них вот в этой статье. В будущем, когда программы сделаю, эта статья будет служить документацией.

Ситуация

Всем же постоянно хочется настраивать свой компьютер в клавиатурном плане: хоткеи, макросы, раскладки. Лично мне компьютер только для этого и нужен: я пишу программы, которые упрощают создание клавиатур, которыми я создаю новые клавиатуры. Идеальная экосистема.

На стороне компьютера приходится настраивать хоткеи; как минимум в текстовом редакторе у меня есть несколько своих, а в оконном менеджере свои у меня все. Простые инструменты, отлично работающие между собой — то, что всем нужно. Вот есть такая программа: sxhkd, в ней можно простым синтаксисом описывать какие команды выполнять при определённых сочетаниях клавиш:

super + {h,j,k,l}
	bspc node -f {west,south,north,east}

Вот этот пример назначил 4 хоткея для навигации по окнам в оконном менеджере bspwm. Очень изящно (хотя я этой программой не пользуюсь :) ). Нужно больше такого.

Программы

Мне придумалось сразу четыре полезные программы. Все названия начинаются с bx, что значит bouncepaw x, где bouncepaw — это я, а x — это X11, графическая система, на которой работают почти все линуксы и прочие юниксы. Ещё есть Wayland, но я о нём не парюсь.

bxlisten

Это просто программа, которая слушает, какие кнопки нажимаются и отжимаются. Что-то типа xev (пример вывода ниже), но проще, только про клавиатуру и не требует запуска какого-то странного окна для слежки.

KeyRelease event, serial 47, synthetic NO, window 0x4400001,
    root 0x6a7, subw 0x0, time 33564969, (223,964), root:(252,965),
    state 0x0, keycode 28 (keysym 0x74, t), same_screen YES,
    XLookupString gives 1 bytes: (74) "t"
    XFilterEvent returns: False

bxlisten просто пишет то же самое, но на одно событие уходит всего одна строка, в которой значения разделены двоеточием (так принято много где).

33564969:T:down

Сначала идёт таймштамп, потом кикод, потом down, если кнопка была нажата, или up, если кнопка была отжата. С модификаторами поступает так же, к ним нет особого отношения:

34849544:Super_R:up

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

$ bxlisten > ~/log.csv

Внимание на расширение файла: .csv. Конечно! Все значения разделены одним и тем же знаком, поэтому подобный формат легко пропарсить любым языком. Даже приложения электронных таблиц умеют импортировать такие файлы.

Ну, это ладно. У программы ещё есть опции, меняющие поведение программы.

И всё. Если хочется уточнить результат, то надо использовать другие программы. Например, grep для фильтрации. Этот пример выведет только те записи, в которых кнопку отжали:

$ bxlisten | grep 'up'

А этот только первые 5 записей:

$ bxlisten | head -n 5

bxstalker

Эта программа ожидает на вход записи в формате как у bxlisten. Выводит же она нажатые хоткеи.

За хоткей считаем немодификатор и любое количество модификаторов, нажатые вместе. Нажатые вместе немодификаторы не являются хоткеем, мы это называем аккордом. bxstalker их примет за два хоткея. Кстати, нажатие немодификатора без модификаторов тоже вполне хоткей.

Ctrl+C, Shift+Alt+G, V — примеры хоткеев.

Формат вывода такой: сначала нажатый немодификатор, потом (через двоеточие, конечно) модификаторы. Как-то так:

T:Control_L:Shift_R

Поскольку требуется ввод от bxlisten, запускать надо так:

$ bxlisten | bxstalker

Программа будет выводить, пока не прервут. Но есть опция!:

По сути, эта программа — просто обёртка над bxlisten. Можно было даже её не делать, а встроить в bxlisten, но все программы в этой статье следуют философии юникса: программы должны делать что-то одно и делать это отлично. bxlisten отлично слушает клавиатурные события, а bxstalker отлично следит за нажатыми хоткеями.

bxexec

Эта программа вдохновлена текстовыми редакторами вимом и емаксом. Там есть такая фишка: можно сделать так, чтобы следующий хоткей нажимался несколько раз. Например, если в виме нажать цифру 3, а потом стрелочку вниз, то курсор сместится на три строчки вниз вместо одной. В емаксе аналогично, только надо нажать что-то типа Ctrl+U 3 Down или Ctrl+3 Down. Эта программа реализует аналогичный функционал.

На вход она получает хоткеи, которые надо исполнить, в формате, как у bxstalker. Вот так можно сделать так, чтобы следующий нажатый хоткей повторился (head -n 1 пускает дальше только одну строчку):

$ bxlisten | bxstalker | head -n 1 | bxexec

А вот указать, сколько раз в итоге хоткей должен быть нажат (bxexec нажмёт на один меньше, ведь один уже нажат пользователем), можно при помощи опции -n <n>:

$ bxlisten | bxstalker | head -n 1 | bxexec -n 3

И если нажать какой-нибудь хоткей, то он в итоге нажмётся три раза. Если опцию эту не указывать, то нажмётся два раза (-n 2 — стандартное значение).

А если хочется ввести кнопкой, сколько раз надо повторить? Тут на помощь придут те же самые программы. Достаточно сделать так:

$ bxlisten | bxstalker | head -n 1 | bxexec -n $(bxlisten | bxstalker | grep '^[01-9]' | head -n 1 | awk -F': '{print $1}')

Поскольку в шелле сначала исполнится то, что тут обёрнуто в $(), первый нажатый хоткей заберёт на себя первый bxlisten. grep '^[01-9]' пустит дальше только строки, начинающиеся с цифры (именно они и нужны), а awk -F':' '{print $1}' достанет нужную цифру.

Вот она сила!

А ведь хоткеи можно сохранять в файл, а потом уже исполнять:

$ bxlisten | bxstalker > hotkey.csv
$ cat hotkey.csv | bxexec

Логическое развитие этой мысли в следующей программе.

bxmacro

В виме и емаксе также есть макросы: последовательность хоткеев сохраняется, и можно её потом вызвать. Совместив с цифровым префиксом, как в прошлой секции, можно делать крутые штуки. Я вот часто таким пользуюсь.

Например, в емаксе Ctrl+x ( начнёт запись макроса, а Ctrl+x ) её завершит. Ctrl+x e исполнит последний записанный макрос. Вот такая последовательность удалит последний символ на следующих трёх строках:

Ctrl+x
(
Down
End
Backspace
Ctrl+x
)
Ctrl+u
3
Ctrl+x
e

Очень полезная штука, но работает только в рамках текстового редактора. bxmacro привносит этот функционал во все программы.

Так вот, за макрос считаем просто набор строк, на каждой написан хоткей в формате bxstalker (анонимный читатель должен был уже заметить, что он используется везде :) ). Этот набор хранится в файлах. bxmacro хранит их в директории $XDG_CONFIG_HOME/bxmacro/macros/<name>.csv. На большинстве компьютеров $XDG_CONFIG_HOME равняется ~/.config. А вот <name> — любое имя для макроса. Макросы спокойно лежат себе в файлах и останутся там, даже если перезагрузить макрос. Файл можно удалить, ещё можно записать пустой макрос.

Во время начала записи макроса можно указать имя. Если его не указать, то он сохранится во временном буфере под именем _.

$ bxmacro --record <name>
# а следующие два идентичные
$ bxmacro --record
$ bxmacro --record _

Все нажатия будут записываться в макрос, пока запись кто-нибудь не остановит так:

$ bxmacro --stop

А чтобы вызвать макрос, надо сделать так:

$ bxmacro --play <name> | bxexec
# а следующие два идентичные
$ bxmacro --play | bxexec
$ bxmacro --play _ | bxexec

Всё верно, программа для макросов не умеет их исполнять. И не должна! Она просто выводит содержимое файла с макросом.

Эту программу можно использовать для создания хоткеев, которые симулируют нажатие нескольких других хоткеев (в графическом редакторе пригодится, мне, по крайней мере), которые вводят шаблоны текста, да и много какие ещё. Фантазией не ограничено.

Заключение

Повторим изученное:

И всё это можно привязать к определённым хоткеям или кнопкам на панели задач! Возможностей много. А благодаря ограниченному функционалу программ этой коллекции, выучить их целиком проще простого.

Осталось только их написать :)