#!/bin/sh set -e # Later, we're going to want to set $IFS to a single newline, so let's prepare one. NL=' ' VIS_MENU_PROMPT='' ALLOW_AUTO_SELECT='1' wrap_dirs() { while read -r filename do if [ -d "$filename" ]; then printf '%s/\n' "$filename" else printf '%s\n' "$filename" fi done } while getopts fhp: opt; do case "$opt" in f) ALLOW_AUTO_SELECT='' ;; p) VIS_MENU_PROMPT="$OPTARG" ;; h|?) printf 'usage: %s [-f] [-h] [-p prompt] [--] [file-pattern]\n' "${0##*/}" exit 0 ;; esac done shift "$((OPTIND - 1))" # At this point, all the remaining arguments should be the expansion of # any globs that were passed on the command line. if [ "$#" -eq 1 ] && [ "$ALLOW_AUTO_SELECT" = '1' ]; then # If there were globs on the command-line, they've expanded to # a single item, so we can just process it. if [ -d "$1" ]; then # Recurse and show the contents of the named directory, # We pass -f to force the next iteration to present the # full list, even if it's just an empty directory. cd "$1" IFS="$NL" # Don't split ls output on tabs or spaces. exec "$0" -p "$VIS_MENU_PROMPT" -f "$(ls -1)" else # We've found a single item, and it's not a directory, # so it must be a filename (or file-like thing) to open, # unless the parent directory does not exist. parentdir="$(dirname -- "$1")" if [ -d "$parentdir" ]; then cd "$parentdir" printf '%s/%s\n' "$(pwd -P)" "$(basename -- "${1%\*}")" exit 0 else exit 1 fi fi fi # At this point, we have a bunch of options we need to present to the # user so they can pick one. CHOICE="$(printf '%s\n' '..' "$@" | wrap_dirs | vis-menu -b -p "$VIS_MENU_PROMPT")" # Did they pick a file or directory? Who knows, let's let the next iteration figure it out. exec "$0" -p "$VIS_MENU_PROMPT" -- "$CHOICE"