aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2016-08-20 16:26:06 +1200
committerTom Ryder <tom@sanctum.geek.nz>2016-08-20 16:26:39 +1200
commit6e3fd021588c87a0743dbc1ec5b3f5aba900f839 (patch)
tree74a790cf3a96c7f55660c612964462f194aa20ce
parentAssume POSIX sh (diff)
downloaddotfiles-6e3fd021588c87a0743dbc1ec5b3f5aba900f839.tar.gz
dotfiles-6e3fd021588c87a0743dbc1ec5b3f5aba900f839.zip
Port vr(1) to POSIX sh
-rw-r--r--ISSUES.markdown3
-rw-r--r--README.markdown4
-rw-r--r--bash/bashrc.d/vr.bash59
-rw-r--r--sh/shrc.d/vr.sh49
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 -- "$@"
+}