Search The Web From Your Desktop Using Dmenu

Credit goes to the suckless website? The author’s name is in the file itself.

Here’s a little script to use your favourite search engine right from your desktop without needing to open a web browser first. As the title says, this script uses dmenu, and in my case, I use brave search.

As the image shows, I have a file saved in a dmenu directory I created, but you can put it anywhere.

Make sure to mark is as executable.



#!/bin/sh

# title: dmenu_websearch <http://efe.kim/dmenu_websearch.html>
# license: CC0
# author: Sunur Efe Vural <efe@efe.kim>
# version: Mar 22, 2019
# dependencies: dmenu, xdotool, hexdump, xprop, setxkbmap, coreutils.

# A  browser-independent address  bar  with bookmark  support. When  the
# cursor is on a web browser it acts as the address bar of that browser.

browser='firefox'
engine='https://search.brave.com/search?q=%s'
bookmarks="$HOME/.bookmarks"

gotourl() {
	if [ "$nbrowser" = surf ]
	then
		xprop -id "$winid" -f _SURF_GO 8s -set _SURF_GO "$choice"
	elif [ -n "$winid" ] && [ -z "$nbrowser" ]
	then
		#change layout to us cuz xdotool spasms with non-latin layouts
		layout=$(setxkbmap -query | awk '/^layout:/{ print $2 }')
		setxkbmap -layout us
		xdotool key --clearmodifiers "$shortcut"\
			type --clearmodifiers --delay 2 "$choice"
		xdotool key --clearmodifiers Return
		setxkbmap -layout "$layout"
	elif [ -n "$nbrowser" ]
	then
		$nbrowser "$choice"
	else $browser "$choice"
	fi
}

searchweb() {
	#convert search query to percent encoding and insert it into url
	choice=$(echo "$choice" | hexdump -v -e '/1 " %02x"')
	choice=$(echo "$engine" | sed "s/%s/${choice% 0a}/;s/[[:space:]]/%/g")
	gotourl
}

xprop -root | grep '^_NET_ACTIVE_WINDOW' && {
	winid=$(xprop -root _NET_ACTIVE_WINDOW | sed 's/.*[[:space:]]//')
	class=$(xprop -id "$winid" WM_CLASS | awk -F'\"' '{ print $(NF - 1) }')
	case "$class" in
		Firefox) nbrowser='firefox' ;;
		#Firefox) shortcut='ctrl+l' ;; # alternative method, uses xdotool
		IceCat) nbrowser='icecat' ;;
		Chromium) nbrowser='chromium' ;;
		Chrome) nbrowser='chrome' ;;
		Opera) nbrowser='opera' ;;
		Vivaldi) nbrowser='vivaldi' ;; # not tested
		Brave) nbrowser='brave' ;; # not tested
		Conkeror) nbrowser='conkeror' ;; # not tested
		Palemoon) nbrowser='palemoon' ;; # not tested
		Iceweasel) nbrowser='iceweasel' ;; # not tested
		qutebrowser) nbrowser='qutebrowser' ;;
		Midori) nbrowser='midori' ;; # not that good
		Luakit) nbrowser='luakit' ;; # uses the last window instance
		Uzbl|Vimb) shortcut='o' ;;
		Links) shortcut='g' ;;
		Netsurf*|Epiphany|Dillo|Konqueror|Arora) shortcut='ctrl+l' ;;
		Surf) nbrowser='surf' ; uricur=$(xprop -id "$winid" _SURF_URI |\
				awk -F'\"' '{ print $( NF - 1 ) }') ;;
		*) pid=$(xprop -id "$winid" _NET_WM_PID | awk '{ print $3 }')
			while pgrep -oP "$pid" >/dev/null
			do
				pid=$(pgrep -oP "$pid")
			done
			pname=$(awk '/^Name\:/{ print $NF }' /proc/"$pid"/status) ||
				winid="" ;;
	esac
	[ -n "$pname" ] && case "$pname" in
		w3m) shortcut="U" ;;
		lynx|elinks|links) shortcut="g" ;;
		*) winid="" ;;
	esac
}

tmpfile=$(mktemp /tmp/dmenu_websearch.XXXXXX)
trap 'rm "$tmpfile"' 0 1 15
printf '%s\n%s\n' "$uricur" "$1" > "$tmpfile"
cat "$bookmarks" >> "$tmpfile"
sed -i -E '/^(#|$)/d' "$tmpfile"
choice=$(dmenu -f -p 'Web Search:' -fn 'JetBrains Mono-20' -nf '#94e2d5' -nb '#11111b' -sf '#fab387' < "$tmpfile") || exit 1

# Detect links without protocol (This is WIP)
protocol='^(https?|ftps?|mailto|about|file):///?'
checkurl() {
	grep -Fx "$choice" "$tmpfile" &&
		choice=$(echo "$choice" | awk '{ print $1 }') && return 0
	[ ${#choice} -lt 4 ] && return 1
	echo "$choice" | grep -Z ' ' && return 1
	echo "$choice" | grep -EiZ "$protocol" && return 0
	echo "$choice" | grep -FZ '..' && return 1
	prepath=$(echo "$choice" | sed 's/(\/|#|\?).*//')
	echo "$prepath" |  grep -FvZ '.' && return 1
	echo "$prepath" |  grep -EZ '^([[:alnum:]~_:-]+\.?){1,3}' && return 0
}

if checkurl
then
	echo "$choice" | grep -EivZ "$protocol" &&
		choice="http://$choice"
	gotourl
else searchweb
fi

You may use it if you feel like it, and modify it to your heart’s content.

Other dmenu scripts can be found here: https://tools.suckless.org/dmenu/scripts/

Note: I copied the code for the script back in December 2023, so if there were any changes made to it by the author since then, it may be better to get it directly from their page instead.

:wink: :vulcan_salute:

3 Likes

:slight_smile:

changing the search engine to DDG and making some tweaks, then a run-through later. thanks for this.
how does it display a web page? like lynx (pure text?)?

It just opens the webpage (meaning the search engine page with your search query) in your selected or default browser, nothing special.

The idea of this script is to eliminate a step or two:

  • You don’t need to open your browser first, as running the script will launch your browser for you
  • If your browser is already open, you don’t need to open a new tab first or click in the address bar — the script will search in a new tab automatically
  • And you don’t need to click on the window icon if your browser isn’t the currently focused window

far out. it seems the possibilities are big with that tool…word processor, pdf or word docs. any app…

Probably. But that is beyond my understanding. Just found it while browsing the suckless tools when I was trying out DWM.

1 Like

the best discoveries are when you are just browsing with nothing special in mind.

1 Like