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 hashes)

Uploaded Source

Built Distribution

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

Uploaded Python 3

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