aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.markdown1
-rw-r--r--bash/bashrc.d/ud.bash41
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
+