diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-20 16:26:06 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-20 16:26:39 +1200 |
commit | 6e3fd021588c87a0743dbc1ec5b3f5aba900f839 (patch) | |
tree | 74a790cf3a96c7f55660c612964462f194aa20ce | |
parent | Assume POSIX sh (diff) | |
download | dotfiles-6e3fd021588c87a0743dbc1ec5b3f5aba900f839.tar.gz dotfiles-6e3fd021588c87a0743dbc1ec5b3f5aba900f839.zip |
Port vr(1) to POSIX sh
-rw-r--r-- | ISSUES.markdown | 3 | ||||
-rw-r--r-- | README.markdown | 4 | ||||
-rw-r--r-- | bash/bashrc.d/vr.bash | 59 | ||||
-rw-r--r-- | sh/shrc.d/vr.sh | 49 |
4 files changed, 51 insertions, 64 deletions
diff --git a/ISSUES.markdown b/ISSUES.markdown index bbaf12ae..c9a832d1 100644 --- a/ISSUES.markdown +++ b/ISSUES.markdown @@ -1,9 +1,6 @@ Known issues ============ -* vr() does not handle the newer version of Subversion repositories which - only have a .svn directory at the root level. -* It should also be POSIX portable without too much effort * The terminfo files probably still do not work on NetBSD (needs retesting and manual page reading). * man(1) completion doesn't work on OpenBSD as manpath(1) isn't a thing on diff --git a/README.markdown b/README.markdown index 558c8739..c79ffd1b 100644 --- a/README.markdown +++ b/README.markdown @@ -201,6 +201,8 @@ in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include: * `ud()` changes into an indexed ancestor of a directory. * `vim()` defines three functions to always use `vim(1)` as my `ex(1)`, `vi(1)` and `view(1)` implementation if it's available. +* `vr()` tries to change to the root directory of a source control + repository. There are a few other little tricks defined for other shells, mostly in `bash/bashrc.d`: @@ -215,8 +217,6 @@ There are a few other little tricks defined for other shells, mostly in * `readz()` is an alias for `read -d '' -r`. * `vared()` allows interactively editing a variable with Readline, emulating a Zsh function I like by the same name. -* `vr()` tries to change to the root directory of a source control - repository. #### Completion diff --git a/bash/bashrc.d/vr.bash b/bash/bashrc.d/vr.bash deleted file mode 100644 index adabb395..00000000 --- a/bash/bashrc.d/vr.bash +++ /dev/null @@ -1,59 +0,0 @@ -# Move to the root directory of a VCS working copy -vr() { - local path - path=${1:-"$PWD"} - path=${path%/} - - # Raise some helpful errors - if [[ ! -e $path ]] ; then - printf 'bash: %s: %s: No such file or directory\n' \ - "$FUNCNAME" "$path" - return 1 - fi - if [[ ! -d $path ]] ; then - printf 'bash: %s: %s: Not a directory\n' \ - "$FUNCNAME" "$path" - return 1 - fi - if [[ ! -x $path ]] ; then - printf 'bash: %s: %s: Permission denied\n' \ - "$FUNCNAME" "$path" - return 1 - fi - - # Ask Git the top level - local git_root - git_root=$(cd -- "$path" && git rev-parse --show-toplevel 2>/dev/null) - if [[ -n $git_root ]] ; then - cd -- "$git_root" - return - fi - - # Ask Mercurial the top level - local hg_root - hg_root=$(cd -- "$path" && hg root 2>/dev/null) - if [[ -n $hg_root ]] ; then - cd -- "$hg_root" - return - fi - - # If we have a .svn directory, iterate upwards until we find an ancestor - # that doesn't; hopefully that's the root - if [[ -d $path/.svn ]] ; then - local search - search=$path - while [[ -n $search ]] ; do - if [[ -d ${search%/*}/.svn ]] ; then - search=${search%/*} - else - cd -- "$search" - return - fi - done - fi - - # Couldn't find repository root, say so - printf 'bash: %s: Failed to find repository root\n' \ - "$FUNCNAME" >&2 - return 1 -} diff --git a/sh/shrc.d/vr.sh b/sh/shrc.d/vr.sh new file mode 100644 index 00000000..b8a31aee --- /dev/null +++ b/sh/shrc.d/vr.sh @@ -0,0 +1,49 @@ +# Move to the root directory of a VCS working copy +vr() { + + # Set positional parameters to the result of trying to figure out the + # repository root + set -- "$( + + # Check we have at most one argument + if [ "$#" -gt 1 ] ; then + printf >&2 'vr(): Too many arguments\n' + exit 2 + fi + + # Get path from first argument, strip trailing slash + path=${1:-"$PWD"} + [ "$path" = / ] || path=${path%/} + + # Step into the directory + cd -- "$path" || exit + + # Ask Git the top level (good) + git rev-parse --show-toplevel 2>/dev/null && exit + + # Ask Mercurial the top level (great) + hg root 2>/dev/null && exit + + # If we can get SVN info, iterate upwards until we can't; hopefully + # that's the root (bad) + while svn info >/dev/null 2>&1 ; do + root=$PWD + [ "$root" = / ] && break + cd .. || exit + done + if [ -n "$root" ] ; then + printf '%s\n' "$root" + exit + fi + + # Couldn't find repository root, say so + printf >&2 'vr(): Failed to find repository root\n' + exit 1 + )" + + # Check we figured out a target, or bail + [ -n "$1" ] || return + + # Try to change into the determined directory + command cd -- "$@" +} |