diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-20 12:29:24 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-20 12:43:48 +1200 |
commit | 416fc33ff1e9e034cf2bb4a58bb177f46606afd5 (patch) | |
tree | e067bc1c8c7af4bb7267b0b691b8b1a7fe832bb7 | |
parent | Remove option term spec from bd() (diff) | |
download | dotfiles-416fc33ff1e9e034cf2bb4a58bb177f46606afd5.tar.gz dotfiles-416fc33ff1e9e034cf2bb4a58bb177f46606afd5.zip |
Port ud() to POSIX sh
-rw-r--r-- | README.markdown | 2 | ||||
-rw-r--r-- | bash/bashrc.d/ud.bash | 50 | ||||
-rw-r--r-- | sh/shrc.d/ud.sh | 42 |
3 files changed, 43 insertions, 51 deletions
diff --git a/README.markdown b/README.markdown index 3bf1e604..6e6f2bbb 100644 --- a/README.markdown +++ b/README.markdown @@ -187,6 +187,7 @@ in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include: preserved; I hate ending up `root`-owned files in my home directory. * `tmux()` changes the default command for `tmux(1)` to `attach-session -d` if a session exists, or creates a new session if one doesn't. +* `ud()` changes into an indexed ancestor of a directory. * `vim()` defines three functions to always use `vim(1)` as my `ex(1)`, `vi(1)` and `view(1)` implementation if it's available. @@ -211,7 +212,6 @@ There are a few other little tricks defined for other shells, mostly in * `readv()` prints names and values from `read` calls to `stderr`. * `readz()` is an alias for `read -d '' -r`. * `sd()` changes into a sibling of the current directory. -* `ud()` changes into an indexed ancestor of a directory. * `vared()` allows interactively editing a variable with Readline, emulating a Zsh function I like by the same name. * `vr()` tries to change to the root directory of a source control diff --git a/bash/bashrc.d/ud.bash b/bash/bashrc.d/ud.bash deleted file mode 100644 index e23de1fa..00000000 --- a/bash/bashrc.d/ud.bash +++ /dev/null @@ -1,50 +0,0 @@ -# Shortcut to step up the directory tree with an arbitrary number of steps, -# like cd .., cd ../.., etc -ud() { - - # 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 - - # Check and save optional first argument, number of steps upward; default - # to 1 if absent - local -i steps - steps=${1:-1} - if ! ((steps > 0)) ; then - printf 'bash: %s: Invalid step count %s\n' "$FUNCNAME" "$1" >&2 - return 2 - fi - - # Check and save optional second argument, target directory; default to - # $PWD (typical usage case) - local dirname - dirname=${2:-"$PWD"} - if [[ ! -e $dirname ]] ; then - printf 'bash: %s: Target directory %s does not exist\n' "$FUNCNAME" "$2" >&2 - return 1 - fi - - # Append /.. to the target the specified number of times - local -i i - for (( i = 0 ; i < steps ; i++ )) ; do - dirname=${dirname%/}/.. - done - - # Try to change into it - cd "${opts[@]}" -- "$dirname" -} diff --git a/sh/shrc.d/ud.sh b/sh/shrc.d/ud.sh new file mode 100644 index 00000000..0dfd858c --- /dev/null +++ b/sh/shrc.d/ud.sh @@ -0,0 +1,42 @@ +# Shortcut to step up the directory tree with an arbitrary number of steps, +# like cd .., cd ../.., etc +ud() { + + # Change the positional parameters from the number of steps given to a + # "../../.." string + set -- "$( + + # Check first argument, number of steps upward, default to 1 + # "0" is weird, but valid; "-1" however makes no sense at all + steps=${1:-1} + if [ "$steps" -lt 0 ] ; then + printf >&2 'ud(): Invalid step count\n' + exit 2 + fi + + # Check second argument, target directory, default to $PWD + dirname=${2:-"$PWD"} + + # Append /.. to the target the specified number of times + i=0 + while [ "$i" -lt "$steps" ] ; do + dirname=${dirname%/}/.. + i=$((i+1)) + done + + # Check we have a target after all that + if [ -z "$dirname" ] ; then + printf >&2 'ud(): Destination construction failed\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 -- "$@" +} |