48 lines
1.7 KiB
Bash
Executable File
48 lines
1.7 KiB
Bash
Executable File
#!/bin/sh
|
|
set -euf
|
|
|
|
# fzfmenu: a dmenu replacement with fzf and a terminal emulator
|
|
# I know like 300 of these projects already exist but I wrote this for funsies
|
|
#
|
|
# usage: fzfmenu [-p PROMPT] [--] [arg...]
|
|
#
|
|
# all the args to this script get passed directly to fzf. -p is just a dmenu-compatible prompt setter, since fzf doesn't have -p
|
|
# works just like dmenu: reads stdin, splits on newlines (unless you use --read0), prints selection to stdout
|
|
# if you want shift+enter-esque functionality, I recommend adding '--bind ctrl-space:print-query+abort' to your FZF_DEFAULT_OPTS (shift+enter isn't compatible with every terminal)
|
|
|
|
# floating_terminal shouldn't have any spaces, tabs, or newlines, so no need to escape the arguments
|
|
# I put a -name here for urxvt so my window manager can center+ontop it. change as necessary/wanted
|
|
FLOATING_TERMINAL="${FLOATING_TERMINAL:-urxvt -name FLOATING_TERMINAL}"
|
|
|
|
clean() {
|
|
[ -p "${term_menu_tmp:-}" ] && rm "$term_menu_tmp"
|
|
}
|
|
|
|
if getopts :p: OPT; then
|
|
case $OPT in
|
|
p) set -- "$@" "--prompt" "$OPTARG > " && shift 2 ;; # convert to fzf-compatible --prompt
|
|
*) : ;; # simply ignore any other options cuz they might just be fzf options
|
|
esac
|
|
fi
|
|
|
|
# escape the cli arguments cuz they get passed to the nested sh
|
|
for arg; do
|
|
set -- "$@" "'$(printf "%s" "$arg" | sed "s/'/'\\\\''/g")'"
|
|
shift
|
|
done
|
|
|
|
# all of this shit can be replaced by one line
|
|
# "$TERMINAL" -e sh -c 'fzf </proc/'"$$"'/fd/0 >/proc/'"$$"'/fd/1'
|
|
# but that isn't portable (linux only). this implementation is. still cool to see though
|
|
|
|
trap 'clean' INT HUP QUIT EXIT
|
|
export input="$(cat)"
|
|
export term_menu_tmp="$(mktemp -u -t term-menu.XXXX)"
|
|
mkfifo "$term_menu_tmp"
|
|
|
|
$FLOATING_TERMINAL -e sh -c 'fzf '"$*"' <<EOF > "$term_menu_tmp"
|
|
$input
|
|
EOF' &
|
|
|
|
cat < "$term_menu_tmp"
|