Merge remote-tracking branch 'erichs/master'
diff --git a/bash_it.sh b/bash_it.sh
old mode 100644
new mode 100755
index 8564c88..cd97ab3
--- a/bash_it.sh
+++ b/bash_it.sh
@@ -21,6 +21,9 @@
     unset $BASH_THEME;
 fi
 
+# Load composure first, so we support function metadata
+source "${BASH_IT}/lib/composure.sh"
+
 # Load colors first so they can be use in base theme
 source "${BASH_IT}/themes/colors.theme.bash"
 source "${BASH_IT}/themes/base.theme.bash"
diff --git a/lib/composure.sh b/lib/composure.sh
new file mode 100755
index 0000000..b4b740b
--- /dev/null
+++ b/lib/composure.sh
@@ -0,0 +1,213 @@
+#!/bin/bash
+# Composure - don't fear the UNIX chainsaw...
+# by erichs, 2012
+
+# these are a set of light-hearted shell functions that aim to make
+# programming the shell easier and more intuitive
+
+# latest source available at http://git.io/composure
+
+source_composure ()
+{
+    if [ -z "$EDITOR" ]
+    then
+      export EDITOR=vi
+    fi
+
+    if $(tty -s)    # is this a TTY?
+    then
+      bind '"\C-j": edit-and-execute-command'
+    fi
+
+    cite ()
+    {
+        about () { :; }
+        about creates a new meta keyword for use in your functions
+        local keyword=$1
+        for keyword in $*; do
+            eval "function $keyword { :; }"
+        done
+    }
+
+    cite about param example
+
+    draft ()
+    {
+      about wraps last command into a new function
+      param 1: name to give function
+      example $ ls
+      example $ draft list
+      example $ list
+      local name=$1
+      eval 'function ' $name ' { ' $(fc -ln -1) '; }'
+    }
+
+    write ()
+    {
+      about prints function declaration to stdout
+      param name of function or functions, separated by spaces
+      example $ write myfunction
+      example $ write func1 func2 func3 > ~/funcs.sh
+      local func
+      for func in $*
+      do
+          # trim trailing semicolons generated by declare -f
+          declare -f $func | sed  "s/^\(.*\);$/\1/"
+          echo
+      done
+    }
+
+    revise ()
+    {
+        about loads function into editor for revision
+        param name of function or functions, separated by spaces
+        example $ revise myfunction
+        example $ revise func1 func2 func3
+        local temp=$(mktemp /tmp/revise.XXXX)
+        write $* > $temp
+        $EDITOR $temp
+        eval "$(cat $temp)"
+        rm $temp
+    }
+
+    metafor ()
+    {
+        about prints function metadata associated with keyword
+        param 1: function name
+        param 2: meta keyword
+        example $ metafor reference example
+        local func=$1 keyword=$2
+        write $func | sed -n "s/^ *$keyword \([^([].*\)$/\1/p"
+    }
+
+    reference ()
+    {
+        about displays help summary for all functions, or help for specific function
+        param 1: optional, function name
+        example $ reference
+        example $ reference metafor
+
+        printline ()
+        {
+            local metadata=$1 lhs=${2:- }
+
+            if [[ -z "$metadata" ]]
+            then
+                return
+            fi
+
+            OLD=$IFS; IFS=$'\n'
+            local line
+            for line in $metadata
+            do
+                printf "%-20s%s\n" $lhs $line
+            done
+            IFS=$OLD
+        }
+
+        help ()
+        {
+            local func=$1
+
+            local about="$(metafor $func about)"
+            printline "$about" $func
+
+            local params="$(metafor $func param)"
+            if [[ -n "$params" ]]
+            then
+                echo "parameters:"
+                printline "$params"
+            fi
+
+            local examples="$(metafor $func example)"
+            if [[ -n "$examples" ]]
+            then
+                echo "examples:"
+                printline "$examples"
+            fi
+
+            unset printline
+        }
+
+        if [[ -n "$1" ]]
+        then
+            help $1
+        else
+            for func in $(compgen -A function); do
+                local about="$(metafor $func about)"
+                printline "$about" $func
+            done
+        fi
+
+        unset help printline
+    }
+
+}
+
+install_composure ()
+{
+    echo 'stay calm. installing composure elements...'
+
+    # find our absolute PATH
+    SOURCE="${BASH_SOURCE[0]}"
+    while [ -h "$SOURCE" ]
+    do
+        SOURCE="$(readlink "$SOURCE")"
+    done
+    DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+    # vim: automatically chmod +x scripts with #! lines
+    done_previously () { [ ! -z "$(grep BufWritePost | grep bin | grep chmod)" ]; }
+
+    if [ -f ~/.vimrc ] && ! $(<~/.vimrc done_previously)
+    then
+      echo 'vimrc: adding automatic chmod+x for files with shebang (#!) lines...'
+      echo 'au BufWritePost * if getline(1) =~ "^#!" | if getline(1) =~ "/bin/" | silent execute "!chmod a+x <afile>" | endif | endif' >> ~/.vimrc
+    fi
+
+    # source this file in your startup: .bashrc, or .bash_profile
+    local done=0
+    done_previously () { [ ! -z "$(grep source | grep $DIR | grep composure)" ]; }
+
+    [ -f ~/.bashrc ] && $(<~/.bashrc done_previously) && done=1
+    ! (($done)) && [ -f ~/.bash_profile ] && $(<~/.bash_profile done_previously) && done=1
+
+    if ! (($done))
+    then
+      echo 'sourcing composure from .bashrc...'
+      echo "source $DIR/$(basename $0)" >> ~/.bashrc
+    fi
+
+    echo 'composure installed.'
+}
+
+if [[ "$BASH_SOURCE" == "$0" ]]
+then
+  install_composure
+else
+  source_composure
+  unset install_composure source_composure
+fi
+
+: <<EOF
+License: The MIT License
+
+Copyright © 2012 Erich Smith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this
+software and associated documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be included in all copies
+or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+EOF
diff --git a/plugins/available/base.plugin.bash b/plugins/available/base.plugin.bash
old mode 100644
new mode 100755
index 3edd8ad..0447f33
--- a/plugins/available/base.plugin.bash
+++ b/plugins/available/base.plugin.bash
@@ -2,84 +2,125 @@
 
 # For generic functions.
 
