| 123456789101112131415161718192021222324252627282930313233343536373839404142434445 |
- #!/bin/bash
- # Run a command, or fall back to a web search if it isn't one.
- # fuzzel --dmenu prints the typed string as-is when nothing matches,
- # which is what makes the search fallback work.
- 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
- }
- result=$(list_path_bins | fuzzel --dmenu)
- [[ -z $result ]] && exit 0
- # type -P looks only at PATH, so builtins and keywords correctly fall through
- # to the search branch instead of failing silently in exec.
- if type -P "${result%% *}" >/dev/null 2>&1; then
- exec $result
- fi
- query=$(jq -rn --arg q "$result" '$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.
- 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
- exit 0
- fi
- sleep 0.05
- done
|