diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-20 12:08:31 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-20 12:09:36 +1200 |
commit | 304f4afceef0d421f2bba1ab9acff98fc83b000d (patch) | |
tree | 129ecdcae789e82a609ab0c76667d4ced768b1fe | |
parent | Remove OLDPWD hack (diff) | |
download | dotfiles-304f4afceef0d421f2bba1ab9acff98fc83b000d.tar.gz dotfiles-304f4afceef0d421f2bba1ab9acff98fc83b000d.zip |
Port bd() to POSIX sh
-rw-r--r-- | bash/bashrc.d/bd.bash | 78 | ||||
-rw-r--r-- | sh/shrc.d/bd.sh | 67 |
2 files changed, 67 insertions, 78 deletions
diff --git a/bash/bashrc.d/bd.bash b/bash/bashrc.d/bd.bash deleted file mode 100644 index 23a2d380..00000000 --- a/bash/bashrc.d/bd.bash +++ /dev/null @@ -1,78 +0,0 @@ -# Move back up the directory tree to the first directory matching the name -bd() { - - # For completeness' sake, we'll pass any options to cd - local arg - local -a opts - for arg ; do - case $arg in - --) - shift - break - ;; - -*) - shift - opts[${#opts[@]}]=$arg - ;; - *) - break - ;; - esac - done - - # We should have zero or one arguments after all that, bail if there are - # more - if (($# > 1)) ; then - printf 'bash: %s: usage: %s [PATH]\n' \ - "$FUNCNAME" "$FUNCNAME" >&2 - return 2 - fi - - # The requested pattern is the first argument; strip trailing slashes if - # there are any - local req=$1 - [[ $req != / ]] || req=${req%/} - - # What to do now depends on the request - local dirname - case $req in - - # If no argument at all, just go up one level - '') - dirname=.. - ;; - - # Just go straight to the root or dot directories if asked - /|.|..) - dirname=$req - ;; - - # Anything else with a leading / needs to anchor to the start of the - # path - /*) - dirname=$req - if [[ $PWD != "$dirname"/* ]] ; then - printf 'bash: %s: Directory name not in path\n' \ - "$FUNCNAME" >&2 - return 1 - fi - ;; - - # In all other cases, iterate through the directory tree to find a - # match, or whittle the dirname down to an empty string trying - *) - dirname=${PWD%/*} - while [[ -n $dirname && $dirname != */"$req" ]] ; do - dirname=${dirname%/*} - done - if [[ -z $dirname ]] ; then - printf 'bash: %s: Directory name not in path\n' \ - "$FUNCNAME" >&2 - return 1 - fi - ;; - esac - - # Try to change into the determined directory - builtin cd "${opts[@]}" -- "$dirname" -} diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh new file mode 100644 index 00000000..0d1abbcf --- /dev/null +++ b/sh/shrc.d/bd.sh @@ -0,0 +1,67 @@ +# Move back up the directory tree to the first directory matching the name +bd() { + + # Set positional parameters to an option terminator and what will hopefully + # end up being a target directory + set -- -- "$( + + # If the first of the existing positional arguments is --, shift it + # off + [ "$1" = -- ] && shift + + # There's no more than one argument after that + [ "$#" -le 1 ] || exit 1 + + # The requested pattern is the first argument, defaulting to just the + # parent directory + req=${1:-..} + + # Strip trailing slashes if a trailing slash isn't the whole pattern + [ "$req" = / ] || req=${req%/} + + # What to do now depends on the request + case $req in + + # Just go straight to the root or dot directories if asked + /|.|..) + dirname=$req + ;; + + # Anything with a leading / needs to anchor to the start of the + # path. A strange request though. Why not just use cd? + /*) + dirname=$req + case $PWD in + "$dirname"/*) ;; + *) dirname='' ;; + esac + ;; + + # In all other cases, iterate through the PWD to find a match, or + # whittle the target down to an empty string trying + *) + dirname=$PWD + while [ -n "$dirname" ] ; do + dirname=${dirname%/*} + case $dirname in + */"$req") break ;; + esac + done + ;; + esac + + # Check we have a target after all that + if [ -z "$dirname" ] ; then + printf >&2 'bd(): Directory name not in path\n' + exit 1 + fi + + # Print the target + printf '%s\n' "$dirname" + + # If the subshell failed, return from the function with the same exit value + )" || return + + # Try to change into the determined directory + command cd "$@" +} |