Important
Haka has become more than just a notes utility it used to be.
Those features are now shipped as plugins by default.
Haka is a lightweight, fast, pluggable automation tool. It is designed to
run quietly in the background as a system-service.
Written completely in C for performance, but it does not* require
you to write your plugins entirely in C. It is dynamic and hot-reloadable!
Dependencies
build.sh
includes the installation of all the dependencies, but only for arch and debian
based distros. For any other distribution, kindly install the aforementioned
dependencies. Or simply use the based
Makefile
From your favourite terminal, execute the build.sh script for installation
chmod +x build.sh
./build.shTo access the input group and access the event devices using libevdev,
one needs root privileges. Although running haka as the root user has many
issues, the most critiacl being the current user session, including the
primary clipboard, is not available when running as root.
To resolve this issue, we use the
capabilities(7)
to grant haka the permission to change its group ID to input. Now
haka can run as a user process and still be able to access the evdev.
Credit for this workaround goes to this blog.
Note
build.sh handles this implicitly. If you used build.sh to build haka, this has been performed already.
sudo setcap "cap_setgid=eip" ./haka.out
./haka.out # no sudo required while runningIf you want to use haka as a new-style systemd
daemon to run in the background, use
daemon.sh to
generate the unit file for systemd.
daemon.sh creates the unit file required to run as a --user daemon and it
creates a symlink of the unit file to ~/.config/systemd/user/
Note
Make sure to execute daemon.sh from the directory containing
haka.out. If you renamed the executable, edit the HAKA variable in
daemon.sh
chmod +x daemon.sh
./daemon.shCheck logs:
journalctl --user -u haka.service -fConfig file for haka must be named
haka.cfg
which must be present in the same directory as the haka executable. The haka
config parser allows you to use command substitution for configuration
values. For example, you can specify the editor dynamically using:
editor=$(which emacs)The below config options are described with respect to the markdown plugin.
| Option | Value | Description |
|---|---|---|
| editor | /path/to/editor/bin | Specify the editor to open files in |
| terminal | /path/to/terminal/bin | Specify the terminal to open editor in |
| notes-dir | /path/to/notes/dir | Custom path to notes dir |
| tofi-cfg | /path/to/tofi/cfg | Custom path for tofi.cfg file |
| plugins | /path/to/plugins/dir/ | Custom path for plugins dir |
- Haka comes with a
deafultplugin andmarkdownplugin (haka exclusively used to be a notes utility). - The files displayed in the selection menu is the
notes/directory and can be found in the directory containing haka executable - The
editorby default inneovim hakacurrently supports the first 249KEY_NAMEdefined inlinux/input-event-codes.h- If a key is binded to
NULL, that key would be implicitly binded to reload plugins - The defualt
ActivationComboisLeft Ctr+Left Alt - The default activation combo is set in the
src/binds.c:setActivationCombo_. - In case of a
KEY_binded to multiple functions, the first plugin to bind it would be executed. - There are 3 log levels:
-DLOG=0: No logs-DLOG=1: Info logs (ILOG)-DLOG=2: Debug logs (DLOG+ILOG) default
- Default
ActivationComboisLEFT_CTRL + LEFT_ALT
plugins/default.c
| Key | Action |
|---|---|
KEY_R |
Reload plugins |
KEY_C |
Append selected text to current file |
KEY_M |
Display tofi selection menu |
KEY_O |
Open current file in editor |
KEY_F |
Format(wrap) current file content (using neovim) |
KEY_J |
Open journalctl of haka in terminal (if running as daemon) |
plugins/markdown/plugin.c
| Key | Action |
|---|---|
KEY_1 to KEY_4 |
Append selected text as Hn heading to current file |
KEY_A |
Append selected text as unordered list to current file |
KEY_S |
Append selected text as unordered list depth 2 to current file |
KEY_N |
Append newline(\n) to current file |
- The only way to add New custom keybinds is to make plugins. This might sound tedious but is simple.
- By default, haka comes with some plugins. You can see them in plugins/ directory.
A very basic example to extend a plugin (Assuming haka is already running). In plugins/default.c, add this function:
static void hello_world(hakaCtx* ctx) {
printf("Hello World!\n");
}And under the BEGIN_BIND ... END_BIND section of the file, register your function by adding this
line:
Bind(hello_world, KEY_H);Thats it! We have made a new keybind! now, compile the file, in plugins/ directory run:
makeNow press your ActivationCombo(by deafault its LEFT_ALT + LEFT_CTRL) + R
to reload the plugins and then press ActivationCombo + H and you can see
"Hello World!" printed on the terminal!
- A plugin is just a shared object (
.so) inside theplugins/directory or the directory specified in the config file. - A function must be of the prototype:
void func(hakaCtx *ctx)to beBindable. Referlinux/input-event-codes.hforKEY_NAMEmacros.
Boilerplate for plugin:
#include "plug.h" // Can be found in include/
coreApi *api;
/*
Your functions go here
*/
BEGIN_BIND
/*
Register your functions to keys here
*/
END_BINDYou can use the api ptr to call core feature functions and extract data from within the ctx.
Compiling the plugin
- Ensure that plugin is compiled using:
-fPIC -sharedflags
-
If some processes do not work/launch, this is usually because at the time of booting, required env variables were not set. This is a known issue.
systemctl --user restart hakashould be done after booting. -
If noo keybind is working, the issue is most probably with
keyd.keydandhakacannot run simultaneously. This is becausekeydgrabs the input devies, thus leavinghakato poll the input devices indefinitely.killing thekeydprocess should resolve the issue.
Confirmkeydis running:pgrep keyd.
To kill all procs with keyd:sudo killall keyd
- This architecture makes sense
- Instead use
prefix key(?) (multiple benefits of switching tbh) - Warning for Multiple binds on a single key (Or maybe allow multiple binds?)
- Static core.c
- Log levels
- Switch to gtk(?): to reduce dependencies. (bloat tho)
- Add a config file option for vars.
- Ignore newlines in selection(?)
- Improve bindings implementation
This project was inspired out of personal disgust to <C-c> <C-v>