aboutsummaryrefslogtreecommitdiff
path: root/sh
diff options
context:
space:
mode:
Diffstat (limited to 'sh')
-rw-r--r--sh/shrc.d/bd.sh9
-rw-r--r--sh/shrc.d/cd.sh76
-rw-r--r--sh/shrc.d/pd.sh12
-rw-r--r--sh/shrc.d/rd.sh63
-rw-r--r--sh/shrc.d/sd.sh16
-rw-r--r--sh/shrc.d/ud.sh26
6 files changed, 98 insertions, 104 deletions
diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh
index a5344ae7..81ddedb8 100644
--- a/sh/shrc.d/bd.sh
+++ b/sh/shrc.d/bd.sh
@@ -1,13 +1,16 @@
# Move back up the directory tree to the first directory matching the name
bd() {
+ # Check argument count
+ if [ "$#" -gt 1 ] ; then
+ printf >&2 'bd(): Too many arguments'
+ return 2
+ fi
+
# Set positional parameters to an option terminator and what will hopefully
# end up being a target directory
set -- "$(
- # Check there's no more than one argument
- [ "$#" -le 1 ] || exit 1
-
# The requested pattern is the first argument, defaulting to just the
# parent directory
req=${1:-..}
diff --git a/sh/shrc.d/cd.sh b/sh/shrc.d/cd.sh
deleted file mode 100644
index 7bfacd6d..00000000
--- a/sh/shrc.d/cd.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-# If given two arguments, replace the first instance of the first argument with
-# the second argument in $PWD, and make that the target of cd(). This POSIX
-# version cannot handle options, but it can handle an option terminator (--),
-# so e.g. `cd -- -foo -bar` should work.
-cd() {
-
- # First check to see if we can perform the substitution at all; otherwise,
- # we won't be changing any parameters
- if (
-
- # If we have any options, we can't do it, because POSIX shell doesn't
- # let us (cleanly) save the list of options for use later in the script
- for arg ; do
- case $arg in
- --) break ;;
- -*) opts=1 ; shift ;;
- esac
- done
-
- # Shift off -- if it's the first argument
- [ "$1" = -- ] && shift
-
- # Print an explanatory error if there were options and then two
- # arguments
- if [ "$#" -eq 2 ] && [ -n "$opts" ] ; then
- printf >&2 'cd(): Can'\''t combine options and substitution\n'
- fi
-
- # Check we have no options and two non-null arguments
- [ -z "$opts" ] || return
- [ "$#" -eq 2 ] || return
- [ -n "$1" ] || return
- [ -n "$2" ] || return
-
- ) ; then
-
- # Set the positional parameters to an option terminator and what will
- # hopefully end up being the substituted directory name
- set -- -- "$(
-
- # If the first of the existing positional arguments is --, shift it
- # off
- [ "$1" = -- ] && shift
-
- # Current path: e.g. /foo/ayy/bar/ayy
- cur=$PWD
- # Pattern to replace: e.g. ayy
- pat=$1
- # Text with which to replace pattern: e.g. lmao
- rep=$2
-
- # /foo/
- curtc=${cur%%"$pat"*}
- # /bar/ayy
- curlc=${cur#*"$pat"}
- # /foo/lmao/bar/ayy
- new=${curtc}${rep}${curlc}
-
- # Check that a substitution resulted in an actual change and that
- # we ended up with a non-null target, or print an error to stderr
- if [ "$cur" = "$curtc" ] || [ -z "$new" ]; then
- printf >&2 'cd(): Substitution failed\n'
- exit 1
- fi
-
- # Print the target
- printf '%s\n' "$new"
- )"
-
- # If the subshell printed nothing, return with failure
- [ -n "$2" ] || return
- fi
-
- # Execute the cd command as normal
- command cd "$@"
-}
diff --git a/sh/shrc.d/pd.sh b/sh/shrc.d/pd.sh
index c022b1e8..de4ea23b 100644
--- a/sh/shrc.d/pd.sh
+++ b/sh/shrc.d/pd.sh
@@ -4,16 +4,16 @@
# argument, this just shifts up a directory, i.e. `cd ..`
pd() {
+ # Check argument count
+ 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 -- "$(
- # Check argument count
- if [ "$#" -gt 1 ] ; then
- printf >&2 'pd(): Too many arguments\n'
- exit 2
- fi
-
# Figure out target dirname
dirname=${1:-..}
dirname=${dirname%/}
diff --git a/sh/shrc.d/rd.sh b/sh/shrc.d/rd.sh
new file mode 100644
index 00000000..9fd99a55
--- /dev/null
+++ b/sh/shrc.d/rd.sh
@@ -0,0 +1,63 @@
+#
+# Replace the first instance of the first argument string with the second
+# argument string in $PWD, and make that the target of the cd builtin. This is
+# to emulate a feature of the `cd` builtin in Zsh that I like, but that I think
+# should be a separate command rather than overloading `cd`.
+#
+# $ pwd
+# /usr/local/bin
+# $ rd local
+# $ pwd
+# /usr/bin
+# $ rd usr opt
+# $ pwd
+# /opt/bin
+#
+rd() {
+
+ # Check argument count
+ case $# in
+ 1|2) ;;
+ *)
+ printf >&2 \
+ 'rd(): Need a string and optionally a replacement\n'
+ return 2
+ ;;
+ esac
+
+ # Set the positional parameters to an option terminator and what will
+ # hopefully end up being the substituted directory name
+ set -- "$(
+
+ # Current path: e.g. /foo/ayy/bar/ayy
+ cur=$PWD
+ # Pattern to replace: e.g. ayy
+ pat=$1
+ # Text with which to replace pattern: e.g. lmao
+ # This can be a null string or unset, in order to *remove* the pattern
+ rep=$2
+
+ # /foo/
+ curtc=${cur%%"$pat"*}
+ # /bar/ayy
+ curlc=${cur#*"$pat"}
+ # /foo/lmao/bar/ayy
+ new=${curtc}${rep}${curlc}
+
+ # Check that a substitution resulted in an actual change and that we
+ # ended up with a non-null target, or print an error to stderr
+ if [ "$cur" = "$curtc" ] || [ -z "$new" ] ; then
+ printf >&2 'rd(): Substitution failed\n'
+ exit 1
+ fi
+
+ # Print the target
+ printf '%s\n' "$new"
+ )"
+
+ # If the subshell printed nothing, return with failure
+ [ -n "$1" ] || return
+
+ # Try to change into the determined directory
+ command cd -- "$@"
+}
diff --git a/sh/shrc.d/sd.sh b/sh/shrc.d/sd.sh
index 80ae7c12..c5b1106a 100644
--- a/sh/shrc.d/sd.sh
+++ b/sh/shrc.d/sd.sh
@@ -1,6 +1,6 @@
#
-# sd -- sibling/switch directory -- Shortcut to switch to another directory
-# with the same parent, i.e. a sibling of the current directory.
+# Shortcut to switch to another directory with the same parent, i.e. a sibling
+# of the current directory.
#
# $ pwd
# /home/you
@@ -34,14 +34,14 @@
#
sd() {
+ # Check argument count
+ if [ "$#" -gt 1 ] ; then
+ printf >&2 'sd(): Too many arguments\n'
+ return 2
+ fi
+
set -- "$(
- # Check argument count
- if [ "$#" -gt 1 ] ; then
- printf >&2 'sd(): Too many arguments\n'
- exit 1
- fi
-
# Set the positional parameters to either the requested directory, or
# all siblings of the current directory if no request
spec=$1
diff --git a/sh/shrc.d/ud.sh b/sh/shrc.d/ud.sh
index 259f3167..44a3a81d 100644
--- a/sh/shrc.d/ud.sh
+++ b/sh/shrc.d/ud.sh
@@ -2,23 +2,27 @@
# like cd .., cd ../.., etc
ud() {
+ # Check argument count
+ if [ "$#" -gt 1 ] ; then
+ printf >&2 'ud(): Too many arguments\n'
+ return 2
+ fi
+
+ # Check first argument, number of steps upward, default to 1.
+ # "0" is weird, but valid; "-1" however makes no sense at all
+ if [ "${1:-1}" -lt 0 ] ; then
+ printf >&2 'ud(): Invalid step count\n'
+ return 2
+ fi
+
# 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
+ # Append /.. to the target (default PWD) the specified number of times
dirname=${2:-"$PWD"}
-
- # Append /.. to the target the specified number of times
i=0
+ steps=${1:-1}
while [ "$i" -lt "$steps" ] ; do
dirname=${dirname%/}/..
i=$((i+1))