diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2017-06-02 22:09:38 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2017-06-02 22:09:38 +1200 |
commit | e1e02dae1d6cfe6c34d1f0641349fab6eadca19c (patch) | |
tree | f11de1d64997ef90579fef04018e66350e3dfb73 /sh | |
parent | Merge branch 'master' into port/bsd/freebsd (diff) | |
parent | Remove lies from mi5 (diff) | |
download | dotfiles-e1e02dae1d6cfe6c34d1f0641349fab6eadca19c.tar.gz dotfiles-e1e02dae1d6cfe6c34d1f0641349fab6eadca19c.zip |
Merge branch 'master' into port/bsd/freebsd
Diffstat (limited to 'sh')
-rw-r--r-- | sh/profile.d/downloads.sh | 28 | ||||
-rw-r--r-- | sh/shrc.d/ad.sh | 80 | ||||
-rw-r--r-- | sh/shrc.d/bd.sh | 99 | ||||
-rw-r--r-- | sh/shrc.d/gd.sh | 2 | ||||
-rw-r--r-- | sh/shrc.d/gt.sh | 28 | ||||
-rw-r--r-- | sh/shrc.d/hgrep.sh | 6 | ||||
-rw-r--r-- | sh/shrc.d/mysql.sh | 25 | ||||
-rw-r--r-- | sh/shrc.d/pd.sh | 49 | ||||
-rw-r--r-- | sh/shrc.d/pmd.sh | 2 | ||||
-rw-r--r-- | sh/shrc.d/rd.sh | 47 | ||||
-rw-r--r-- | sh/shrc.d/sd.sh | 110 | ||||
-rw-r--r-- | sh/shrc.d/ud.sh | 61 |
12 files changed, 213 insertions, 324 deletions
diff --git a/sh/profile.d/downloads.sh b/sh/profile.d/downloads.sh new file mode 100644 index 00000000..fb8dd64a --- /dev/null +++ b/sh/profile.d/downloads.sh @@ -0,0 +1,28 @@ +# Only if shell is interactive +case $- in + *i*) ;; + *) return ;; +esac + +# Only if not in a tmux window +[ -z "$TMUX" ] || return + +# Not if ~/.hushlogin exists +[ -e "$HOME"/.hushlogin ] && return + +# Not if ~/.downloads doesn't +[ -f "$HOME"/.downloads ] || return + +# Count files in each directory, report if greater than zero +( + while IFS= read -r dir ; do + case $dir in + '#'*) continue ;; + esac + [ -d "$dir" ] || continue + set -- "$dir"/* + [ -e "$1" ] || shift + [ "$#" -gt 0 ] || continue + printf '\nYou have %u unsorted files in %s.\n\n' "$#" "$dir" + done < "$HOME"/.downloads +) diff --git a/sh/shrc.d/ad.sh b/sh/shrc.d/ad.sh deleted file mode 100644 index 55866683..00000000 --- a/sh/shrc.d/ad.sh +++ /dev/null @@ -1,80 +0,0 @@ -# Find an abbreviated path -ad() { - - # Check argument count - if [ "$#" -ne 1 ] ; then - printf >&2 'ad(): Need just one argument\n' - return 2 - fi - - # Change the positional parameters from the abbreviated request - # to any matched directory - set -- "$( - - # Clean up and anchor the request - req=${1%/}/ - case $req in - (/*) ;; - (*) req=${PWD%/}/${req#/} ;; - esac - - # Start building the target directory; go through the request piece by - # piece until it is used up - dir= - while [ -n "$req" ] ; do - - # Chop the next front bit off the request and add it to the dir - dir=${dir%/}/${req%%/*} - req=${req#*/} - - # If that exists, all is well and we can keep iterating - [ -d "$dir" ] && continue - - # Set the positional parameters to a glob expansion of the - # abbreviated directory given - set -- "$dir"* - - # Iterate through the positional parameters filtering out - # directories; we need to run right through the whole list to check - # that we have at most one match - entd= - for ent ; do - [ -d "$ent" ] || continue - - # If we already found a match and have found another one, bail - # out - if [ -n "$entd" ] ; then - printf >&2 'ad(): More than one matching dir for %s*:\n' \ - "$dir" - printf >&2 '%s\n' "$@" - exit 1 - fi - - # Otherwise, this can be our first one - entd=$ent - done - - # If we found no match, bail out - if [ -z "$entd" ] ; then - printf >&2 'ad(): No matching dirs: %s*\n' "$dir" - exit 1 - fi - - # All is well, tack on what we have found and keep going - dir=$entd - - done - - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${dir%/}" - )" - - # 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 -- "$@" -} diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index bf64a9aa..29bde513 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -1,70 +1,47 @@ # Move back up the directory tree to the first directory matching the name bd() { - # Check argument count + # Check arguments; default to ".." if [ "$#" -gt 1 ] ; then - printf >&2 'bd(): Too many arguments' + printf >&2 'bd(): Too many arguments\n' return 2 fi - - # Set positional parameters to an option terminator and what will hopefully - # end up being a target directory - set -- "$( - - # The requested pattern is the first argument, defaulting to just the - # parent directory - req=${1:-..} - - # Strip trailing slashes if a trailing slash is not the whole pattern - [ "$req" = / ] || req=${req%/} - - # What to do now depends on the request - case $req in - - # Just go straight to the root or dot directories if asked - (/|.|..) - dirname=$req - ;; - - # Anything with a leading / needs to anchor to the start of the - # path. A strange request though. Why not just use cd? - (/*) - dirname=$req - case $PWD in - ("$dirname"/*) ;; - (*) dirname='' ;; + set -- "${1:-..}" + + # Look at argument given; default to going up one level + case $1 in + + # If it's slash, dot, or dot-dot, we'll just go there, like `cd` would + /|.|..) ;; + + # Anything else with a slash anywhere is an error + */*) + printf >&2 'bd(): Illegal slash\n' + return 2 + ;; + + # Otherwise, add and keep chopping at the current directory until it's + # empty or it matches the request, then shift the request off + *) + set -- "$1" "$PWD" + while : ; do + case $2 in + */"$1"|'') break ;; + */) set -- "$1" "${2%/}" ;; + */*) set -- "$1" "${2%/*}" ;; + *) set -- "$1" '' ;; esac - ;; - - # In all other cases, iterate through the PWD to find a match, or - # whittle the target down to an empty string trying - (*) - dirname=$PWD - while [ -n "$dirname" ] ; do - dirname=${dirname%/*} - case $dirname in - (*/"$req") break ;; - esac - done - ;; - esac - - # Check we have a target after all that - if [ -z "$dirname" ] ; then - printf >&2 'bd(): Directory name not in path\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 + done + shift + ;; + esac + + # If we have nothing to change into, there's an error + if [ -z "$1" ] ; then + printf >&2 'bd(): No match\n' + return 1 + fi - # Try to change into the determined directory - command cd -- "$@" + # We have a match; try and change into it + command cd -- "$1" } diff --git a/sh/shrc.d/gd.sh b/sh/shrc.d/gd.sh index fa5776f2..9f6a43e7 100644 --- a/sh/shrc.d/gd.sh +++ b/sh/shrc.d/gd.sh @@ -8,7 +8,7 @@ gd() { fi # Complain if mark not actually set yet - if ! [ -n "$PMD" ] ; then + if [ -z "$PMD" ] ; then printf >&2 'gd(): Mark not set\n' return 1 fi diff --git a/sh/shrc.d/gt.sh b/sh/shrc.d/gt.sh index d18a4ab8..95ab4c2f 100644 --- a/sh/shrc.d/gt.sh +++ b/sh/shrc.d/gt.sh @@ -3,26 +3,24 @@ gt() { # Check argument count - if [ "$#" -gt 1 ] ; then - printf >&2 'gd(): Too many arguments\n' + if [ "$#" -ne 1 ] ; then + printf >&2 'gt(): Need one argument\n' return 2 fi - # Strip trailing slash - set -- "${1%/}" - - # If target doesn't have a leading slash, add PWD prefix - case $1 in - /*) ;; - *) set -- "${PWD%/}"/"$1" - esac + # 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 # If target isn't a directory, chop to its parent [ -d "$1" ] || set -- "${1%/*}" - # If target is now empty, go to the root - [ -n "$1" ] || set -- / - - # Try to change into the determined directory - command cd -- "$@" + # Try to change into the determined directory, or root if empty + command cd -- "${1:-/}" } diff --git a/sh/shrc.d/hgrep.sh b/sh/shrc.d/hgrep.sh index 1c4c3ec5..fe297ab3 100644 --- a/sh/shrc.d/hgrep.sh +++ b/sh/shrc.d/hgrep.sh @@ -6,11 +6,11 @@ hgrep() { if [ "$#" -eq 0 ] ; then printf >&2 'hgrep(): Need a pattern\n' - exit 2 + return 2 fi - if ! [ -n "$HISTFILE" ] ; then + if [ -z "$HISTFILE" ] ; then printf >&2 'hgrep(): No HISTFILE\n' - exit 2 + return 2 fi grep "$@" "$HISTFILE" } diff --git a/sh/shrc.d/mysql.sh b/sh/shrc.d/mysql.sh deleted file mode 100644 index abb496d2..00000000 --- a/sh/shrc.d/mysql.sh +++ /dev/null @@ -1,25 +0,0 @@ -# If a file ~/.mysql/$1.cnf exists, call mysql(1) using that file, discarding -# the rest of the arguments. Otherwise just run MySQL with given args. Use -# restrictive permissions on these files. Doesn't allow filenames beginning -# with hyphens. -# -# Examples: -# -# [client] -# host=dbhost.example.com -# user=foo -# password=SsJ2pICe226jM -# -# [mysql] -# database=bar -# -mysql() { - case $1 in - -*) ;; - *) - [ -f "$HOME/.mysql/$1".cnf ] && - set -- --defaults-extra-file="$HOME/.mysql/$1".cnf - ;; - esac - command mysql "$@" -} 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:-/}" } diff --git a/sh/shrc.d/pmd.sh b/sh/shrc.d/pmd.sh index c96a50bd..4b0cd5bd 100644 --- a/sh/shrc.d/pmd.sh +++ b/sh/shrc.d/pmd.sh @@ -1,6 +1,6 @@ # Print the marked directory pmd() { - if ! [ -n "$PMD" ] ; then + if [ -z "$PMD" ] ; then printf >&2 'pmd(): Mark not set\n' return 1 fi diff --git a/sh/shrc.d/rd.sh b/sh/shrc.d/rd.sh index 3b699c0d..9633713a 100644 --- a/sh/shrc.d/rd.sh +++ b/sh/shrc.d/rd.sh @@ -1,4 +1,3 @@ -# # 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 @@ -12,7 +11,6 @@ # $ rd usr opt # $ pwd # /opt/bin -# rd() { # Check argument count @@ -25,42 +23,17 @@ rd() { ;; 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 + # Check there's something to substitute, and do it + case $PWD in + *"$1"*) + set -- "${PWD%%"$1"*}""$2""${PWD#*"$1"}" + ;; + *) printf >&2 'rd(): Substitution failed\n' - exit 1 - fi - - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${new%/}" - )" - - # Remove trailing slash - set -- "${1%/}" - - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return + return 1 + ;; + esac # Try to change into the determined directory - command cd -- "$@" + command cd -- "$1" } diff --git a/sh/shrc.d/sd.sh b/sh/shrc.d/sd.sh index 4d63b7d6..8b12c170 100644 --- a/sh/shrc.d/sd.sh +++ b/sh/shrc.d/sd.sh @@ -1,4 +1,3 @@ -# # Shortcut to switch to another directory with the same parent, i.e. a sibling # of the current directory. # @@ -31,7 +30,6 @@ # /tmp/tmp.ZSunna5Eup/a # # Seems to work for symbolic links. -# sd() { # Check argument count @@ -40,48 +38,80 @@ sd() { return 2 fi - # Change positional parameters to what will hopefully be a completed - # substitution - set -- "$( + # Read sole optional argument + case $1 in + + # Slashes aren't allowed + */*) + printf >&2 'bd(): Illegal slash\n' + return 2 + ;; + + # If blank, we try to find if there's just one sibling, and change to + # that if so + '') + # First a special case: root dir + case $PWD in + *[!/]*) ;; + *) + printf >&2 'sd(): No siblings\n' + return 1 + ;; + esac + + # Get a full list of directories at this level; include dotfiles, + # but not the . and .. entries, using glob tricks to avoid Bash + # ruining things with `dotglob` + set -- ../[!.]*/ + [ -e "$1" ] || shift + set -- ../.[!.]*/ "$@" + [ -e "$1" ] || shift + set -- ../..?*/ "$@" + [ -e "$1" ] || shift + + # Check the number of matches + case $# in + + # One match? Must be $PWD, so no siblings--throw in 0 just in + # case, but that Shouldn't Happen (TM) + 0|1) + printf >&2 'sd(): No siblings\n' + return 1 + ;; - # Set the positional parameters to either the requested directory, or - # all siblings of the current directory if no request - spec=$1 - set -- - if [ -n "$spec" ] ; then - set -- "$@" ../"$spec" - else - for sib in ../.* ../* ; do - case ${sib#../} in - (.|..|"${PWD##*/}") continue ;; - esac - set -- "$@" "$sib" - done - fi + # Two matches; hopefully just one sibling, but which is it? + 2) - # We should have exactly one sibling - case $# in - (1) ;; - (0) - printf >&2 'sd(): No siblings\n' - exit 1 - ;; - (*) - printf >&2 'sd(): More than one sibling\n' - exit 1 - ;; - esac + # Push PWD onto the stack, strip trailing slashes + set -- "$1" "$2" "$PWD" + while : ; do + case $3 in + */) set -- "$1" "$2" "${3%/}" ;; + *) break ;; + esac + done - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${1%/}" - )" + # Pick whichever of our two parameters doesn't look like + # PWD as our sole parameter + case $1 in + ../"${3##*/}"/) set -- "$2" ;; + *) set -- "$1" ;; + esac + ;; - # Remove trailing slash - set -- "${1%/}" + # Anything else? Multiple siblings--user will need to specify + *) + printf >&2 'sd(): Multiple siblings\n' + return 1 + ;; + esac + ;; - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return + # If not, simply set our target to that directory, and let `cd` do the + # complaining if it doesn't exist + *) set -- ../"$1" ;; + esac - # Try to change into the determined directory - command cd -- "$@" + # Try and change into the first parameter + command cd -- "$1" } diff --git a/sh/shrc.d/ud.sh b/sh/shrc.d/ud.sh index 79f4b5e7..06234569 100644 --- a/sh/shrc.d/ud.sh +++ b/sh/shrc.d/ud.sh @@ -2,48 +2,45 @@ # like cd .., cd ../.., etc ud() { - # Check argument count - if [ "$#" -gt 1 ] ; then + # Check arguments; default to 1 and $PWD + if [ "$#" -gt 2 ] ; then printf >&2 'ud(): Too many arguments\n' return 2 fi + set -- "${1:-1}" "${2:-"$PWD"}" - # 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 + # Check first argument, number of steps upward. "0" is weird, but valid; + # "-1" however makes no sense at all + if [ "$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 -- "$( - - # Append /.. to the target (default PWD) the specified number of times - dirname=${2:-"$PWD"} - i=0 - steps=${1:-1} - while [ "$i" -lt "$steps" ] ; do - dirname=${dirname%/}/.. - i=$((i+1)) + # Check second argument, starting path, for relativity and anchor it if + # need be + case $2 in + /*) ;; + *) set -- "$1" "$PWD"/"$2" ;; + esac + + # Chop an element off the target the specified number of times + while [ "$1" -gt 0 ] ; do + + # Make certain there are no trailing slashes to foul us up + while : ; do + case $2 in + */) set -- "$1" "${2%/}" ;; + *) break ;; + esac done - # Check we have a target after all that - if [ -z "$dirname" ] ; then - printf >&2 'ud(): Destination construction failed\n' - exit 1 - fi + # Strip a path element + set -- "$(($1-1))" "${2%/*}" + done - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${dirname%/}" - )" + # Shift off the count, which should now be zero + shift - # 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 -- "$@" + # Try to change into the determined directory, or the root if blank + command cd -- "${1:-/}" } |