diff options
-rw-r--r-- | README.markdown | 1 | ||||
-rw-r--r-- | bash/bashrc.d/ud.bash | 41 |
2 files changed, 42 insertions, 0 deletions
diff --git a/README.markdown b/README.markdown index b772f751..43dae299 100644 --- a/README.markdown +++ b/README.markdown @@ -182,6 +182,7 @@ There are a few other little tricks in `bash/bashrc.d`, including: * `pd` — Change to the argument’s parent directory * `scr` — Create a temporary directory and change into it * `sprunge` — Pastebin frontend tool I pilfered from `#bash` on Freenode +* `ud` — Change into an indexed ancestor of a directory I also wrap a few command calls with functions to stop me from doing silly things that the commands themselves don’t catch. My favourite is the one that diff --git a/bash/bashrc.d/ud.bash b/bash/bashrc.d/ud.bash new file mode 100644 index 00000000..c83b7c56 --- /dev/null +++ b/bash/bashrc.d/ud.bash @@ -0,0 +1,41 @@ +# Shortcut to step up the directory tree with an arbitrary number of steps, +# like cd .., cd ../.., etc +ud() { + + # Check and save optional first argument, number of steps upward; default + # to 1 if absent + local -i 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 dir=${2:-$PWD} + if [[ ! -e "$dir" ]] ; then + printf 'bash: %s: Target dir %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 + dir=${dir%/}/.. + done + + # Try to change into it + cd -- "$dir" +} + +# Completion is only useful for the second argument +_ud() { + if ((COMP_CWORD == 2)) ; then + local word=${COMP_WORDS[COMP_CWORD]} + COMPREPLY=( $(compgen -A directory -- "$word" ) ) + else + return 1 + fi +} +complete -F _ud ud + |