* Thorsten Wißmann <edu _at_ thorsten _minus_ wissmann _dot_ de> [2013-06-25 09:39:14 +0200]: > all in all, the patch is nice. I have some questions, for which I don't > have a (best) answer yet. By now, I probably do :) Note this is still one big commit and not splitted in smaller ones, but I hope that's okay, as there are too many changes which influence others. > On Thu, Jun 20, 2013 at 10:15:53PM +0200, Florian Bruhin wrote: > > herbstclient --idle '(tag_changed|goto_last_tag|reload)' \ > > | while read line ; do > > - ARGS=( $line ) > > + args=( $line ) > > Can we also use this read -a thing here? I now switched all foo=( $bar ) to read -ra. (-r to not interpret backslash escape sequences) This also means the "set -f" is unneeded because with read -ra, globs don't get expanded: $ touch boobs # SCNR $ str="foo *" $ arr1=( $str ) $ read -ra arr2 <<< "$str" $ echo "${arr1[1]}" boobs $ echo "${arr2[1]}" * > > simple_command() { > > - arg=$($hc complete 1 "$@"|dmenu_cmd -p "$@:") \ > > - && exec $hc "$@" "$arg" > > + arg=$("$hc" complete 1 "$@" | dmenu_cmd -p "$@:") \ > > + && exec "$hc" "$@" "$arg" > > > -$hc complete 1 use | > > +"$hc" complete 1 use | > > while read tag ; do > > [..] > > - $hc layout "$tag" \ > > + "$hc" layout "$tag" \ > > > [similar hunks...] > > My idea was to allow default arguments in herbstclient (maybe there will > be a flag like --use-this-and-that-protocol in the future). So the > decision is: Do we allow default arguments for herbstclient or allow > spaces in the path of the herbstclient binary... (That's exactly the > reason why hlwm-commands are arrays of strings and not just strings.) As discussed with you in IRC, I replaced all the hc foo by this: hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ; # ... hc do_something This means: - Users can have herbstclient_command unset, then herbstclient gets used - Users can have herbstclient_command set to a string, then this gets called e.g. herbstclient_command=~/bin/herbstclient - Users can have herbstclient_command set to an array, e.g. for some future options, e.g. herbstclient_command=("/path with spaces/herbstclient" --some-option) > > -function uniq_linebuffered() { > > - awk -W interactive '$0 != l { print ; l=$0 ; fflush(); }' "$@" > > +uniq_linebuffered() { > > + awk -W interactive '$0 != l { print ; l=$0 ; fflush(); }' "$@" 2>/dev/null > > } > > Why do you want to ignore stderr of awk? There are some versions of awk > that do not support fflush(), so it may be useful if panel.sh would > complain about that on stderr. As discussed as well, now I'll leave stderr alone, but only set "-W interactive" if using mawk. Difference between this and the last patch summarized (running diff on commit messages is kinda cool :P): Everywhere: - Use "read -ra" to read fields into an array everywhere. This saves a "tr" call (in release.sh), only splits on the intended character (and not on any whitespace) and prevents accidental glob expansion. http://mywiki.wooledge.org/BashGuide/Arrays#line-81 - Make calls of herbstclient/dmenu more consistent: If herbstclient_command is unset, "herbstclient" is called. If herbstclient_command is set to a string, the string is called. e.g.: herbstclient_command="$HOME/dev/herbstluftwm/herbstclient" If herbstclient_command is set to an array, the array is called. e.g.: herbstclient_command=("some path with spaces/herbstclient" "--some-future-option") In herbstcommander.sh: - Rename dmenu_cmd to dmenu_command for consistency In keychain.sh - Make modkey configurable, and use Mod1 instead of Mod4 by default In panel.sh: - Remove "set -f" call, because this is now unneeded when switching to "read -ra" to fill arrays. - Read lines into cmd array directly - Only use "-W interactive" in uniq_linebuffered() when running mawk mawk needs this to line-buffer the output correctly, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=593504 Other awk-versions (e.g. gawk) issue a warning, so we don't want to use it there. - Also use configured herbstclient call in clickable dzen area Florian -- www.the-compiler.org | Top-posting sucks! http://s.cmpl.cc/top I love long mails! | http://email.is-not-s.ms/ BOFH excuse #426: internet is needed to catch the etherbunny
From 516f76c42fb6d05eec555c1d46d13096ead030a2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Tue, 18 Jun 2013 15:20:33 +0200 Subject: [PATCH] Cleanup, simplifications and bugfixes in scripts Everywhere: - Replace all-caps variable names by lower-case ones, because upper-case variable names should be reserved for environment variables. http://stackoverflow.com/a/673940/2085149 - Replace multiple sed calls to the same file with one sed-call with multiple -e arguments. - Use consistent spacing for pipes - Quote variables which could potentially have whitespace in them (monitor names, tag names, file paths) http://mywiki.wooledge.org/Quotes#line-28 - Use "read -ra" to read fields into an array everywhere. This saves a "tr" call (in release.sh), only splits on the intended character (and not on any whitespace) and prevents accidental glob expansion. http://mywiki.wooledge.org/BashGuide/Arrays#line-81 - Make calls of herbstclient/dmenu more consistent: If herbstclient_command is unset, "herbstclient" is called. If herbstclient_command is set to a string, the string is called. e.g.: herbstclient_command="$HOME/dev/herbstluftwm/herbstclient" If herbstclient_command is set to an array, the array is called. e.g.: herbstclient_command=("some path with spaces/herbstclient" "--some-future-option") In release.sh: - Fix typo in comment In dumpbeautify.sh: - Remove unneeded semicolons in awk script - Print color clear character directly from awk, saving a sed call - Print an additional clear after output is finished - Use & for the backreference for sed (faster, easier to read) In exec_on_tag.sh: - Use "hc attr" to get current tag In floatmon.sh: - Replace grep | cut | sed by single sed call - Check if xwininfo exists In herbstcommander.sh: - Split tags up correctly (only by tab, not any whitespace) - Rename dmenu_cmd to dmenu_command for consistency In keychain.sh - Make modkey configurable, and use Mod1 instead of Mod4 by default In q3terminal.sh: - Bugfix: hc add "$tag", not scratchpad hardcoded - Don't use $ for variables inside ((..)) (consistency) - Add whitespace in calculations (easier to read) In panel.sh: - Remove "set -f" call, because this is now unneeded when switching to "read -ra" to fill arrays. - Read lines into cmd array directly - Change geometry comment to reflect real monitor_rect output - Replace 'if [ -e "$(which foo)" ]' by simple 'if which foo'. which has an exit status saying if it has found anything or not, so there is no need to check it's output. - Use "foo()" instead of "function foo()" Consistency, and "function foo()" is not portable, not even across all bash versions. http://mywiki.wooledge.org/BashPitfalls#function_foo.28.29 - Use \" instead of quote-mixing to get literal " inside "..." (easier to read) - Use simple sed call instead of cut | grep - Remove superfluous check if ${cmd[1]} is empty, as $monitor will never be empty. - Split tags up correctly (only by tab, not any whitespace) - Only use "-W interactive" in uniq_linebuffered() when running mawk mawk needs this to line-buffer the output correctly, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=593504 Other awk-versions (e.g. gawk) issue a warning, so we don't want to use it there. - Also use configured herbstclient call in clickable dzen area --- release.sh | 34 +++++++++++++------------- scripts/dmenu.sh | 12 +++------ scripts/dumpbeautify.sh | 56 +++++++++++++++++++++--------------------- scripts/exec_on_tag.sh | 22 ++++++----------- scripts/floatmon.sh | 42 +++++++++++++++++++------------ scripts/herbstcommander.sh | 29 +++++++++++++--------- scripts/keychain.sh | 9 ++++--- scripts/lasttag.sh | 13 +++++----- scripts/layout.sh | 12 ++++----- scripts/loadstate.sh | 6 ++--- scripts/q3terminal.sh | 33 +++++++++++-------------- scripts/savestate.sh | 6 ++--- scripts/wselect.sh | 9 ++++--- share/panel.sh | 61 ++++++++++++++++++++++++++-------------------- share/restartpanels.sh | 10 ++++---- 15 files changed, 185 insertions(+), 169 deletions(-) diff --git a/release.sh b/release.sh index 31ea228..4d72cda 100755 --- a/release.sh +++ b/release.sh @@ -1,6 +1,6 @@ #!/bin/bash -VERSION="$1" +version="$1" if [ -z "$1" ] || [ "$1" = -h ] ; then echo "$0 VERSIONMAJOR.VERSIONMINOR.VERSIONPATCH" @@ -13,47 +13,47 @@ if git status --porcelain | grep '^ M' ; then exit 1 fi -VERSIONARGS=( $(tr . ' ' <<< "$VERSION") ) +IFS=. read -ra versionargs <<< "$version" echo "==> Release commit" echo ":: Patching version.mk" -sed -i "s/^VERSION_MAJOR.*$/VERSION_MAJOR = ${VERSIONARGS[0]}/" version.mk -sed -i "s/^VERSION_MINOR.*$/VERSION_MINOR = ${VERSIONARGS[1]}/" version.mk -sed -i "s/^VERSION_PATCH.*$/VERSION_PATCH = ${VERSIONARGS[2]}/" version.mk +sed -i -e "s/^VERSION_MAJOR.*$/VERSION_MAJOR = ${versionargs[0]}/" \ + -e "s/^VERSION_MINOR.*$/VERSION_MINOR = ${versionargs[1]}/" \ + -e "s/^VERSION_PATCH.*$/VERSION_PATCH = ${versionargs[2]}/" version.mk echo ":: Patching NEWS" date=$(date +%Y-%m-%d) -newheader="Release $VERSION on $date" -newunderline="$(echo $newheader|sed 's/./-/g')" +newheader="Release $version on $date" +newunderline="$(echo $newheader | sed 's/./-/g')" headerexp="^Next Release: [^ ]*$" -# this requires news sed -sed -i -e "/$headerexp/,+1s/^[-]*$/$newunderline/" NEWS -sed -i -e "s/$headerexp/$newheader/" NEWS +# this requires new sed +sed -i -e "/$headerexp/,+1s/^[-]*$/$newunderline/" \ + -e "s/$headerexp/$newheader/" NEWS echo ":: Commiting changes" git add NEWS version.mk -git commit -m "Release $VERSION" +git commit -m "Release $version" echo ":: Tagging commit" -git tag -s v$VERSION -m "Release $VERSION" +git tag -s "v$version" -m "Release $version" echo "==> Tarball" echo ":: Tarball creation" make tar -tarball=herbstluftwm-$VERSION.tar.gz -md5sum=$(md5sum $tarball| head -c 13 ) +tarball="herbstluftwm-$version.tar.gz" +md5sum=$(md5sum "$tarball" | head -c 13 ) echo ":: Patching www/index.txt" line=$(printf "| %-7s | $date | $md5sum...%15s| link:tarballs/%s[tar.gz]" \ - $VERSION ' ' "$tarball" ) + $version ' ' "$tarball" ) linerexp="// do not remove this: next version line will be added here" sed -i "s#^$linerexp\$#$line\n$linerexp#" www/index.txt echo ":: Commiting changes" git add www/index.txt -git commit -m "www: Add $VERSION tarball" +git commit -m "www: Add $version tarball" echo echo "Still to do:" echo "1. Add the following line to the MD5SUMS file on the mirror:" -md5sum $tarball +md5sum "$tarball" echo "2. Make www files and install them on the remote" echo "3. Push the changes to all public remotes (including --tags)" diff --git a/scripts/dmenu.sh b/scripts/dmenu.sh index 24bd556..053b45d 100755 --- a/scripts/dmenu.sh +++ b/scripts/dmenu.sh @@ -1,15 +1,11 @@ #!/bin/bash -dmenu_command=${dmenu_command:-dmenu} -hc=${herbstclient_command:-herbstclient} - -dmenu_cmd() { - $dmenu_command "$@" -} +dm() { "${dmenu_command[@]:-dmenu}" "$@" ;} +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} simple_command() { - arg=$($hc complete 1 "$@"|dmenu_cmd -p "$@:") \ - && exec $hc "$@" "$arg" + arg=$(hc complete 1 "$@" | dm -p "$@:") \ + && exec "${herbstclient_command[@]:-herbstclient}" "$@" "$arg" } simple_command "$1" diff --git a/scripts/dumpbeautify.sh b/scripts/dumpbeautify.sh index 3301306..423d167 100755 --- a/scripts/dumpbeautify.sh +++ b/scripts/dumpbeautify.sh @@ -7,54 +7,54 @@ awkcode=' BEGIN { indent=2 - ORS=""; - x=0; - open=0; + ORS="" + x=0 + open=0 first=1 - i=0; - color[i++]="\033[1;31m"; - color[i++]="\033[1;32m"; - color[i++]="\033[1;33m"; - color[i++]="\033[1;34m"; - color[i++]="\033[1;35m"; - color[i++]="\033[1;36m"; - color[i++]="\033[1;37m"; - color[i++]="\033[0;31m"; - color[i++]="\033[0;32m"; - color[i++]="\033[0;33m"; - color[i++]="\033[0;34m"; - color[i++]="\033[0;35m"; - color[i++]="\033[0;36m"; - color[i++]="\033[0;37m"; + i=0 + color[i++]="\033[1;31m" + color[i++]="\033[1;32m" + color[i++]="\033[1;33m" + color[i++]="\033[1;34m" + color[i++]="\033[1;35m" + color[i++]="\033[1;36m" + color[i++]="\033[1;37m" + color[i++]="\033[0;31m" + color[i++]="\033[0;32m" + color[i++]="\033[0;33m" + color[i++]="\033[0;34m" + color[i++]="\033[0;35m" + color[i++]="\033[0;36m" + color[i++]="\033[0;37m" } $1 ~ "^[(]" { if (first == 0) { - printf "\n"; - printf "%"(indent*x)"s" , "" ; + printf "\n" + printf "%"(indent*x)"s" , "" } else { - first=0; + first=0 } color_bracket[x]=open print color[(color_bracket[x]) % length(color)] - print ; + gsub("[(]", "&" clear) + print x++ - open++; + open++ } $1 ~ "[)]" { - x-- ; + x-- print color[(color_bracket[x]) % length(color)] print } END { - printf "\n" + printf clear "\n" } ' clear=$(tput sgr0) || clear=$(echo -e '\e[0m') -sed 's/\([()]\)/\n\1/g' | # insert newlines before ( - awk "$awkcode" | - sed 's#(#('"$clear"'#g' +sed 's/[()]/\n&/g' | # insert newlines before ( + awk -v "clear=$clear" "$awkcode" diff --git a/scripts/exec_on_tag.sh b/scripts/exec_on_tag.sh index 5c552db..f7acaa1 100755 --- a/scripts/exec_on_tag.sh +++ b/scripts/exec_on_tag.sh @@ -1,7 +1,9 @@ #!/bin/bash -TAG="$1" -EXPIRE="120" # expiry time in seconds +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} + +tag="$1" +expire="120" # expiry time in seconds shift if [ -z "$1" ] ;then @@ -12,22 +14,12 @@ if [ -z "$1" ] ;then fi -hc() { - herbstclient "$@" -} - -curtag() { - hc tag_status \ - | grep -oE "$(echo -ne '\t')#[^$(echo -ne '\t')]*" \ - | tail -c +3 -} - -TAG=${TAG:-$(curtag)} +tag=${tag:-$(hc attr tags.focus.name)} # ensure tag exists -hc add "$TAG" +hc add "$tag" # move next window from this process to this tag -hc rule maxage="$EXPIRE" pid="$$" tag="$TAG" once +hc rule maxage="$expire" pid="$$" tag="$tag" once exec "$@" diff --git a/scripts/floatmon.sh b/scripts/floatmon.sh index 9f1f053..48cad41 100755 --- a/scripts/floatmon.sh +++ b/scripts/floatmon.sh @@ -5,23 +5,35 @@ tag=fl Mod=${Mod:-Mod1} Floatkey=${Floatkey:-Shift-f} -hc() { herbstclient "$@" ; } +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} -size=$(xwininfo -root | - grep -E '^ (Width|Height):' | - cut -d' ' -f4 | - sed 'N;s/\n/x/') +if which xwininfo &> /dev/null; then + size=$(xwininfo -root | + sed -n -e '/^ Width: / { + s/.*: //; + h + } + /^ Height: / { + s/.*: //g; + H; + x; + s/\n/x/p + }') +else + echo "This script requires the xwininfo binary." + exit 1 +fi -hc chain , add $tag , floating $tag on -hc or , add_monitor "$size"+0+0 $tag $monitor \ - , move_monitor $monitor "$size"+0+0 -hc raise_monitor $monitor -hc lock_tag $monitor +hc chain , add "$tag" , floating "$tag" on +hc or , add_monitor "$size"+0+0 "$tag" "$monitor" \ + , move_monitor "$monitor" "$size"+0+0 +hc raise_monitor "$monitor" +hc lock_tag "$monitor" cmd=( or case: and # if not on floating monitor - . compare monitors.focus.name != $monitor + . compare monitors.focus.name != "$monitor" # and if a client is focused . get_attr clients.focus.winid # then remember the last monitor of the client @@ -30,12 +42,12 @@ or case: and . substitute M monitors.focus.index set_attr clients.focus.my_lastmon M # and then move the client to the floating tag - . shift_to_monitor $monitor - . focus_monitor $monitor + . shift_to_monitor "$monitor" + . focus_monitor "$monitor" . true case: and # if on the floating monitor - . compare monitors.focus.name = $monitor + . compare monitors.focus.name = "$monitor" # and if a client is focused . get_attr clients.focus.winid # then send it back to the original monitor @@ -50,5 +62,5 @@ or case: and . focus_monitor 0 ) -herbstclient keybind $Mod-$Floatkey "${cmd[@]}" +hc keybind $Mod-$Floatkey "${cmd[@]}" diff --git a/scripts/herbstcommander.sh b/scripts/herbstcommander.sh index 244d286..4698bb2 100755 --- a/scripts/herbstcommander.sh +++ b/scripts/herbstcommander.sh @@ -6,18 +6,25 @@ # To customize dmenu-colors, create a file named "herbstcommander" in your # herbstluftwm config-directory, with something like this in it: # -# dmenu_cmd="dmenu -i -b -nb #313131 -nf #686868 -sb #454545 -sf #898989" +# dmenu_command=(dmenu -i -b -nb '#313131' -nf '#686868' -sb '#454545' -sf '#898989') # # You can also directly pass dmenu-arguments to this script instead, as long -# as dmenu_cmd is undefined. +# as dmenu_command is undefined. config_1="$XDG_CONFIG_HOME/herbstluftwm/herbstcommander" config_2="$HOME/.config/herbstluftwm/herbstcommander" [[ -f "$config_1" ]] && source "$config_1" [[ -f "$config_2" ]] && source "$config_2" -dmenu_cmd=${dmenu_cmd:-dmenu -i} -herbstclient_cmd=${herbstclient_cmd:-herbstclient} +dm() { + if [[ "${dmenu_command[@]}" ]]; then + "${dmenu_command[@]}" "$@" + else + dmenu -i "$@" + fi +} + +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} prompt=${prompt:-herbstluft: } display_reply=${display_reply:-true} @@ -27,27 +34,27 @@ forceexec=0 while :; do dmenu_args="" if [[ "$forceexec" != 1 ]]; then - completion=$($herbstclient_cmd complete "${#cmd[@]}" "${cmd[@]}") + completion=$(hc complete "${#cmd[@]}" "${cmd[@]}") if [[ "$?" = 7 ]] ; then forceexec=1 fi fi if [[ "$forceexec" == 1 ]]; then echo "Executing ${cmd[@]}" - reply=$($herbstclient_cmd "${cmd[@]}") + reply=$(hc "${cmd[@]}") status=$? if [[ "$display_reply" && "$reply" ]]; then - $dmenu_cmd -p "${cmd[*]}" <<< "$reply" >/dev/null + dm -p "${cmd[*]}" <<< "$reply" >/dev/null fi exit $status else case "${cmd[*]}" in raise|jumpto|bring) - tags=( $($herbstclient_cmd tag_status) ) + IFS=$'\t' read -ra tags <<< "$(hc tag_status)" i=1 completion=$( wmctrl -l | while read line; do - fields=( $line ) + IFS=' ' read -ra fields <<< "$line" id=${fields[0]} tag=${tags[ ${fields[1]} ]} class=$(xprop -notype -id $id WM_CLASS | @@ -61,7 +68,7 @@ while :; do dmenu_args="-l 10" ;; esac - next=$($dmenu_cmd $dmenu_args -p "${prompt}${cmd[*]}" <<< "$completion") + next=$(dm $dmenu_args -p "${prompt}${cmd[*]}" <<< "$completion") (( $? != 0 )) && exit 125 # dmenu was killed if [[ -z "$next" ]]; then forceexec=1 # empty reply instead of completion @@ -69,7 +76,7 @@ while :; do case "${cmd[*]}" in raise|jumpto|bring) # add the WINID only (second field) - fields=( $next ) + IFS=' ' read -ra fields <<< "$next" cmd+=( ${fields[1]} ) ;; *) diff --git a/scripts/keychain.sh b/scripts/keychain.sh index 54c6618..1ac1c0f 100755 --- a/scripts/keychain.sh +++ b/scripts/keychain.sh @@ -3,16 +3,19 @@ # Execute this (e.g. from your autostart) to obtain basic key chaining like it # is known from other applications like screen. # -# E.g. you can press Mod4-i 1 (i.e. first press Mod4-i and then press the +# E.g. you can press Mod1-i 1 (i.e. first press Mod1-i and then press the # 1-button) to switch to the first workspace # # The idea of this implementation is: If one presses the prefix (in this case -# Mod4-i) except the notification, nothing is really executed but new +# Mod1-i) except the notification, nothing is really executed but new # keybindings are added to execute the actually commands (like use_index 0) and # to unbind the second key level (1..9 and 0) of this keychain. (If you would # not unbind it, use_index 0 always would be executed when pressing the single # 1-button). +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} +Mod=Mod1 + # Create the array of keysyms, the n'th entry will be used for the n'th # keybinding keys=( {1..9} 0 ) @@ -27,7 +30,7 @@ done # key chain. (Except the spawn notify-send of course, which can be deactivated # by only deleting the appropriate line) -herbstclient keybind Mod4-i chain \ +hc keybind $Mod-i chain \ '->' spawn notify-send "Select a workspace number or press Escape" \ '->' keybind "${keys[0]}" chain "${unbind[@]}" , use_index 0 \ '->' keybind "${keys[1]}" chain "${unbind[@]}" , use_index 1 \ diff --git a/scripts/lasttag.sh b/scripts/lasttag.sh index c329227..a6f951d 100755 --- a/scripts/lasttag.sh +++ b/scripts/lasttag.sh @@ -6,16 +6,17 @@ # to switch to the last tag, call: herbstclient emit_hook goto_last_tag # or bind it: herbstclient keybind Mod1-Escape emit_hook goto_last_tag -herbstclient --idle '(tag_changed|goto_last_tag|reload)' \ +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} +hc --idle '(tag_changed|goto_last_tag|reload)' \ | while read line ; do - ARGS=( $line ) - case ${ARGS[0]} in + IFS=$'\t' read -ra args <<< "$line" + case ${args[0]} in tag_changed) - LASTTAG="$TAG" - TAG=${ARGS[1]} + lasttag="$tag" + tag=${args[1]} ;; goto_last_tag) - ! [ -z "$LASTTAG" ] && herbstclient use "$LASTTAG" + [ "$lasttag" ] && hc use "$lasttag" ;; reload) exit diff --git a/scripts/layout.sh b/scripts/layout.sh index c631a84..fbac24f 100755 --- a/scripts/layout.sh +++ b/scripts/layout.sh @@ -3,14 +3,14 @@ # print layout of all tags, and colorizes all window ids # it's useful to get a overview over the list of all windows -hc=${herbstclient_command:-herbstclient} +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} -$hc complete 1 use | +hc complete 1 use | while read tag ; do echo -n "$tag " - indent=$(echo -n "$tag "|sed 's/./ /g') + indent=$(echo -n "$tag " | sed 's/./ /g') # prepend indent, except in first line - $hc layout "$tag" \ - | sed "2,\$ s/^/$indent/" \ - | sed "s/\(0x[0-9a-f]\{1,\}\)/$(tput setaf 3)\1$(tput sgr0)/g" + hc layout "$tag" \ + | sed -e "2,\$ s/^/$indent/" \ + -e "s/0x[0-9a-f]\+/$(tput setaf 3)&$(tput sgr0)/g" done diff --git a/scripts/loadstate.sh b/scripts/loadstate.sh index 1c5e0a0..5a781f8 100755 --- a/scripts/loadstate.sh +++ b/scripts/loadstate.sh @@ -1,6 +1,6 @@ #!/bin/bash -hc=${herbstclient_command:-herbstclient} +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} # loads layouts for each tag coming from stdin # the format is the one created by savestate.sh @@ -13,6 +13,6 @@ hc=${herbstclient_command:-herbstclient} while read line ; do tag="${line%%: *}" tree="${line#*: }" - $hc add "$tag" - $hc load "$tag" "$tree" + hc add "$tag" + hc load "$tag" "$tree" done diff --git a/scripts/q3terminal.sh b/scripts/q3terminal.sh index 9d74580..bae9e89 100755 --- a/scripts/q3terminal.sh +++ b/scripts/q3terminal.sh @@ -13,27 +13,23 @@ # If a tag name is supplied, this is used instead of the scratchpad tag="${1:-scratchpad}" - -hc() { - #echo "hc $@" >&2 ; - herbstclient "$@" ; -} +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} mrect=( $(hc monitor_rect -p "" ) ) -termwidth=$(((${mrect[2]}*8)/10)) +termwidth=$(( (${mrect[2]} * 8) / 10 )) termheight=400 rect=( $termwidth $termheight - $((${mrect[0]}+(${mrect[2]}-termwidth)/2)) - $((${mrect[1]}-termheight)) + $(( ${mrect[0]} + (${mrect[2]} - termwidth) / 2 )) + $(( ${mrect[1]} - termheight )) ) y_line=${mrect[1]} -hc add scratchpad +hc add "$tag" monitor=q3terminal @@ -45,9 +41,9 @@ if ! hc add_monitor $(printf "%dx%d%+d%+d" "${rect[@]}") \ else # remember which monitor was focused previously hc chain \ - , new_attr string monitors.by-name.$monitor.my_prev_focus \ + , new_attr string monitors.by-name."$monitor".my_prev_focus \ , substitute M monitors.focus.index \ - set_attr monitors.by-name.$monitor.my_prev_focus M + set_attr monitors.by-name."$monitor".my_prev_focus M fi update_geom() { @@ -61,19 +57,18 @@ interval=0.01 animate() { progress=( "$@" ) for i in "${progress[@]}" ; do - rect[3]=$((${y_line}-(i*termheight)/$steps)) + rect[3]=$((y_line - (i * termheight) / steps)) update_geom sleep "$interval" done } show() { - hc lock - hc raise_monitor $monitor - hc focus_monitor $monitor + hc raise_monitor "$monitor" + hc focus_monitor "$monitor" hc unlock - hc lock_tag $monitor + hc lock_tag "$monitor" animate $(seq $steps -1 0) } @@ -91,10 +86,10 @@ hide() { animate $(seq 0 +1 $steps) # if q3terminal still is focused, then focus the previously focused monitor # (that mon which was focused when starting q3terminal) - hc substitute M monitors.by-name.$monitor.my_prev_focus \ - and + compare monitors.focus.name = $monitor \ + hc substitute M monitors.by-name."$monitor".my_prev_focus \ + and + compare monitors.focus.name = "$monitor" \ + focus_monitor M - hc remove_monitor $monitor + hc remove_monitor "$monitor" } [ $exists = true ] && hide || show diff --git a/scripts/savestate.sh b/scripts/savestate.sh index b717f46..74e597b 100755 --- a/scripts/savestate.sh +++ b/scripts/savestate.sh @@ -1,6 +1,6 @@ #!/bin/bash -hc=${herbstclient_command:-herbstclient} +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} # prints a machine readable format of all tags and its layouts # one tag with its layout per line @@ -10,8 +10,8 @@ hc=${herbstclient_command:-herbstclient} # and sometime later: # loadstate.sh < mystate -$hc complete 1 use | +hc complete 1 use | while read tag ; do echo -n "$tag: " - $hc dump "$tag" + hc dump "$tag" done diff --git a/scripts/wselect.sh b/scripts/wselect.sh index 5a31d69..de45d4c 100755 --- a/scripts/wselect.sh +++ b/scripts/wselect.sh @@ -4,7 +4,8 @@ # dependencies: wmctrl, awk, # dmenu with multiline support (command line flag -l) -dmenu_command=${dmenu_command:-dmenu} +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} +dm() { "${dmenu_command[@]:-dmenu}" "$@" ;} dmenu_lines=${dmenu_lines:-10} case "$1" in @@ -12,16 +13,16 @@ case "$1" in bring) # bring the selected window to the current tag and focus it name=Bring: - action() { herbstclient bring "$@" ; } + action() { hc bring "$@" ; } ;; select|*) # switch to the selected window and focus it - action() { herbstclient jumpto "$@" ; } + action() { hc jumpto "$@" ; } name=Select: ;; esac id=$(wmctrl -l |cat -n| sed 's/\t/) /g'| sed 's/^[ ]*//' \ - | $dmenu_command -l $dmenu_lines -p "$name") \ + | dm -l $dmenu_lines -p "$name") \ && action $(awk '{ print $2 ; }' <<< "$id") diff --git a/share/panel.sh b/share/panel.sh index 5dcfec8..93cf1c9 100755 --- a/share/panel.sh +++ b/share/panel.sh @@ -1,31 +1,28 @@ #!/bin/bash -# disable path name expansion or * will be expanded in the line -# cmd=( $line ) -set -f - +hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} monitor=${1:-0} geometry=( $(herbstclient monitor_rect "$monitor") ) if [ -z "$geometry" ] ;then echo "Invalid monitor $monitor" exit 1 fi -# geometry has the format: WxH+X+Y +# geometry has the format W H X Y x=${geometry[0]} y=${geometry[1]} panel_width=${geometry[2]} panel_height=16 font="-*-fixed-medium-*-*-*-12-*-*-*-*-*-*-*" -bgcolor=$(herbstclient get frame_border_normal_color) -selbg=$(herbstclient get window_border_active_color) +bgcolor=$(hc get frame_border_normal_color) +selbg=$(hc get window_border_active_color) selfg='#101010' #### # Try to find textwidth binary. # In e.g. Ubuntu, this is named dzen2-textwidth. -if [ -e "$(which textwidth 2> /dev/null)" ] ; then +if which textwidth &> /dev/null ; then textwidth="textwidth"; -elif [ -e "$(which dzen2-textwidth 2> /dev/null)" ] ; then +elif which dzen2-textwidth &> /dev/null ; then textwidth="dzen2-textwidth"; else echo "This script requires the textwidth tool of the dzen2 project." @@ -41,23 +38,33 @@ else dzen2_svn="" fi -function uniq_linebuffered() { - awk -W interactive '$0 != l { print ; l=$0 ; fflush(); }' "$@" -} +if awk -Wv 2>/dev/null | head -1 | grep -q '^mawk'; then + # mawk needs "-W interactive" to line-buffer stdout correctly + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=593504 + uniq_linebuffered() { + awk -W interactive '$0 != l { print ; l=$0 ; fflush(); }' "$@" + } +else + # other awk versions (e.g. gawk) issue a warning with "-W interactive", so + # we don't want to use it there. + uniq_linebuffered() { + awk '$0 != l { print ; l=$0 ; fflush(); }' "$@" + } +fi -herbstclient pad $monitor $panel_height +hc pad $monitor $panel_height { # events: #mpc idleloop player & while true ; do date +'date ^fg(#efefef)%H:%M^fg(#909090), %Y-%m-^fg(#efefef)%d' sleep 1 || break - done > >(uniq_linebuffered) & + done > >(uniq_linebuffered) & childpid=$! - herbstclient --idle + hc --idle kill $childpid } 2> /dev/null | { - TAGS=( $(herbstclient tag_status $monitor) ) + IFS=$'\t' read -ra tags <<< "$(hc tag_status $monitor)" visible=true date="" windowtitle="" @@ -65,7 +72,7 @@ herbstclient pad $monitor $panel_height bordercolor="#26221C" separator="^bg()^fg($selbg)|" # draw tags - for i in "${TAGS[@]}" ; do + for i in "${tags[@]}" ; do case ${i:0:1} in '#') echo -n "^bg($selbg)^fg($selfg)" @@ -84,7 +91,10 @@ herbstclient pad $monitor $panel_height ;; esac if [ ! -z "$dzen2_svn" ] ; then - echo -n "^ca(1,herbstclient focus_monitor $monitor && "'herbstclient use "'${i:1}'") '"${i:1} ^ca()" + echo -n "^ca(1,\"${herbstclient_command[@]:-herbstclient}\" " + echo -n "focus_monitor \"$monitor\" && " + echo -n "\"${herbstclient_command[@]:-herbstclient}\" " + echo -n "use \"${i:1}\") ${i:1} ^ca()" else echo -n " ${i:1} " fi @@ -93,19 +103,18 @@ herbstclient pad $monitor $panel_height echo -n "^bg()^fg() ${windowtitle//^/^^}" # small adjustments right="$separator^bg() $date $separator" - right_text_only=$(echo -n "$right"|sed 's.\^[^(]*([^)]*)..g') + right_text_only=$(echo -n "$right" | sed 's.\^[^(]*([^)]*)..g') # get width of right aligned text.. and add some space.. width=$($textwidth "$font" "$right_text_only ") echo -n "^pa($(($panel_width - $width)))$right" echo # wait for next event - read line || break - cmd=( $line ) + IFS=$'\t' read -ra cmd || break # find out event origin case "${cmd[0]}" in tag*) #echo "resetting tags" >&2 - TAGS=( $(herbstclient tag_status $monitor) ) + IFS=$'\t' read -ra tags <<< "$(hc tag_status $monitor)" ;; date) #echo "resetting date" >&2 @@ -115,8 +124,8 @@ herbstclient pad $monitor $panel_height exit ;; togglehidepanel) - currentmonidx=$(herbstclient list_monitors |grep ' \[FOCUS\]$'|cut -d: -f1) - if [ -n "${cmd[1]}" ] && [ "${cmd[1]}" -ne "$monitor" ] ; then + currentmonidx=$(hc list_monitors | sed -n '/\[FOCUS\]$/s/:.*//p') + if [ "${cmd[1]}" -ne "$monitor" ] ; then continue fi if [ "${cmd[1]}" = "current" ] && [ "$currentmonidx" -ne "$monitor" ] ; then @@ -125,10 +134,10 @@ herbstclient pad $monitor $panel_height echo "^togglehide()" if $visible ; then visible=false - herbstclient pad $monitor 0 + hc pad $monitor 0 else visible=true - herbstclient pad $monitor $panel_height + hc pad $monitor $panel_height fi ;; reload) diff --git a/share/restartpanels.sh b/share/restartpanels.sh index 320a3fe..9d9110c 100755 --- a/share/restartpanels.sh +++ b/share/restartpanels.sh @@ -2,15 +2,15 @@ installdir=/ -XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config} +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" defaultpanel="$XDG_CONFIG_HOME/herbstluftwm/panel.sh" -[ -x "$defaultpanel" ] || defaultpanel=$installdir/etc/xdg/herbstluftwm/panel.sh +[ -x "$defaultpanel" ] || defaultpanel="$installdir/etc/xdg/herbstluftwm/panel.sh" -panelcmd=${1:-$defaultpanel} +panelcmd="${1:-$defaultpanel}" herbstclient emit_hook quit_panel -for i in $(herbstclient list_monitors|cut -d':' -f1) ; do - $panelcmd $i & +for i in $(herbstclient list_monitors | cut -d':' -f1) ; do + "$panelcmd" $i & done -- 1.8.3.4
Attachment:
pgpdahTLuFUkb.pgp
Description: PGP signature