A trick of my dmenu setup: a custom $PATH

December 17, 2022

Dmenu is hard to describe. It's often called a 'dynamic menu'; at a technical level it's a pop up text entry widget with autocompletion (with what it autocompletes taken from standard input) that prints your entered (or autocompleted) text to standard output. I've been using dmenu for quite a while and as part of that I've built an elaborate setup around it. One of the things my dmenu does is run commands, and part of my setup is that I invoke commands with a custom $PATH with a collection of directories that are only used for dmenu.

(This element of my setup has been there from the beginning.)

What I put in these custom $PATH directories is a collection of little programs, often with extremely short names. Effectively, these create abbreviations for commonly used things. For example, one such program is called 'g'; it uses Firefox remote control to open a Firefox window that's doing a web search on whatever command line arguments it was invoked with. These command line arguments come from whatever else I typed in dmenu, so I can type 'g dmenu arch wiki' and have a Firefox window open with the results you'd expect. Another little program is called 'pd', and uses Firefox remote control to open a window on the Python website's page for a given package in the standard library (eg 'pd time').

(A significant number of these small programs use Firefox remote control to open Firefox windows on various URLs, because it turns out that visiting various sorts of URLs is something I do a lot.)

My various custom $PATH directories are separated by both their purpose and their visibility in dmenu's initial list of completions (having dmenu completions that aren't initially visible is a personal feature I added that turned out to be quite useful). Because these directories aren't in my normal $PATH, I can load them up with very short names that might cause problems in normal shell usage (or clash with real commands that are only a few letters long), I can use names that I wouldn't want to be commands normally, and I can 'reframe' regular commands to be run with special arguments or special argument handling that makes them more useful in the context of dmenu.

(I can also create short aliases for commands, if I want to.)

One of the things I don't do as often as I should is go through all of these special dmenu $PATH directories to weed out things I'm not using any more (and things that I thought I'd use when I created them but I was totally wrong). In practice, a lot of my clever ideas for short things have turned out to not get used.

Special directories with custom scripts in them isn't the only way to implement this sort of thing. Dmenu needs a wrapper script to do things with its output, so you could put the intelligence into the wrapper script (and my dmenu wrapper has a certain amount of that). However, I've found it easier to modify this sort of abbreviation by adding, removing, or changing a little script than by always editing my dmenu wrapper script.

Comments on this page:

From at 2022-12-18 03:37:51:

Hmm, that's a method I didn't think about – I used to have a few aliases in dmenu, but they were implemented within the dmenu_run wrapper script, altering $input before passing it to shell to be run.

Though I don't use dmenu in the "standard" horizontal mode where it offers all commands from $PATH – I've found it much more useful to have it as a vertical drop-down that keeps a full command history sorted by frecency, and to rely on dmenu's fuzzy search to find things like wireshark -ki wlan0 -f "port 37008". (If I tried to create aliases for every one of those, that'd be a lot of aliases.)

By cks at 2022-12-18 19:31:29:

I use dmenu horizontally (across the bottom of my screen), but I never put everything in my $PATH in it, partly because a lot of commands just won't work when run outside a terminal. Instead what appears in my dmenu is theoretically a carefully curated set of things I want to be visible or at least autocompletion targets (which is another entry I have to write).

By Simon at 2022-12-19 06:51:40:

Does your script first resolve the command with your special $PATH and then execute the resolved command with your normal $PATH or do all the things invoked via dmenu inherit the special $PATH?

(Sorry if this is obvious to dmenu users. I don't use dmenu but I have a setup that sounds somewhat similar and there this would be a problem with your approach)

By cks at 2022-12-19 09:46:28:

My script currently uses the brute force approach of adding the special directories to the front of my $PATH, using 'which $cmd' to see if something is executable, and running the command with the new $PATH. On the one hand this means special scripts can find each other and run each other with argument changes; on the other hand, this does mean that everything inherits that $PATH and makes things a bit messier. Fortunately I don't start local terminals through dmenu or I might have hit issues with this sooner.

Written on 17 December 2022.
« A practical issue with YAML: your schema is not actually documentation
My dmenu wrapper script and what it will invoke for me »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sat Dec 17 22:42:24 2022
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.