1#!/usr/local/bin/bash 2 3# herbstcommander.sh - launch herbstluftwm-commands via dmenu 4# Written by Florian Bruhin <me@the-compiler.org> 5 6# To customize dmenu-colors, create a file named "herbstcommander" in your 7# herbstluftwm config-directory, with something like this in it: 8# 9# dmenu_command=(dmenu -i -b -nb '#313131' -nf '#686868' -sb '#454545' -sf '#898989') 10# 11# You can also directly pass dmenu-arguments to this script instead, as long 12# as dmenu_command is undefined. 13 14config_1="$XDG_CONFIG_HOME/herbstluftwm/herbstcommander" 15config_2="$HOME/.config/herbstluftwm/herbstcommander" 16[[ -f "$config_1" ]] && source "$config_1" 17[[ -f "$config_2" ]] && source "$config_2" 18 19dm() { 20 if [[ "${dmenu_command[@]}" ]]; then 21 "${dmenu_command[@]}" "$@" 22 else 23 dmenu -i "$@" 24 fi 25} 26 27hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} 28prompt=${prompt:-herbstluft: } 29display_reply=${display_reply:-true} 30 31cmd=( "$@" ) 32forceexec=0 33 34while :; do 35 dmenu_args="" 36 if [[ "$forceexec" != 1 ]]; then 37 completion=$(hc complete "${#cmd[@]}" "${cmd[@]}") 38 if [[ "$?" = 7 ]] ; then 39 forceexec=1 40 fi 41 fi 42 if [[ "$forceexec" == 1 ]]; then 43 echo "Executing ${cmd[@]}" 44 reply=$(hc "${cmd[@]}") 45 status=$? 46 if [[ "$display_reply" && "$reply" ]]; then 47 dm -p "${cmd[*]}" <<< "$reply" >/dev/null 48 fi 49 exit $status 50 else 51 case "${cmd[*]}" in 52 raise|jumpto|bring) 53 IFS=$'\t' read -ra tags <<< "$(hc tag_status)" 54 i=1 55 completion=$( 56 wmctrl -l | while read line; do 57 IFS=' ' read -ra fields <<< "$line" 58 id=${fields[0]} 59 tag=${tags[ ${fields[1]} ]} 60 class=$(xprop -notype -id $id WM_CLASS | 61 sed 's/.*\?= *//; s/"\(.*\?\)", *"\(.*\?\)".*/\1,\2/') 62 title=${fields[@]:3} 63 printf "%-3s %s %-3s [%s] %s\n" "$i)" "$id" "$tag" "$class" "$title" 64 i=$((i+1)) 65 done 66 ) 67 68 dmenu_args="-l 10" 69 ;; 70 esac 71 next=$(dm $dmenu_args -p "${prompt}${cmd[*]}" <<< "$completion") 72 (( $? != 0 )) && exit 125 # dmenu was killed 73 if [[ -z "$next" ]]; then 74 forceexec=1 # empty reply instead of completion 75 else 76 case "${cmd[*]}" in 77 raise|jumpto|bring) 78 # add the WINID only (second field) 79 IFS=' ' read -ra fields <<< "$next" 80 cmd+=( ${fields[1]} ) 81 ;; 82 *) 83 cmd+=( $next ) 84 ;; 85 esac 86 fi 87 fi 88done 89