| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- #!/bin/bash
- # Run a command, or search the web for it.
- #
- # Enter run it if it is an executable, otherwise search for it
- # Alt+Enter always search, even if it looks like a command
- #
- # The second one exists because deciding by "is the first word a binary?" gets
- # it wrong for ordinary phrases: test, who, which, sort, time and file are all
- # real executables. Alt+Enter is bound to fuzzel's custom-1, which is dmenu-only
- # and exits with code 10 (see [key-bindings] in fuzzel.ini).
- browser_app_id="google-chrome"
- search_url="https://duckduckgo.com/?q="
- # Executables in PATH. Deliberately not `compgen -c`: that also lists shell
- # builtins and keywords (cd, alias, if, ...), which `command -v` reports as
- # found but `exec` cannot run.
- list_path_bins() {
- local IFS=: dir file
- for dir in $PATH; do
- [[ -d $dir ]] || continue
- for file in "$dir"/*; do
- [[ -f $file && -x $file ]] && printf '%s\n' "${file##*/}"
- done
- done | sort -u
- }
- search_web() {
- local query
- query=$(jq -rn --arg q "$1" '$q|@uri')
- xdg-open "$search_url$query" &
- # Wait for the browser window instead of guessing at a fixed sleep: a cold
- # start takes well over half a second, while an already-running Chrome is
- # ready almost immediately.
- local _
- for _ in $(seq 40); do
- if swaymsg -t get_tree |
- jq -e --arg id "$browser_app_id" \
- 'recurse(.nodes[]?, .floating_nodes[]?) | select(.app_id == $id)' >/dev/null; then
- swaymsg "[app_id=\"$browser_app_id\"] focus" >/dev/null
- return 0
- fi
- sleep 0.05
- done
- }
- result=$(list_path_bins | fuzzel --dmenu)
- status=$?
- [[ -z $result ]] && exit 0
- case $status in
- # Alt+Enter: search regardless of what the text looks like.
- 10)
- search_web "$result"
- ;;
- # Enter: run it if it really is an executable. type -P looks only at PATH,
- # so builtins and keywords fall through to the search instead of failing
- # silently in exec.
- 0)
- if type -P "${result%% *}" >/dev/null 2>&1; then
- exec $result
- fi
- search_web "$result"
- ;;
- # Escape, or fuzzel failed to start.
- *)
- exit 0
- ;;
- esac
|