spmenu is a program for X11 that reads standard input and allows the user to select items separated by a newline. It is a fork of suckless’s dmenu which is a good more minimal alternative to spmenu.
What makes spmenu different from all the dmenu forks is that spmenu has features like color support, Vim-like modes, image support, proper mouse/keybind configuration, and more.
It should be noted that most of these features may be disabled by the user, either during compile time or through configuration.
On runtime, spmenu reads from standard input (stdin). spmenu items
are separated by a newline (\n
). When (by default) Enter is
pressed, the selected item will be piped to stdout.
This allows things like
printf "Apple\nOrange\nPear\n" | spmenu
. This command will
spawn an spmenu window with three items, ‘Apple’, ‘Orange’ and ‘Pear’.
This can be used in shell scripts to create interactive menus.
On top of this, you can specify arguments to change the behavior of spmenu. See a list below for a list.
You may use long, descriptive arguments or the shorter arguments.
-mh, --line-height height
-mw, --min-width width
-g, --columns grid
-gc, --generate-cache
-ngc, --no-generate-cache
-mc, --max-cache size
-rw, --relative-width
-nrw, --no-relative-width
-f, --fast
-F, --fuzzy
-NF, --no-fuzzy
-P, --password
-nP, --no-password
-p, --prompt text
-It, --input text
-ip, --indent
-nip, --no-indent
-ci, --color-items
-nci, --no-color-items
-sgr, --sgr
-nsgr, --no-sgr
-a, --alpha
-na, --no-alpha
-tp, --allow-typing
-nt, --no-allow-typing
-x, --x-position x offset
-y, --y-position y offset
-n, --preselect line
-z, --width width
-nmt, --normal-mode-text text
-imt, --insert-mode-text text
-clon, --caps-lock-on-text text
-clof, --caps-lock-off-text text
-bw, --border-width width
-so, --sort
-nso, --no-sort
-pri, --priority pri1,pri2,pri3
-s, --case-sensitive
-ns, --case-insensitive
-nm, --normal
-im, --insert
-t, --top
-b, --bottom
-c, --center
-hm, --hide-mode
-hit, --hide-item
-hmc, --hide-match-count
-hla, --hide-left-arrow
-hra, --hide-right-arrow
-hpr, --hide-prompt
-hip, --hide-input
-hpl, --hide-powerline
-hc, --hide-caret, --hide-cursor
-hhl, --hide-highlighting
-hi, --hide-image
-hcl, --hide-caps
-sm, --show-mode
-sit, --show-item
-smc, --show-match-count
-sla, --show-left-arrow
-sra, --show-right-arrow
-spr, --show-prompt
-sin, --show-input
-spl, --show-powerline
-sc, --show-caret, --show-cursor
-shl, --show-highlighting
-si, --show-image
-scl, --show-caps
-xrdb, --xrdb
-nxrdb, --no-xrdb
-gbc, --global-colors
-ngbc, --no-global-colors
-m, --monitor monitor
-w, --embed window id
-H, --hist-file hist file
-ig, --image-gaps gaps
-txp, --text-padding padding
-vem, --vertical-margin margin
-hem, --horizontal-margin margin
-lp, --vertical-padding padding
-hp, --horizontal-padding padding
-la, --left-arrow-symbol symbol
-ra, --right-arrow-symbol symbol
-is, --image-size size
-it, --image-top
-ib, --image-bottom
-ic, --image-center
-itc, --image-topcenter
-wm, --managed, --x11-client
-nwm, --unmanaged
-cf, --config-file file
-lcfg, --load-config
-ncfg, --no-load-config
-v, --version
-fn, --font font
-nif, --normal-item-foreground color
-nib, --normal-item-background color
-sif, --selected-item-foreground color
-sib, --selected-item-background color
-npf, --normal-item-priority-foreground color
-npb, --normal-item-priority-background color
-spf, --selected-item-priority-foreground color
-spb, --selected-item-priority-background color
-pfg, --prompt-foreground color
-pbg, --prompt-background color
-ifg, --input-foreground color
-ibg, --input-background color
-mnbg, --menu-background color
-nhf, --normal-highlight-foreground color
-nhb, --normal-highlight-background color
-shf, --selected-highlight-foreground color
-shb, --selected-highlight-background color
-nfg, --number-foreground color
-nbg, --number-background color
-mfg, --mode-foreground color
-mbg, --mode-background color
-laf, --left-arrow-foreground color
-raf, --right-arrow-foreground color
-lab, --left-arrow-background color
-rab, --right-arrow-background color
-cfc, --caret-foreground color
-cbc, --caret-background color
-bc, --border-background color
-sgr0, --sgr0 color
-sgr1, --sgr1 color
-sgr2, --sgr2 color
-sgr3, --sgr3 color
-sgr4, --sgr4 color
-sgr5, --sgr5 color
-sgr6, --sgr6 color
-sgr7, --sgr7 color
-sgr8, --sgr8 color
-sgr9, --sgr9 color
-sgr10, --sgr10 color
-sgr11, --sgr11 color
-sgr12, --sgr12 color
-sgr13, --sgr13 color
-sgr14, --sgr14 color
-sgr15, --sgr15 color
dmenu compatibility can be achieved using these arguments:
-S
-i
-nb color
-nf color
-sb color
-sf color
See keybinds.h
for a list.
One of the features that separate spmenu from dmenu is spmenu’s different modes. As of version 0.2, there are two modes. Normal mode and Insert mode. These modes are of course similar to Vim.
Normal mode is the mode spmenu starts in unless a mode argument is specified. In normal mode, all keys perform some action, but you cannot type any actual text to filter items. This mode is used for navigation, as well as quickly selecting an item.
Insert mode is entered through (by default) pressing i
in normal mode. In this mode, most keybinds do nothing. When you are in
insert mode, you filter items by typing text into the field. Once you’re
done with insert mode, you can press Escape to enter normal mode
again.
spmenu has a -p option, which stands for prompt. It allows you to specify text to display next to the item list. It is displayed on the left side of the spmenu window. It should be noted that the prompt is purely visual though.
spmenu supports drawing images. This image is placed on the left side
of the menu window. To use an image, pipe
IMG:/path/to/image
to spmenu. If you want you can specify
arguments like usual. Note that you should add a Tab (\t
)
character after the path to the image file. Otherwise the text after
will be interpreted as part of the filename and the image will not be
drawn.
Any text after the Tab character will be interpreted as a regular item. In practice, drawing an image might look like this:
printf "IMG:/path/to/image\tLook at that image, isn't it awesome?\n" | spmenu
There are also a few image related arguments, such as:
-is
, -ig
, -it
,
-ib
, -ic
, -itc
and
-gc
.
NOTE: Vector images (such as .svg) can be displayed too.
spmenu supports colored text through SGR sequences. This is the same colors that you might already be using in your shell scripts. This means you can pipe practically any colored shell script straight into spmenu, no need to filter the output or anything.
Not only does it support colored text, but it also supports colored
backgrounds. This allows something similar to the emoji highlight patch,
except even more useful. Example:
printf "\033[0;44m😀\033[0m Emoji highlighting\n" | spmenu --columns 1
For 256 color support to work, you must add to the array. See
libs/color.h
if you want this.
See ‘SGR sequences’ for more information.
A basic supported SGR sequence looks like this:
\033[X;YZm
Here, X specifies if you want normal or bright colors. Y specifies if you want background or foreground. Z specifies the color number.
Foreground colors: 30
through 37
Background
colors: 40
through 47
Reset:
0
NOTE: ;
is a separator, and in this example it separates
the color number and normal/bright. \033 may also be written as
^]
or simply ESC
. The separator may be omitted
for some sequences, such as \033[0m
which resets the
colorscheme.
spmenu supports most color sequences, although not true color by default (unless -sgr arguments are used).
There are a few arguments, you can override SGR colors on-the-fly
using the -sgrX
arguments. See ‘Arguments’ for more
information.
Just as a tip, you can pipe your colored spmenu output to
sed -e 's/\x1b\[[0-9;]*m//g'
. This will clear the SGR
sequences from the output. This is useful when you want to check what
the output actually is.
If spmenu was compiled with Pango enabled (default), you should be able to utilize Pango markup in every part of spmenu. That is, the mode indicator, items, input, prompt, etc.
Pango markup allows you to style text similar to an HTML document. It
also provides the <span>
tag, which can be used to do
surprisingly complex things.
There are many convenient tags as well which can be used to avoid
using a <span>
tag, such as:
<b>
<b>Bold</b>
)
<i>
<i>Italic</i>
)
<s>
<s>Strikethrough</s>
)
<u>
<u>Underline</u>
)
<sub>
<sub>Subscript</sub>
)
<sup>
<sup>Supscript</sup>
)
<tt>
<tt>Monospaced font is used here</tt>
)
<small>
<small>text is so small here</small>
)
<big>
<big>text is so big here</big>
)
Note that Pango markup is NOT escaped, and is piped to stdout.
Therefore you need to parse it manually. Doing so with sed
is very easy. For example:
... | spmenu ... | sed 's/<big>//g; s/</big>//g'
See this page for more information.
Unlike dmenu, spmenu has a configuration file which can be edited by
hand. It is located in ~/.config/spmenu/spmenu.conf, but you can
override this by exporting $XDG_CONFIG_HOME
.
When spmenu is installed, it copies a sample configuration to
/usr/share/spmenu/spmenu.conf. You can copy this to your
.config/spmenu
directory. This configuration file is loaded
on startup.
You can also include other configuration files in the configuration
file using @include "path/to/config"
.
spmenu also has .Xresources (xrdb) support built in. It reads the xrdb (.Xresources database) on runtime. You may disable it by passing -nxrdb, or enable it by padding -xrdb. You can also set this in the regular config file.
spmenu loads ~/.config/spmenu/spmenurc
or alternatively
if you’re old fashioned, ~/.spmenurc
on startup. This
requires that xrdb
is available on your operating system.
Of course, you don’t NEED to use them, as you can just
xrdb -override
any .Xresources file you want.
You can also use wildcards (such as *
) to achieve a
global colorscheme. Programs like pywal
do this to apply
universal colorschemes.
spmenu supports profiles. Profiles are like configuration files (See
Configuration
) that can be switched between quickly using a
keybind.
Pressing (by default) Ctrl+Shift+p will list out profiles, and also allow you to add/remove existing profiles. Selecting a profile will switch to that profile. The selected profile will now be loaded on startup just like the spmenurc until another profile is selected.
Selecting ‘Add’ allows you to create a new profile. When a new
profile is created it is going to use the spmenu defaults (copied from
/usr/share/spmenu/example.Xresources
). Profiles are going
to be in ~/.config/spmenu/profiles/
and the current profile
is in ~/.config/spmenu/.profile
. The profile can simply be
edited using any text editor and be configured in .Xresources
syntax.
Selecting Remove
will allow you to pick a profile which
will be permanently removed. Selecting Default
will simply
load spmenurc
and nothing else on startup, as if this
feature did not exist.
Not only can profiles be used to configure color schemes and fonts, allowing you to swap color schemes quickly, but also any other options you may want.
Note that any profiles are applied ON TOP of the current loaded profile, meaning if any options are missing from the selected profile, the setting in the profile used before will be used in place.
There are a few color schemes for spmenu included in the repository,
see the themes/
directory. Feel free to copy those to your
profile directory.
spmenu includes a shell script called spmenu_run. It lists executable programs in $PATH and displays them to the user in a list. Not only that but it shows recently run programs first in the list.
spmenu_run will interpret any arguments as spmenu arguments and pass
them to spmenu. Therefore spmenu_run --prompt 'Run:'
will
set the prompt to Run:
. While it is similar to dmenu_run
(and achieves the same goal), this version has some extra features.
The selected option is piped to /bin/sh (by default). Unlike dmenu_run, spmenu_run has some cool features. For example:
#
will spawn it in a terminal instead of
just a shell.?
will run the command in a function, most
of the time used to display the man page.magnet
will open a magnet link in
$TORRENTwww
will open a page in $BROWSERMost of the time you don’t need to prepend www
though,
for example typing in https://gnu.org
will open gnu.org in
$BROWSER even without the prefix. Same goes for magnet links.
You can also configure the run launcher through editing
~/.config/spmenu/run/config
which is configured in shell
syntax.
In addition to the aforementioned spmenu_run
, the spmenu
package also provides spmenu_desktop
which instead of
reading $PATH only lists out .desktop entries.
Unlike the regular run launcher though, spmenu_desktop supports displaying an icon for entries that use one.
It can be configured through editing
~/.config/spmenu/desktop/config
. The configuration file can
also be moved by setting ${XDG_CONFIG_HOME}
.
spmenu has a few special commands. These work similar to the images.
For example to list the version, in addition to the
--version
argument you can also simply run
printf 'spmenu:version' | spmenu
. There are a few of
these.
spmenu:version
spmenu:license
spmenu:test
spmenu is licensed under the MIT license because that’s the original suckless license. See the included LICENSE file for more information.
Please report issues on the Codeberg repository or alternatively email me.