Skip to main content

Which key via dmenu.

Project description

wkd

Which-key via dmenu, wkd.

Why?

  • I like keychords
  • I like which-key
  • I like dmenu

If you like these things too then you may like wkd.

Demo

Simple usage of wkd

Usage of wkd -p KEY

Disclaimer

The version of dmenu that I am using is heavily patched to provide the functionality shown.

Worry not, I provide copies to the individual patches that I am using. There are is also a README with some more info about each patch.

Install

The usual way:

pip install wkd

Requires python3.

Getting started

wkd is what you make it. So lets see how you can configure it.

wkdrc

Here are the following configuration settings, a description of what they do, and their default values:

# "prompt_cmd" is the program to use to display the availible binds. This
# setting supports fzf, or rofi instead of dmenu but you'll have to experiment
# with those. If you do please let me know how it goes and how I can better
# support usage of wkd with those programs.
prompt_cmd = dmenu

# Default args to use when running your prompt_cmd. This supports any arg
# that your version of dmenu supports.
bind_args = None

# Separator between your keybind and the description. A space will get added on
# each side between the key and description.
separator = ->

# If shell is True then your keybind will execute in a shell. Becareful if you
# set this to True.
shell = False

# You can create pretty intricate binds for wkd, but if you perfer multiple
# smaller binds/keys files you can set which dir wkd should look for input/output
# files here. The full path for these defaults would be $XDG_CONFIG_HOME/wkd/binds
# for the binds_dir.
binds_dir = binds
keys_dir  = keys

# If you have the grid patch applied to dmenu you can specify the number of columns
# to show. If a value is set then wkd will calculate the needed lines to show all the
# binds at a given level. This is mostly aesthetic but it makes a big difference imo
# as dmenu fills in a column with options before moving to the next column instead of
# filling in all columns in a line and moving to the next line.
columns = 0

bindsrc

The bindsrc file is the default source when updating your keybinds. The syntax for this file is fairly simple but it is not (to my knowledge) common so let's go over it!

Top level keybinds

The following is a top level keybind:

# This is a comment, nothing new.
k This is a description == echo "Everything past == is a command."

When you run wkd and press k the command will run.

Some things to note:

  • White space only matters between the keybind and the description.
  • The keybind can only be a single key.
  • wkd will fail to parse bindsrc if the keybind is not a single key.
  • Everything past the first == is treated a command.

Prefixes

Top level keybinds are nice but they really aren't much different than a normal keybind. A prefix is a keybind that contains more keybinds/prefixes. Prefixes are a great thing, let's cover them:

# The next line is a prefix
p No command allowed
    :s Sub keybind == echo "Notice the colon."
    # The next line is another prefix
    :i Inner prefix
        ::t A keybind! == echo "We reached the end."

Things to note:

  • A prefix has no command, just a keybind and a description.
  • The : is not just for looks.
  • If a keybind/prefix is n number of prefixes deep, then n colons are required for that keybind/prefix.

And that's pretty much it. Let's look at how this translates to a keys.json file.

The result

You can run wkd -u to update your keys.json file from your bindsrc file. Side note, the default bindsrc file is located at $XDG_CONFIG_HOME/wkd along with the resulting keys.json file.

Let's say this is your bindsrc file:

# Browsers prefix
b Browsers
    :f Firefox == firefox
    # Profiles prefix
    :F Firefox profiles
        ::f Focus == firefox -P Focus
        ::l Learning == firefox -P Learning
        ::e Entertainment == firefox -P Entertainment
    # Sites prefix
    :s Sites
        ::m My site == firefox "https://www.my-site.org"
        ::o Other site == firefox "https://www.my-other-site.org"
# emacs prefix
e Emacs
    :e Open emacs == emacs
    # Projects prefix
    :p Projects
        ::m My project == emacs "~/Projects/My Project"
        ::o Other project == emacs "~/Projects/My Other Project"
# mpv prefix
m mpv
    :m My music == mpv "~/Music/my_playlist.m3u"
    :e Empty mpv == mpv --idle=yes

After running wkd -u your keys.json file will look like this:

{
    "b -> Browsers": {
        "f -> Firefox": "firefox",
        "F -> Firefox profiles": {
            "f -> Focus": "firefox -P Focus",
            "l -> Learning": "firefox -P Learning",
            "e -> Entertainment": "firefox -P Entertainment"
        },
        "s -> Sites": {
            "m -> My site": "firefox \"https://www.my-site.org\"",
            "o -> Other site": "firefox \"https://www.my-other-site.org\""
        }
    },
    "e -> Emacs": {
        "e -> Open emacs": "emacs",
        "p -> Projects": {
            "m -> My project": "emacs \"~/Projects/My Project\"",
            "o -> Other project": "emacs \"~/Projects/My Other Project\""
        }
    },
    "m -> mpv": {
        "m -> My music": "mpv \"~/Music/my_playlist.m3u\"",
        "e -> Empty mpv": "mpv --idle=yes"
    }
}

The keys.json file is what is used when running wkd so you can pick your poison.

I prefer to set my keybinds through the bindsrc file as I can add comments and I find it easier to work with.

Usage

Here is the help page for wkd:

usage: wkd [-h] [-d] [-i FILE] [-o FILE] [-p KEYs] [-r FILE | -u]

Which-key via dmenu.

options:
  -h, --help            show this help message and exit
  -d, --debug           Instead of (re)writing your keys.json when updating prints to screen.
  -i FILE, --input FILE
                        Can be used with --update to read a different bindsrc file.
  -o FILE, --output FILE
                        Can be used with --update to output to a different keys.json file.
  -p KEY(s), --press KEY(s)
                        Effectively presses KEY(s) after launching.
  -r FILE, --read FILE  Read an alternate keys.json file. If FILE is a relative path wkd assumes
                        it is in the $XDG_CONFIG_HOME/wkd/keys directory.
  -u, --update          Update keybinds using bindsrc. See --input and --output for additional
                        options.

dmenu

So far wkd has really only been tested with dmenu. However, it works very, very well with dmenu. Please read the README in the dmenu/patches directory in this repo for recommended configuration of dmenu.

Thanks for reading

Hope you like wkd, I sure do.

There are some pretty cool things you can do with it, let me know what you come up with or what you think could be improved!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wkd-0.0.2.tar.gz (22.7 kB view details)

Uploaded Source

Built Distribution

wkd-0.0.2-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file wkd-0.0.2.tar.gz.

File metadata

  • Download URL: wkd-0.0.2.tar.gz
  • Upload date:
  • Size: 22.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.7

File hashes

Hashes for wkd-0.0.2.tar.gz
Algorithm Hash digest
SHA256 98113cc5634112558782e528256e6a7591e29ad7a5dd7f85f54ab30051ce9387
MD5 debb08b9bf4b2cd007038cdf0d4888b6
BLAKE2b-256 8cfd295e2b54b2829477bcb624935c5e16bcebe53799404e2999e5a7e9a49d3c

See more details on using hashes here.

File details

Details for the file wkd-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: wkd-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.7

File hashes

Hashes for wkd-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 308b700668bef20279130ebaa4db82532734a68afc8d1ae1f58d3c0b2dae38a8
MD5 373d0517028bc1c195467295cc655930
BLAKE2b-256 d141df153ea1f0345ad8381f5831c1c7d4893c9fb14b8ac4312aa84caceb8527

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page