-function ips {
-  ifconfig | grep "inet " | awk '{ print $2 }'
+ips ()
+{
+    about display all ip addresses for this host
+    ifconfig | grep "inet " | awk '{ print $2 }'
 }
 
-function down4me() {
-  curl -s "http://www.downforeveryoneorjustme.com/$1" | sed '/just you/!d;s/<[^>]*>//g'
+down4me ()
+{
+    about checks whether a website is down for you, or everybody
+    param 1: website url
+    example $ down4me http://www.google.com
+    curl -s "http://www.downforeveryoneorjustme.com/$1" | sed '/just you/!d;s/<[^>]*>//g'
 }
 
-function myip {
-  res=$(curl -s checkip.dyndns.org | grep -Eo '[0-9\.]+')
-  echo -e "Your public IP is: ${echo_bold_green} $res ${echo_normal}"
-}
-
-pass() {
-  which gshuf &> /dev/null
-  if [ $? -eq 1 ]
-  then
-    echo "Error: shuf isn't installed!"
-    return 1
-  fi
-
-  pass=$(shuf -n4 /usr/share/dict/words | tr '\n' ' ')
-  echo "With spaces (easier to memorize): $pass"
-  echo "Without (use this as the pass): $(echo $pass | tr -d ' ')"
-}
-
-# Function for previewing markdown files in the browser
-
-function pmdown() {
-  if command -v markdown &>/dev/null
-  then
-    markdown $1 | browser
-  else
-    echo "You don't have a markdown command installed!"
-  fi
-}
-
-# Make a directory and immediately 'cd' into it
-
-function mkcd() {
-  mkdir -p "$*"
-  cd "$*"
-}
-
-# Search through directory contents with grep
-
-function lsgrep(){
-  ls | grep "$*"
-}
-
-# View man documentation in Preview
-pman () {
-   man -t "${1}" | open -f -a $PREVIEW
+myip ()
+{
+    about displays your ip address, as seen by the Internet
+    res=$(curl -s checkip.dyndns.org | grep -Eo '[0-9\.]+')
+    echo -e "Your public IP is: ${echo_bold_green} $res ${echo_normal}"
 }
 
 
-pcurl() {
-  curl "${1}" | open -f -a $PREVIEW
+pickfrom ()
+{
+    about picks random line from file
+    param 1: filename
+    example $ pickfrom /usr/share/dict/words
+    local file=$1
+    [ -z "$file" ] && reference $FUNCNAME && return
+    length=$(cat $file | wc -l)
+    n=$(expr $RANDOM \* $length \/ 32768 + 1)
+    head -n $n $file | tail -1
 }
 
-pri() {
-  ri -T "${1}" | open -f -a $PREVIEW
+pass ()
+{
+    about generates random password from dictionary words
+    param optional integer length
+    param if unset, defaults to 4
+    example $ pass
+    example $ pass 6
+    local i pass length=${1:-4}
+    pass=$(echo $(for i in $(eval echo "{1..$length}"); do pickfrom /usr/share/dict/words; done))
+    echo "With spaces (easier to memorize): $pass"
+    echo "Without (use this as the pass): $(echo $pass | tr -d ' ')"
 }
 
-quiet() {
+pmdown ()
+{
+    about preview markdown file in a browser
+    param 1: markdown file
+    example $ pmdown README.md
+    if command -v markdown &>/dev/null
+    then
+      markdown $1 | browser
+    else
+      echo "You don't have a markdown command installed!"
+    fi
+}
+
+mkcd ()
+{
+    about make a directory and cd into it
+    param path to create
+    example $ mkcd foo
+    example $ mkcd /tmp/img/photos/large
+    mkdir -p "$*"
+    cd "$*"
+}
+
+lsgrep ()
+{
+    about search through directory contents with grep
+    ls | grep "$*"
+}
+
+
+pman ()
+{
+    about view man documentation in Preview
+    param 1: man page to view
+    example $ pman bash
+    man -t "${1}" | open -f -a $PREVIEW
+}
+
+
+pcurl ()
+{
+    about download file and Preview it
+    param 1: download URL
+    example $ pcurl http://www.irs.gov/pub/irs-pdf/fw4.pdf
+    curl "${1}" | open -f -a $PREVIEW
+}
+
+pri ()
+{
+    about display information about Ruby classes, modules, or methods, in Preview
+    param 1: Ruby method, module, or class
+    example $ pri Array
+    ri -T "${1}" | open -f -a $PREVIEW
+}
+
+quiet ()
+{
 	$* &> /dev/null &
 }
 
-banish-cookies() {
+banish-cookies ()
+{
+    about redirect .adobe and .macromedia files to /dev/null
 	rm -r ~/.macromedia ~/.adobe
 	ln -s /dev/null ~/.adobe
 	ln -s /dev/null ~/.macromedia
 }
 
-# disk usage per directory
-# in Mac OS X and Linux
 usage ()
 {
+    about disk usage per directory, in Mac OS X and Linux
+    param 1: directory name
     if [ $(uname) = "Darwin" ]; then
         if [ -n $1 ]; then
             du -hd $1
@@ -96,25 +137,31 @@
     fi
 }
 
-# One thing todo
-function t() {
-	 if [[ "$*" == "" ]] ; then
-		 cat ~/.t
-	 else
-		 echo "$*" > ~/.t
-	 fi
+t ()
+{
+    about one thing todo
+    param if not set, display todo item
+    param 1: todo text
+	if [[ "$*" == "" ]] ; then
+	    cat ~/.t
+	else
+	    echo "$*" > ~/.t
+	fi
 }
 
-# Checks for existence of a command
-command_exists () {
+command_exists ()
+{
+    about checks for existence of a command
+    param 1: command to check
+    example $ command_exists ls && echo 'exists'
     type "$1" &> /dev/null ;
 }
 
-# List all plugins and functions defined by bash-it
-function plugins-help() {
-    
+plugins-help ()
+{
+    about list all plugins and functions defined by bash-it
     echo "bash-it Plugins Help-Message"
-    echo 
+    echo
 
     set | grep "()" \
     | sed -e "/^_/d" | grep -v "BASH_ARGC=()" \
@@ -128,10 +175,12 @@
     | grep -v "COMPREPLY=()" | sed -e "s/()//"
 }
 
-# back up file with timestamp
 # useful for administrators and configs
-buf () {
-    filename=$1
-    filetime=$(date +%Y%m%d_%H%M%S)
+buf ()
+{
+    about back up file with timestamp
+    param filename
+    local filename=$1
+    local filetime=$(date +%Y%m%d_%H%M%S)
     cp ${filename} ${filename}_${filetime}
 }
diff --git a/themes/base.theme.bash b/themes/base.theme.bash
index fe112ec..15bd4aa 100644
--- a/themes/base.theme.bash
+++ b/themes/base.theme.bash
@@ -121,7 +121,7 @@
 
 function rbenv_version_prompt {
   if which rbenv &> /dev/null; then
-    rbenv=$(rbenv global) || return
+    rbenv=$(rbenv version-name) || return
     echo -e "$RBENV_THEME_PROMPT_PREFIX$rbenv$RBENV_THEME_PROMPT_SUFFIX"
   fi
 }
diff --git a/themes/zork/zork.theme.bash b/themes/zork/zork.theme.bash
index f541c0d..c71f134 100644
--- a/themes/zork/zork.theme.bash
+++ b/themes/zork/zork.theme.bash
@@ -53,6 +53,8 @@
             ;;
     "pandora") my_ps_host="${red}\h${normal}";
             ;;
+    * ) my_ps_host="${green}\h${normal}";
+            ;;
     esac
 
     my_ps_user="\[\033[01;32m\]\u\[\033[00m\]";