Skip to main content
Version: 2.0

Dmenu Mode

Dux Shell

Dmenu Mode

The dms dmenu command reads newline-separated items from stdin, shows them in the DMS launcher, and prints whatever gets picked to stdout. It's a drop-in replacement for dmenu, with some extra functionality inspired by rofi's dmenu mode.

Matching is always case-insensitive, but dmenu's -i flag is still accepted for script compatibility.

Quick Start​

# Pick from a list
printf '%s\n' opt1 opt2 opt3 | dms dmenu -p "Pick one:"

# Free-text prompt with no item list
dms dmenu --prompt-only -p "Rename to:"

# Use it from a keybind to run a command picker
dms dmenu --input ~/.local/share/commands.txt -p "Run:"

Exit codes: 0 on accept, 1 if the user cancelled (or stdin was empty), 2 if the shell was unreachable.

Options​

Every long-form flag also accepts rofi's single-dash spelling

Prompt & Input​

FlagShortDescription
--prompt-pPrompt label (default: dmenu)
--placeholderInput placeholder text
--lines-lMax visible result rows (spotlight launcher only)
--prompt-onlySkip the piped item list for a plain free-text prompt
--mesgExtra message line shown alongside the list
--inputRead items from this file instead of stdin
--sepInput item separator (default: newline)

Matching & Selection​

FlagShortDescription
--selectPre-select the first row matching this string (with --dump, filters instead)
--active-aMark rows active by index, e.g. 1,3,7:11,-3:
--urgent-uMark rows urgent by index (same syntax as --active)
--only-matchReject free text; only a listed item may be returned. Also blocks Escape/click-outside, forcing a real pick
--no-customReject free text; only a listed item may be returned. Unlike --only-match, Escape/cancel still works
--multi-selectAllow selecting multiple rows; each prints on its own line on accept
--markup-rowsRender each row's text as rich markup
--case-insensitive-iNo effect -- included only for parity with dmenu, matching is always case-insensitive

The index syntax used by --active/--urgent takes comma-separated indices and ranges: 1,3 for single rows, 7:11 for a range, and -3: for "from the third-to-last row onward" (an empty side of : means "to the start/end").

Security​

FlagDescription
--passwordMask typed input (cosmetic only, not a security boundary)
--disable-historyDon't add this session's search query to the launcher's persistent history

NOTE: --password does not automatically disable history. If handling sensitive data such as a password, it is advised you use both flags, as well as display text for each entry which differs from the passed value.

Reading stdin​

FlagDescription
--syncRead all input to EOF before showing the picker (default: stream as items arrive)
--no-run-if-emptyIf stdin is empty, exit 1 immediately with no UI shown

Output Format​

Use --format to control what gets printed on accept. Default is s.

ValuePrints
sThe row's text (default)
i0-based row index
d1-based row index
qShell-quoted text
pText with markup tags stripped
fThe typed filter text
FShell-quoted filter text
# Print the 1-based index of the chosen row instead of its text
printf '%s\n' a b c | dms dmenu --format d

Dump Mode​

FlagDescription
--dumpApply --select against the item list and print the result immediately; no UI is ever shown
--print-infoAlso print an accepted row's info metadata on a second line

--dump is useful for testing a filter non-interactively, or for scripts that want dmenu's --select filtering behavior without paying for a picker UI at all.

# Print every item containing "firefox", no UI shown
printf '%s\n' firefox chromium firefox-dev | dms dmenu --dump --select firefox

Custom Keybinds​

FlagDescription
--keybindBind a custom accept key (repeatable): N=keyspec, e.g. --keybind 1=ctrl+e (N is 1-19)

Accepting via a custom keybind exits with code 9 + N (10-28) instead of 0, so a wrapper script can tell which key was used to accept.

# ctrl+e accepts with exit code 10; a plain Enter still exits 0
printf '%s\n' a b c | dms dmenu --keybind 1=ctrl+e
echo "exit: $?"

Appearance​

FlagDescription
--viewOverride the result view for this invocation: list, grid, or tile (default: list)
--sizeOverride the popup size preset: 1-4, matching the Appearance settings size buttons (default: the shell's own launcher size setting)
--iconShow a Material Symbols icon next to the prompt badge (default: none)

Per-Row Metadata Protocol​

Each line of input can carry metadata past a NUL byte (\0), as key\x1fvalue fields separated by the unit separator (\x1f). Everything before the NUL is the row's displayed/matched text.

Firefox\0icon\x1ffirefox\x1fmeta\x1fweb browser

Supported fields:

FieldTypeEffect
iconstringIcon shown next to the row
displaystringAlternate text to render (matching still uses the row's main text)
metastringSecondary/subtitle text shown under the row
infostringOpaque value printed after the row's text when accepted, if --print-info is set
nonselectableboolRow can't be picked (e.g. a section divider)
urgentboolMarks the row urgent, same styling as --urgent
activeboolMarks the row active, same styling as --active
permanentboolRow stays pinned regardless of filtering
headerboolRenders as a section header rather than a selectable row

Boolean fields accept 1/true/yes for true and 0/false/no/empty for false.

Exit Codes​

CodeMeaning
0Accepted normally (or via Enter)
1Cancelled, or stdin was empty with --no-run-if-empty
2The DMS shell was unreachable
10-28Accepted via custom keybind N (code is 9 + N)

Command Reference​

dms dmenu [flags]

Global Flags:

  • -c, --config <path>: Specify custom DMS config directory
  • -h, --help: Show help