dnavigate (1430B)
1 #!/bin/sh 2 PROGNAME="$(basename $0)" 3 FOREST="${DNAVIGATE_DIR=$HOME/.local/bin/$PROGNAME.d}" 4 5 panic() { echo "$PROGNAME: "$* >&2; exit 1; } 6 usage() { panic "usage: $0 [-d dmenu options... --] tree [branch [args...]]"; } 7 run() { $SHELL -c "$*" & } 8 child() { 9 unset T B 10 [ "$1" ] || return 11 12 tchild $TREE "$@" 13 } 14 tchild() { 15 unset T B 16 [ "$1" ] || return 17 T="$1"; shift 18 [ "$1" ] && B="$1" && shift 19 20 export PPROMPT="$PROMPT" 21 $0 -d $DMENU_OPTS -- $T ${B:-main} "$@" 22 } 23 24 while getopts "d:" OPT; do 25 case ${OPT} in 26 d) 27 shift; # eat -d 28 while [ "$1" != "--" ]; do 29 [ "$1" ] || usage 30 DMENU_OPTS="$DMENU_OPTS$1 "; shift; 31 done 32 shift;; # eat -- 33 *) usage;; 34 esac 35 done 36 37 [ "$1" ] || usage 38 TREE="$1"; shift 39 [ "$1" ] && BRANCH="$1" && shift 40 41 . $FOREST/$TREE "${BRANCH:=main}" "$@" || exit 1 42 43 [ ! "$INPUT" ] && [ ${#LEAVES[*]} -ne ${#ACTIONS[*]} ] && panic "leaf and action count mismatch for '$TREE/$BRANCH'" 44 45 if [ ${#LEAVES[*]} -lt ${NLINES=${#LEAVES[*]}} ]; then 46 for I in $(seq ${#LEAVES[*]} $NLINES); do 47 LEAVES[$I]="" 48 ACTIONS[$I]="" 49 done 50 fi 51 52 [ "$PPROMPT" ] && PROMPT="$PPROMPT => $PROMPT" 53 54 menu() { 55 SEL="$(printf "%s\n" "${LEAVES[@]}" | dmenu -l $NLINES -p "$PROMPT" $DMENU_OPTS $OPTIONS)" 56 if [ $? -ne 0 ]; then 57 return 1; 58 elif [ "$INPUT" ]; then 59 $INPUT $SEL || menu 60 else 61 for I in $(seq 0 "${#LEAVES[*]}"); do 62 [ "${LEAVES[$I]}" = "$SEL" ] && break; 63 done 64 65 eval "${ACTIONS[$I]:-return 1}" || menu 66 fi 67 } 68 69 menu