Wk
wk - Which-Key via X11 and Wayland, inspired by dmenu and bemenu respectively.
Install / Use
/learn @3L0C/WkREADME

wk
wk - Which-Key via X11 and Wayland.
Displays available key chords in a popup window.
Inspired by
emacs-which-key,
dmenu, and
bemenu.
Introduction
wk offers users a portable, scriptable, and highly
customizable interface for their key chord mappings through
a number of sources. Key chords can be built into the binary
via the key_chords.def.h header,
read from a wks file, or read from stdin with
the same wks syntax.
Video Demos
As you can tell from the length of this README, there is a
lot to go over. If you would prefer a video demo, you can
check out the demo series
here
where I cover wk basics and beyond.
Building
Make
# Make wk for X11 and Wayland (uses default or existing key chords)
make
# Build from wks file (transpile config/key_chords.wks and rebuild)
# This is a three-stage bootstrapping process:
# 1. Build wk with bootstrap key chords
# 2. Transpile key_chords.wks using the built binary
# 3. Rebuild wk with the transpiled key chords
make from-wks
# Make wk for X11 only
make x11
# Make wk for Wayland only
make wayland
# Build from wks file for X11 only
make from-wks-x11
# Build from wks file for Wayland only
make from-wks-wayland
# Install
make clean && make && sudo make install
# Install with custom key chords from wks file
make clean && make from-wks && sudo make install
Nix
See INSTALL-NIX.md for detailed Nix/NixOS/Home Manager installation instructions.
Dependencies
- C compiler
- scdoc to generate man pages (optional)
All runtime dependencies below are searched with
pkg-config.
| Backend | Dependencies | |---------|---------------------------------------------------------------| | Common | cairo, pango, pangocairo | | X11 | x11, xinerama | | Wayland | wayland-client, wayland-protocols, xkbcommon, wlr-layer-shell |
About Wayland support
Wayland is only supported by compositors that implement the
wlr-layer-shell
protocol. Typically
wlroots-based
compositors. For those not on a wlroots-based compositor,
Xwayland
does work based on my testing, but the popup menu seems to
only display on one screen.
See here for notes about common compositor quirks (e.g., mouse click behavior differences, etc.).
Usage
# Display built-in key chords.
wk
# Display menu at the top of the screen.
wk --top
# Display key chords in a `wks` file.
wk --key-chords my_key_chords.wks
# Try to pre-press keys 'C-c', and 'x'.
wk --press 'C-c x'
# Transpile the key chords in a `wks` file and print a properly
# formated `config.h` header to stdout.
wk --transpile my_key_chords.wks
# Read script from stdin
printf '%s\n' 'a "Chord" %{{echo "Hello, world!"}}' | wk --script
# Everything else
wk --help
usage: wk [options]
options:
-h, --help Display help message and exit.
-v, --version Display version number and exit.
-d, --debug Print debug information.
-D, --delay INT Delay the popup menu by INT milliseconds from
startup/last keypress (default 1000 ms).
-t, --top Position menu at top of screen.
-b, --bottom Position menu at bottom of screen.
-s, --script Read script from stdin to use as key chords.
-U, --unsorted Disable sorting of key chords (sorted by default).
-m, --max-columns INT Set the maximum menu columns to INT (defualt 5).
-p, --press KEY(s) Press KEY(s) before dispalying menu.
-T, --transpile FILE Transpile FILE to valid 'key_chords.h' syntax and
print to stdout.
-k, --key-chords FILE Use FILE for key chords rather than those
precompiled.
-w, --menu-width INT Set menu width to INT. Set to '-1' for a width
equal to 1/2 of the screen width (default -1)
-g, --menu-gap INT Set menu gap between top/bottom of screen to INT.
Set to '-1' for a gap equal to 1/10th of the
screen height (default -1).
--wrap-cmd STRING Wrap all commands with STRING, i.e.,
/bin/sh -c STRING cmd
This does not apply to hooks (default "").
--border-width INT Set border width to INT (default 4).
--border-radius NUM Set border radius to NUM degrees. 0 means no curve
(default 0).
--wpadding INT Set left and right padding around hint text to
INT (default 6).
--hpadding INT Set top and bottom padding around hint text to
INT (default 2).
--table-padding INT Set additional padding between the outermost cells
and the border to INT. -1 = same as cell padding,
0 = no additional padding (default -1).
--fg COLOR Set all menu foreground text to COLOR where color
is some hex string i.e. '#F1CD39' (default unset).
--fg-key COLOR Set foreground key to COLOR (default '#DCD7BA').
--fg-delimiter COLOR Set foreground delimiter to COLOR (default '#525259').
--fg-prefix COLOR Set foreground prefix to COLOR (default '#AF9FC9').
--fg-chord COLOR Set foreground chord to COLOR (default '#DCD7BA').
--fg-title COLOR Set foreground title to COLOR (default '#DCD7BA').
--fg-goto COLOR Set foreground goto to COLOR (default '#E6C384').
--title STRING Set global title displayed above menu to STRING.
--title-font STRING Set title font to STRING. Should be a valid Pango
font description (default 'sans-serif, 16').
--bg COLOR Set background to COLOR (default '#181616').
--bd COLOR Set border to COLOR (default '#7FB4CA').
--shell STRING Set shell to STRING (default '/bin/sh').
--font STRING Set font to STRING. Should be a valid Pango font
description (default 'monospace, 14').
--implicit-keys STRING Set implicit keys to STRING (default 'asdfghjkl;').
run `man 1 wk` for more info on each option.
Mouse and Touch Support
wk is a keyboard driven tool. While wk provides a
graphical menu with available key chords, users cannot
click/touch the menu to select any of the items. Any click,
scroll, or touch (untested) on the menu will cause it to
close.
Wayland has some quirks when it comes to clicking/scrolling outside the menu. You can read more about this here.
Configuration
wk can be configured at runtime or your settings and key
chords can be built into the binary.
Runtime
Configure wk at the command line as shown above, or use
preprocessor macros in a wks file
passed to --key-chords, --transpile, or --script. For
example, define your configuration in ~/.config/wk/main.wks
and bind Super+Comma in your window manager to run
wk --key-chords ~/.config/wk/main.wks.
Built-in
You can build your configuration into the wk binary by
placing it in config/key_chords.wks and running
make from-wks && sudo make install. The result is
equivalent to running wk --key-chords config/key_chords.wks
but without the runtime parsing overhead.
Tradeoffs
Runtime configuration allows fast iteration. Built-in configuration is faster at startup and suits stable setups. Start with runtime, then switch to built-in once your configuration stabilizes or startup time becomes noticeable.
wks Files
Which-Key source (wks) files are the driving force behind
wk. The syntax is novel but provides a flexible means to
manage and express key chords.
Comments
In wks files, comments can be added using the pound
character (#). When a pound character is encountered, it
signifies the start of a comment. The comment extends from
the pound character until the end of the line. It's
important to note that the pound character is treated as a
literal character within descriptions and commands and does
not indicate the start of a comment in those contexts.
Key Chords
key_chord -> ( chord | prefix | chord_array ) ;
The key chord is the main building block of a wks file.
This can be either a chord, prefix, or a chord array.
The chord is the most basic example of a key chord and
serves as a good entry point for this discussion.
Chords
A chord is a key chord that results in wk performing some
action, like executing a command, when the trigger key is
pressed.
chord -> trigger_key description keyword* command ;
All chords must have a trigger key, description, and a command. Zero or more keywords may be given between the description and command. These will be addressed later. For now, let's break down the required parts of the chord.
Trigger Keys
A trigger key represents the specific keypress or key
combination that triggers a corresponding action or command.
In a wks file, it is the written representation of the
physical key(s) pressed by the user on their keyboard.
trigger_k
