diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-12-13 13:03:49 +1300 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-12-13 13:03:49 +1300 |
commit | 6b5073d7c37a77e7afa2ddc48510e5ae0b09ac5f (patch) | |
tree | 502d41ffad32b30efdd76a7d470406e1db32b3a4 /sh | |
parent | Add strik(6df) (diff) | |
download | dotfiles-6b5073d7c37a77e7afa2ddc48510e5ae0b09ac5f.tar.gz dotfiles-6b5073d7c37a77e7afa2ddc48510e5ae0b09ac5f.zip |
Add ad()
Diffstat (limited to 'sh')
-rw-r--r-- | sh/shrc.d/ad.sh | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/sh/shrc.d/ad.sh b/sh/shrc.d/ad.sh new file mode 100644 index 00000000..d3e5a90a --- /dev/null +++ b/sh/shrc.d/ad.sh @@ -0,0 +1,77 @@ +# Find an abbreviated path +ad() { + + # Check argument count + if [ "$#" -ne 1 ] ; then + printf >&2 'ad(): Need just one argument\n' + return 2 + fi + + # Change the positional parameters from the abbreviated request + # to any matched directory + set -- "$( + + # Clean up and anchor the request + req=${1%/}/ + case $req in + (/*) ;; + (*) req=${PWD%/}/${req#/}/ ;; + esac + + # Start building the target directory; go through the request piece by + # piece until it is used up + dir= + while [ -n "$req" ] ; do + + # Chop the next front bit off the request and add it to the dir + dir=${dir%/}/${req%%/*} + req=${req#*/} + + # If that exists, all is well and we can keep iterating + [ -d "$dir" ] && continue + + # Set the positional parameters to a glob expansion of the + # abbreviated directory given + set -- "$dir"* + + # Iterate through the positional parameters filtering out + # directories; we need to run right through the whole list to check + # that we have at most one match + entd= + for ent ; do + [ -d "$ent" ] || continue + + # If we already found a match and have found another one, bail + # out + if [ -n "$entd" ] ; then + printf >&2 'ad(): More than one matching dir for %s*:\n' \ + "$dir" + printf >&2 '%s\n' "$@" + exit 1 + fi + + # Otherwise, this can be our first one + entd=$ent + done + + # If we found no match, bail out + if [ -z "$entd" ] ; then + printf >&2 'ad(): No matching dirs: %s*\n' "$dir" + exit 1 + fi + + # All is well, tack on what we have found and keep going + dir=$entd + + done + + # Print the target + printf '%s\n' "$dir" + )" + + # If the subshell printed nothing, return with failure + [ -n "$1" ] || return + + # Try to change into the determined directory + command cd -- "$@" +} |