aboutsummaryrefslogtreecommitdiff
path: root/sh/shrc.d/pd.sh
diff options
context:
space:
mode:
Diffstat (limited to 'sh/shrc.d/pd.sh')
-rw-r--r--sh/shrc.d/pd.sh49
1 files changed, 20 insertions, 29 deletions
diff --git a/sh/shrc.d/pd.sh b/sh/shrc.d/pd.sh
index ce43837b..e3a6daaa 100644
--- a/sh/shrc.d/pd.sh
+++ b/sh/shrc.d/pd.sh
@@ -2,39 +2,30 @@
# use when you've got a file path in a variable, or in history, or in Alt+.,
# and want to quickly move to its containing directory. In the absence of an
# argument, this just shifts up a directory, i.e. `cd ..`
+#
+# Note this is equivalent to `ud 1`.
pd() {
- # Check argument count
+ # Check arguments; default to $PWD
if [ "$#" -gt 1 ] ; then
printf >&2 'pd(): Too many arguments\n'
return 2
fi
-
- # Change the positional parameters from the target to its containing
- # directory
- set -- "$(
-
- # Figure out target dirname
- dirname=${1:-..}
- dirname=${dirname%/}
- dirname=${dirname%/*}
-
- # Check we have a target after that
- if [ -z "$dirname" ] ; then
- printf >&2 'ud(): Destination construction failed\n'
- exit 1
- fi
-
- # Print the target with trailing slash to work around newline stripping
- printf '%s/' "${dirname%/}"
- )"
-
- # Remove trailing slash
- set -- "${1%/}"
-
- # If the subshell printed nothing, return with failure
- [ -n "$1" ] || return
-
- # Try to change into the determined directory
- command cd -- "$@"
+ set -- "${1:-"$PWD"}"
+
+ # Make certain there are no trailing slashes to foul us up, and anchor path
+ # if relative
+ while : ; do
+ case $1 in
+ */) set -- "${1%/}" ;;
+ /*) break ;;
+ *) set -- "$PWD"/"$1" ;;
+ esac
+ done
+
+ # Strip a path element
+ set -- "${1%/*}"
+
+ # Try to change into the determined directory, or root if empty
+ command cd -- "${1:-/}"
}