Dmenu script for keyboard layout selection

In this video I talk about Dmenu and its usage. I also walk you thru the creation of a simple shell script for keyboard layout selection. The full modified script is in the bottom of the description, using test for sorting out “cancel”

Dmenu homepage at Suckless

Dylanarapas pure SH bible

Full script:

#!/bin/sh
# Tiny script for selecting keyboard layout while in X
rtrim (){
 printf '%s\n' "${1%%$2}"
}

# declare delimiter
delimiter=" -"

# declare languages
languages="se - Swedish\nus - English\nCancel"

# Sending languages to Dmenu
selected=$(echo "$languages" | dmenu)

if test "$selected" != "Cancel" ;then
# Trimming
trimmed="$(rtrim $selected $delimiter)"
setxkbmap $trimmed
fi

Transcript (English)

Hello YouTube, this is Cristian Herrera. A small update about dmenu. This morning I was on the Swedish corner of the web, saw a question about a good keyboard layout selector, and suggested a shell script with dmenu and setxkbmap.

I haven’t coded for many years and I hate coding with the Swedish layout—it’s horrible—so I’ve always switched to the US layout when coding. I’m rusty, but I want to get back into the habit. I prefer POSIX sh over Bash so it works everywhere and avoids bashisms.

dmenu is a suckless tool (link above). It’s used by other projects like pass and clipmenu. Example with clipmenu: visual-select, yank, then pick from the clipboard history without line numbers. dmenu just takes a newline-delimited list and returns your selection: printf "bananas\napples\noranges\n" | dmenu gives a three-line menu and returns the choice.

For this script I kept it POSIX: no arrays, simple strings, tried to avoid sed/awk. I found Dylan Araps’ Pure sh Bible with handy functions like rtrim. Command substitution is needed to capture the trimmed string.

Shell debugging tip: run sh -x languages.sh. My script sets a delimiter, defines languages="se - Swedish\nus - English\nCancel", pipes to dmenu, trims the selection, and calls setxkbmap. Pick us to get a coding-friendly layout; run again and pick se to go back.

The script isn’t perfect—I used a case, so adding layouts means adding cases. Better: test for “Cancel” and otherwise apply whatever was chosen, so new layouts only need to be added in the list. Easy to extend with Russian, Spanish, etc. I’ll refine it later.

If you find this useful, like/subscribe/comment—it helps motivation. Feel free to ask for explainer videos (e.g., HTTP protocol). Have a great Easter even in tough times. Bye!

comments powered by Disqus