Install dictd, and configure it to use offline dictionaries.
To use dict with dmenu, create an index. The following assumes that you are using the WordNet dictionary.
cd ~/.local/state cp /usr/share/dictd/wn.index . sed "s/ .*//g" wn.index | sort -n > wn.tmp && mv wn.tmp wn.index
Note that in the sed command above, there is a tab, but your browser might show a space. If you copy it to your clipboard, it should work regardless.
To use this with sxhkd:
alt + shift + d definition="$XDG_RUNTIME_DIR/dmenu_dict"; \ dict "$(dmenu -i -l 10 < $XDG_STATE_HOME/wn.index)" > "$definition"; \ [ -s "$definition" ] && st less -+F -c "$definition"
2025 Aug 8th: I switched back to sdcv since the AUR has a repository with only the WordNet files without its programs.
alt + d def="$XDG_RUNTIME_DIR/sdcv"; \ sdcv -n "$(:|dmenu -p "Define:")" > "$def"; \ [ -s "$def" ] && st less "$def"
I no longer use the following hacky setup with GCIDE. Its custom markup sucks.
cd gcide for f in CIDE*; do; mv $f "${f#*.}"; done mkdir info; find -maxdepth 1 -type f -not -name "?" -exec mv {} info \; find -maxdepth 1 -type f -exec sh -c 'sed "s/<ldquo\//<q>/g; s/<rdquo\//<\/q>/g" "$1" > tmp && mv tmp "$1" || rm tmp' echo {} \; sed "s/<ent> /<ent>/" K > K.tmp && mv K.tmp K def word # or dmenu_def, shell scripts below, licensed under BSD0 # repeat the following to replace GCIDE's non-standard markup while referencing webfont.txt find -maxdepth 1 -type f -exec sh -c 'sed "s/<cced\//ç/g; s/<Cced\//Ç/" "$1" > tmp && mv tmp "$1" || rm tmp' echo {} \;
#!/bin/sh -e DICT="$HOME/data/books/dictionary" phrase="${*:-$(cat)}" # e.g. gum ammoniac is with dictionary entries that start with A [ "$phrase" = "-t" ] && { thorough=1; phrase="$(cat)"; } phrase="$(printf "%s" "$phrase" | tr '[:lower:]' '[:upper:]' | sed 's=\\=\\\\=g; s=\/=\\\/=g')" letter="$(printf "%.1s" "$phrase")" case "$letter" in "'") end="${phrase#?}"; letter="${end%"${end#?}"}" ;; # second char "-") search_files="$(grep -irl "<ent>$phrase</ent>" "$DICT")" ;; ".") letter="V" ;; [0-9]|"\\") letter="A" ;; esac : "${search_files="$DICT/$letter"}" definitions="$(printf "%s\n" "$search_files" | xargs sed -n "/<ent>$phrase<\/ent>/I,/^$/p")" [ "$thorough" ] && [ -z "$definitions" ] && { search_files="$(grep -irl "<ent>$phrase</ent>" "$DICT")" definitions="$(printf "%s\n" "$search_files" | xargs sed -n "/<ent>$phrase<\/ent>/I,/^$/p")" } printf "%s" "$definitions" | w3m -dump -T text/html
#!/bin/sh -e DICT="$HOME/data/books/dictionary" CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/dmenu_def" [ -f "$CACHE" ] || grep -orh --exclude-dir=info "<ent>.*</ent>" "$DICT" | sed "s/<.\?ent>//g" | sort -n | uniq > "$CACHE" dmenu -i -l 10 < "$CACHE" | def -t