Merge pull request #90 from rjorgenson/master

My prompt theme and a bugfix
diff --git a/aliases/available/maven.aliases.bash b/aliases/available/maven.aliases.bash
new file mode 100644
index 0000000..349f9d8
--- /dev/null
+++ b/aliases/available/maven.aliases.bash
@@ -0,0 +1,22 @@
+alias mci="mvn clean install"
+alias mi="mvn install"
+alias mrprep="mvn release:prepare"
+alias mrperf="mvn release:perform"
+alias mrrb="mvn release:rollback"
+alias mdep="mvn dependency:tree"
+alias mpom="mvn help:effective-pom"
+alias mcisk="mci -Dmaven.test.skip=true"
+
+function maven-help() {
+  echo "Maven Custom Aliases Usage"
+  echo
+  echo "  mci    = mvn clean install"
+  echo "  mi     = mvn install"
+  echo "  mrprep = mvn release:prepare"
+  echo "  mrperf = mvn release:perform"
+  echo "  mrrb   = mvn release:rollback"
+  echo "  mdep   = mvn dependency:tree"
+  echo "  mpom   = mvn help:effective-pom"
+  echo "  mcisk  = mvn clean install -Dmaven.test.skip=true"  
+  echo
+}
diff --git a/completion/available/defaults.completion.bash b/completion/available/defaults.completion.bash
new file mode 100644
index 0000000..5a8d034
--- /dev/null
+++ b/completion/available/defaults.completion.bash
@@ -0,0 +1,175 @@
+# defaults
+# Bash command line completion for defaults
+#
+# Created by Jonathon Mah on 2006-11-08.
+# Copyright 2006 Playhaus. All rights reserved.
+#
+# Version 1.0 (2006-11-08)
+
+
+_defaults_domains()
+{
+    local cur
+    COMPREPLY=()
+    cur=${COMP_WORDS[COMP_CWORD]}
+
+	local domains=$( defaults domains | sed -e 's/, /:/g' | tr : '\n' | sed -e 's/ /\\ /g' | grep -i "^$cur" )
+	local IFS=$'\n'
+	COMPREPLY=( $domains )
+	if [[ $( echo '-app' | grep "^$cur" ) ]]; then
+		COMPREPLY[${#COMPREPLY[@]}]="-app"
+	fi
+
+    return 0
+}
+
+
+_defaults()
+{
+	local cur prev host_opts cmds cmd domain keys key_index
+    cur=${COMP_WORDS[COMP_CWORD]}
+    prev=${COMP_WORDS[COMP_CWORD-1]}
+
+	host_opts='-currentHost -host'
+	cmds='read read-type write rename delete domains find help'
+
+	if [[ $COMP_CWORD -eq 1 ]]; then
+		COMPREPLY=( $( compgen -W "$host_opts $cmds" -- $cur ) )
+		return 0
+	elif [[ $COMP_CWORD -eq 2 ]]; then
+		if [[ "$prev" == "-currentHost" ]]; then
+			COMPREPLY=( $( compgen -W "$cmds" -- $cur ) )
+			return 0
+		elif [[ "$prev" == "-host" ]]; then
+			return 0
+			_known_hosts -a
+		else
+			_defaults_domains
+			return 0
+		fi
+	elif [[ $COMP_CWORD -eq 3 ]]; then
+		if [[ ${COMP_WORDS[1]} == "-host" ]]; then
+			_defaults_domains
+			return 0
+		fi
+    fi
+
+	# Both a domain and command have been specified
+
+	if [[ ${COMP_WORDS[1]} == [${cmds// /|}] ]]; then
+		cmd=${COMP_WORDS[1]}
+		domain=${COMP_WORDS[2]}
+		key_index=3
+		if [[ "$domain" == "-app" ]]; then
+			if [[ $COMP_CWORD -eq 3 ]]; then
+				# Completing application name. Can't help here, sorry
+				return 0
+			fi
+			domain="-app ${COMP_WORDS[3]}"
+			key_index=4
+		fi
+	elif [[ ${COMP_WORDS[2]} == "-currentHost" ]] && [[ ${COMP_WORDS[2]} == [${cmds// /|}] ]]; then
+		cmd=${COMP_WORDS[2]}
+		domain=${COMP_WORDS[3]}
+		key_index=4
+		if [[ "$domain" == "-app" ]]; then
+			if [[ $COMP_CWORD -eq 4 ]]; then
+				# Completing application name. Can't help here, sorry
+				return 0
+			fi
+			domain="-app ${COMP_WORDS[4]}"
+			key_index=5
+		fi
+	elif [[ ${COMP_WORDS[3]} == "-host" ]] && [[ ${COMP_WORDS[3]} == [${cmds// /|}] ]]; then
+		cmd=${COMP_WORDS[3]}
+		domain=${COMP_WORDS[4]}
+		key_index=5
+		if [[ "$domain" == "-app" ]]; then
+			if [[ $COMP_CWORD -eq 5 ]]; then
+				# Completing application name. Can't help here, sorry
+				return 0
+			fi
+			domain="-app ${COMP_WORDS[5]}"
+			key_index=6
+		fi
+	fi
+
+	keys=$( defaults read $domain 2>/dev/null | sed -n -e '/^    [^}) ]/p' | sed -e 's/^    \([^" ]\{1,\}\) = .*$/\1/g' -e 's/^    "\([^"]\{1,\}\)" = .*$/\1/g' | sed -e 's/ /\\ /g' )
+
+	case $cmd in
+	read|read-type)
+		# Complete key
+		local IFS=$'\n'
+		COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
+		;;
+	write)
+		if [[ $key_index -eq $COMP_CWORD ]]; then
+			# Complete key
+			local IFS=$'\n'
+			COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
+		elif [[ $((key_index+1)) -eq $COMP_CWORD ]]; then
+			# Complete value type
+			# Unfortunately ${COMP_WORDS[key_index]} fails on keys with spaces
+			local value_types='-string -data -integer -float -boolean -date -array -array-add -dict -dict-add'
+			local cur_type=$( defaults read-type $domain ${COMP_WORDS[key_index]} 2>/dev/null | sed -e 's/^Type is \(.*\)/-\1/' -e's/dictionary/dict/' | grep "^$cur" )
+			if [[ $cur_type ]]; then
+				COMPREPLY=( $cur_type )
+			else
+				COMPREPLY=( $( compgen -W "$value_types" -- $cur ) )
+			fi
+		elif [[ $((key_index+2)) -eq $COMP_CWORD ]]; then
+			# Complete value
+			# Unfortunately ${COMP_WORDS[key_index]} fails on keys with spaces
+			COMPREPLY=( $( defaults read $domain ${COMP_WORDS[key_index]} 2>/dev/null | grep -i "^${cur//\\/\\\\}" ) )
+		fi
+		;;
+	rename)
+		if [[ $key_index -eq $COMP_CWORD ]] ||
+		   [[ $((key_index+1)) -eq $COMP_CWORD ]]; then
+			# Complete source and destination keys
+			local IFS=$'\n'
+			COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
+		fi
+		;;
+	delete)
+		if [[ $key_index -eq $COMP_CWORD ]]; then
+			# Complete key
+			local IFS=$'\n'
+			COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
+		fi
+		;;
+	esac
+
+    return 0
+}
+
+complete -F _defaults -o default defaults
+
+
+# This file is licensed under the BSD license, as follows:
+#
+# Copyright (c) 2006, Playhaus
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Playhaus nor the names of its contributors may be
+#   used to endorse or promote products derived from this software without
+#   specific prior written permission.
+#
+# This software is provided by the copyright holders and contributors "as is"
+# and any express or implied warranties, including, but not limited to, the
+# implied warranties of merchantability and fitness for a particular purpose are
+# disclaimed. In no event shall the copyright owner or contributors be liable
+# for any direct, indirect, incidental, special, exemplary, or consequential
+# damages (including, but not limited to, procurement of substitute goods or
+# services; loss of use, data, or profits; or business interruption) however
+# caused and on any theory of liability, whether in contract, strict liability,
+# or tort (including negligence or otherwise) arising in any way out of the use
+# of this software, even if advised of the possibility of such damage.
diff --git a/completion/available/fabric-completion.bash b/completion/available/fabric-completion.bash
new file mode 100644
index 0000000..a4aa90f
--- /dev/null
+++ b/completion/available/fabric-completion.bash
@@ -0,0 +1,133 @@
+#!/bin/bash
+#
+# Bash completion support for Fabric (http://fabfile.org/)
+#
+#
+# Copyright (C) 2011 by Konstantin Bakulin
+#
+# 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.
+#
+# Thanks to:
+# - Adam Vandenberg,
+#   https://github.com/adamv/dotfiles/blob/master/completion_scripts/fab_completion.bash
+#
+# - Enrico Batista da Luz,
+#   https://github.com/ricobl/dotfiles/blob/master/bin/fab_bash_completion
+#
+
+
+# Use cache files for fab tasks or not.
+# If set to "false" command "fab --shortlist" will be executed every time.
+export FAB_COMPLETION_CACHE_TASKS=true
+
+# File name where tasks cache will be stored (in current dir).
+export FAB_COMPLETION_CACHED_TASKS_FILENAME=".fab_tasks~"
+
+
+# Set command to get time of last file modification as seconds since Epoch
+case `uname` in
+    Darwin|FreeBSD)
+        __FAB_COMPLETION_MTIME_COMMAND="stat -f '%m'"
+        ;;
+    *)
+        __FAB_COMPLETION_MTIME_COMMAND="stat -c '%Y'"
+        ;;
+esac
+
+
+#
+# Get time of last fab cache file modification as seconds since Epoch
+#
+function __fab_chache_mtime() {
+    ${__FAB_COMPLETION_MTIME_COMMAND} \
+        $FAB_COMPLETION_CACHED_TASKS_FILENAME | xargs -n 1 expr
+}
+
+
+#
+# Get time of last fabfile file/module modification as seconds since Epoch
+#
+function __fab_fabfile_mtime() {
+    local f="fabfile"
+    if [[ -e "$f.py" ]]; then
+        ${__FAB_COMPLETION_MTIME_COMMAND} "$f.py" | xargs -n 1 expr
+    else
+        # Suppose that it's a fabfile dir
+        find $f/*.py -exec ${__FAB_COMPLETION_MTIME_COMMAND} {} + \
+            | xargs -n 1 expr | sort -n -r | head -1
+    fi
+}
+
+
+#
+# Completion for "fab" command
+#
+function __fab_completion() {
+    # Return if "fab" command doesn't exists
+    [[ -e `which fab 2> /dev/null` ]] || return 0
+
+    # Variables to hold the current word and possible matches
+    local cur="${COMP_WORDS[COMP_CWORD]}"
+    local opts=()
+
+    # Generate possible matches and store them in variable "opts"
+    case "${cur}" in
+        -*)
+            if [[ -z "${__FAB_COMPLETION_LONG_OPT}" ]]; then
+                export __FAB_COMPLETION_LONG_OPT=$(
+                    fab --help | egrep -o "\-\-[A-Za-z_\-]+\=?" | sort -u)
+            fi
+            opts="${__FAB_COMPLETION_LONG_OPT}"
+            ;;
+
+        # Completion for short options is not nessary.
+        # It's left here just for history.
+        # -*)
+        #     if [[ -z "${__FAB_COMPLETION_SHORT_OPT}" ]]; then
+        #         export __FAB_COMPLETION_SHORT_OPT=$(
+        #             fab --help | egrep -o "^ +\-[A-Za-z_\]" | sort -u)
+        #     fi
+        #     opts="${__FAB_COMPLETION_SHORT_OPT}"
+        #     ;;
+
+        *)
+            # If "fabfile.py" or "fabfile" dir with "__init__.py" file exists
+            local f="fabfile"
+            if [[ -e "$f.py" || (-d "$f" && -e "$f/__init__.py") ]]; then
+                # Build a list of the available tasks
+                if $FAB_COMPLETION_CACHE_TASKS; then
+                    # If use cache
+                    if [[ ! -s ${FAB_COMPLETION_CACHED_TASKS_FILENAME} ||
+                          $(__fab_fabfile_mtime) -gt $(__fab_chache_mtime) ]]; then
+                        fab --shortlist > ${FAB_COMPLETION_CACHED_TASKS_FILENAME} \
+                            2> /dev/null
+                    fi
+                    opts=$(cat ${FAB_COMPLETION_CACHED_TASKS_FILENAME})
+                else
+                    # Without cache
+                    opts=$(fab --shortlist 2> /dev/null)
+                fi
+            fi
+            ;;
+    esac
+
+    # Set possible completions
+    COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
+}
+complete -o default -o nospace -F __fab_completion fab
diff --git a/completion/available/ssh.completion.bash b/completion/available/ssh.completion.bash
index 30fd65d..ea49026 100644
--- a/completion/available/ssh.completion.bash
+++ b/completion/available/ssh.completion.bash
@@ -13,7 +13,7 @@
     # parse all hosts found in .ssh/known_hosts
     if [ -r $HOME/.ssh/known_hosts ]; then
         if grep -v -q -e '^ ssh-rsa' $HOME/.ssh/known_hosts ; then
-        COMPREPLY=( $COMPREPLY $(compgen -W "$( awk '{print $1}' $HOME/.ssh/known_hosts | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" -- ${COMP_WORDS[COMP_CWORD]} )) 
+        COMPREPLY=( ${COMPREPLY[@]} $(compgen -W "$( awk '{print $1}' $HOME/.ssh/known_hosts | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" -- ${COMP_WORDS[COMP_CWORD]} )) 
         fi
     fi
     
diff --git a/completion/available/tmux.completion.bash b/completion/available/tmux.completion.bash
new file mode 100644
index 0000000..e8ee5e7
--- /dev/null
+++ b/completion/available/tmux.completion.bash
@@ -0,0 +1,189 @@
+#!/bin/bash
+
+# tmux completion
+# See: http://www.debian-administration.org/articles/317 for how to write more.
+# Usage: Put "source bash_completion_tmux.sh" into your .bashrc
+# Based upon the example at http://paste-it.appspot.com/Pj4mLycDE
+
+_tmux_expand () 
+{ 
+    [ "$cur" != "${cur%\\}" ] && cur="$cur"'\';
+    if [[ "$cur" == \~*/* ]]; then
+        eval cur=$cur;
+    else
+        if [[ "$cur" == \~* ]]; then
+            cur=${cur#\~};
+            COMPREPLY=($( compgen -P '~' -u $cur ));
+            return ${#COMPREPLY[@]};
+        fi;
+    fi
+}
+
+_tmux_filedir () 
+{ 
+    local IFS='
+';
+    _tmux_expand || return 0;
+    if [ "$1" = -d ]; then
+        COMPREPLY=(${COMPREPLY[@]} $( compgen -d -- $cur ));
+        return 0;
+    fi;
+    COMPREPLY=(${COMPREPLY[@]} $( eval compgen -f -- \"$cur\" ))
+}
+
+function _tmux_complete_client() {
+    local IFS=$'\n'
+    local cur="${1}"
+    COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$(tmux -q list-clients | cut -f 1 -d ':')" -- "${cur}") )
+}
+function _tmux_complete_session() {
+    local IFS=$'\n'
+    local cur="${1}"
+    COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$(tmux -q list-sessions | cut -f 1 -d ':')" -- "${cur}") )
+}
+function _tmux_complete_window() {
+    local IFS=$'\n'
+    local cur="${1}"
+    local session_name="$(echo "${cur}" | sed 's/\\//g' | cut -d ':' -f 1)"
+    local sessions
+    
+    sessions="$(tmux -q list-sessions | sed -re 's/([^:]+:).*$/\1/')"
+    if [[ -n "${session_name}" ]]; then
+        sessions="${sessions}
+$(tmux -q list-windows -t "${session_name}" | sed -re 's/^([^:]+):.*$/'"${session_name}"':\1/')"
+    fi
+    cur="$(echo "${cur}" | sed -e 's/:/\\\\:/')"
+    sessions="$(echo "${sessions}" | sed -e 's/:/\\\\:/')"
+    COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${sessions}" -- "${cur}") )
+}
+
+_tmux() {
+    local cur prev
+    local i cmd cmd_index option option_index
+    local opts=""
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+
+    if [ ${prev} == -f ]; then
+        _tmux_filedir
+    else
+    # Search for the command
+    local skip_next=0
+    for ((i=1; $i<=$COMP_CWORD; i++)); do
+        if [[ ${skip_next} -eq 1 ]]; then
+            #echo "Skipping"
+            skip_next=0;
+        elif [[ ${COMP_WORDS[i]} != -* ]]; then
+            cmd="${COMP_WORDS[i]}"
+            cmd_index=${i}
+            break
+        elif [[ ${COMP_WORDS[i]} == -f ]]; then
+            skip_next=1
+        fi
+    done
+
+    # Search for the last option command
+    skip_next=0
+    for ((i=1; $i<=$COMP_CWORD; i++)); do
+        if [[ ${skip_next} -eq 1 ]]; then
+            #echo "Skipping"
+            skip_next=0;
+        elif [[ ${COMP_WORDS[i]} == -* ]]; then
+            option="${COMP_WORDS[i]}"
+            option_index=${i}
+            if [[ ${COMP_WORDS[i]} == -- ]]; then
+                break;
+            fi
+        elif [[ ${COMP_WORDS[i]} == -f ]]; then
+            skip_next=1
+        fi
+    done
+
+    if [[ $COMP_CWORD -le $cmd_index ]]; then
+        # The user has not specified a command yet
+        local all_commands="$(tmux -q list-commands | cut -f 1 -d ' ')"
+        COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${all_commands}" -- "${cur}") )
+    else        
+        case ${cmd} in
+            attach-session|attach)
+            case "$prev" in
+                -t) _tmux_complete_session "${cur}" ;;
+                *) options="-t -d" ;;
+            esac ;;
+            detach-client|detach)
+            case "$prev" in
+                -t) _tmux_complete_client "${cur}" ;;
+                *) options="-t" ;;
+            esac ;;
+            lock-client|lockc)
+            case "$prev" in
+                -t) _tmux_complete_client "${cur}" ;;
+                *) options="-t" ;;
+            esac ;;
+            lock-session|locks)
+            case "$prev" in
+                -t) _tmux_complete_session "${cur}" ;;
+                *) options="-t -d" ;;
+            esac ;;
+            new-session|new)
+            case "$prev" in
+                -t) _tmux_complete_session "${cur}" ;;
+                -[n|d|s]) options="-d -n -s -t --" ;;
+                *) 
+                if [[ ${COMP_WORDS[option_index]} == -- ]]; then
+                    _command_offset ${option_index}
+                else
+                    options="-d -n -s -t --"
+                fi
+                ;;
+            esac
+            ;;
+            refresh-client|refresh)
+            case "$prev" in
+                -t) _tmux_complete_client "${cur}" ;;
+                *) options="-t" ;;
+            esac ;;
+            rename-session|rename)
+            case "$prev" in
+                -t) _tmux_complete_session "${cur}" ;;
+                *) options="-t" ;;
+            esac ;;
+            source-file|source) _tmux_filedir ;;
+            has-session|has|kill-session)
+            case "$prev" in
+                -t) _tmux_complete_session "${cur}" ;;
+                *) options="-t" ;;
+            esac ;;
+            suspend-client|suspendc)
+            case "$prev" in
+                -t) _tmux_complete_client "${cur}" ;;
+                *) options="-t" ;;
+            esac ;;
+            switch-client|switchc)
+            case "$prev" in
+                -c) _tmux_complete_client "${cur}" ;;
+                -t) _tmux_complete_session "${cur}" ;;
+                *) options="-l -n -p -c -t" ;;
+            esac ;;
+            
+            send-keys|send)
+            case "$option" in
+                -t) _tmux_complete_window "${cur}" ;;
+                *) options="-t" ;;
+            esac ;;
+          esac # case ${cmd}
+        fi # command specified
+      fi # not -f 
+            
+      if [[ -n "${options}" ]]; then
+          COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${options}" -- "${cur}") )
+      fi
+            
+      return 0
+
+}
+complete -F _tmux tmux
+
+# END tmux completion
+
diff --git a/lib/preexec.bash b/lib/preexec.bash
new file mode 100644
index 0000000..e092d82
--- /dev/null
+++ b/lib/preexec.bash
@@ -0,0 +1,195 @@
+#!/bin/bash
+# http://www.twistedmatrix.com/users/glyph/preexec.bash.txt
+# preexec.bash -- Bash support for ZSH-like 'preexec' and 'precmd' functions.
+
+# The 'preexec' function is executed before each interactive command is
+# executed, with the interactive command as its argument.  The 'precmd'
+# function is executed before each prompt is displayed.
+
+# To use, in order:
+
+#  1. source this file
+#  2. define 'preexec' and/or 'precmd' functions (AFTER sourcing this file),
+#  3. as near as possible to the end of your shell setup, run 'preexec_install'
+#     to kick everything off.
+
+# Note: this module requires 2 bash features which you must not otherwise be
+# using: the "DEBUG" trap, and the "PROMPT_COMMAND" variable.  preexec_install
+# will override these and if you override one or the other this _will_ break.
+
+# This is known to support bash3, as well as *mostly* support bash2.05b.  It
+# has been tested with the default shells on MacOS X 10.4 "Tiger", Ubuntu 5.10
+# "Breezy Badger", Ubuntu 6.06 "Dapper Drake", and Ubuntu 6.10 "Edgy Eft".
+
+
+# Copy screen-run variables from the remote host, if they're available.
+
+if [[ "$SCREEN_RUN_HOST" == "" ]]
+then
+    SCREEN_RUN_HOST="$LC_SCREEN_RUN_HOST"
+    SCREEN_RUN_USER="$LC_SCREEN_RUN_USER"
+fi
+
+# This variable describes whether we are currently in "interactive mode";
+# i.e. whether this shell has just executed a prompt and is waiting for user
+# input.  It documents whether the current command invoked by the trace hook is
+# run interactively by the user; it's set immediately after the prompt hook,
+# and unset as soon as the trace hook is run.
+preexec_interactive_mode=""
+
+# Default do-nothing implementation of preexec.
+function preexec () {
+    true
+}
+
+# Default do-nothing implementation of precmd.
+function precmd () {
+    true
+}
+
+# This function is installed as the PROMPT_COMMAND; it is invoked before each
+# interactive prompt display.  It sets a variable to indicate that the prompt
+# was just displayed, to allow the DEBUG trap, below, to know that the next
+# command is likely interactive.
+function preexec_invoke_cmd () {
+    precmd
+    preexec_interactive_mode="yes"
+}
+
+# This function is installed as the DEBUG trap.  It is invoked before each
+# interactive prompt display.  Its purpose is to inspect the current
+# environment to attempt to detect if the current command is being invoked
+# interactively, and invoke 'preexec' if so.
+function preexec_invoke_exec () {
+    if [[ -n "$COMP_LINE" ]]
+    then
+        # We're in the middle of a completer.  This obviously can't be
+        # an interactively issued command.
+        return
+    fi
+    if [[ -z "$preexec_interactive_mode" ]]
+    then
+        # We're doing something related to displaying the prompt.  Let the
+        # prompt set the title instead of me.
+        return
+    else
+        # If we're in a subshell, then the prompt won't be re-displayed to put
+        # us back into interactive mode, so let's not set the variable back.
+        # In other words, if you have a subshell like
+        #   (sleep 1; sleep 2)
+        # You want to see the 'sleep 2' as a set_command_title as well.
+        if [[ 0 -eq "$BASH_SUBSHELL" ]]
+        then
+            preexec_interactive_mode=""
+        fi
+    fi
+    if [[ "preexec_invoke_cmd" == "$BASH_COMMAND" ]]
+    then
+        # Sadly, there's no cleaner way to detect two prompts being displayed
+        # one after another.  This makes it important that PROMPT_COMMAND
+        # remain set _exactly_ as below in preexec_install.  Let's switch back
+        # out of interactive mode and not trace any of the commands run in
+        # precmd.
+
+        # Given their buggy interaction between BASH_COMMAND and debug traps,
+        # versions of bash prior to 3.1 can't detect this at all.
+        preexec_interactive_mode=""
+        return
+    fi
+
+    # In more recent versions of bash, this could be set via the "BASH_COMMAND"
+    # variable, but using history here is better in some ways: for example, "ps
+    # auxf | less" will show up with both sides of the pipe if we use history,
+    # but only as "ps auxf" if not.
+    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
+
+    # If none of the previous checks have earlied out of this function, then
+    # the command is in fact interactive and we should invoke the user's
+    # preexec hook with the running command as an argument.
+    preexec "$this_command"
+}
+
+# Execute this to set up preexec and precmd execution.
+function preexec_install () {
+
+    # *BOTH* of these options need to be set for the DEBUG trap to be invoked
+    # in ( ) subshells.  This smells like a bug in bash to me.  The null stderr
+    # redirections are to quiet errors on bash2.05 (i.e. OSX's default shell)
+    # where the options can't be set, and it's impossible to inherit the trap
+    # into subshells.
+
+    set -o functrace > /dev/null 2>&1
+    shopt -s extdebug > /dev/null 2>&1
+
+    # Finally, install the actual traps.
+    PROMPT_COMMAND="${PROMPT_COMMAND};preexec_invoke_cmd"
+    trap 'preexec_invoke_exec' DEBUG
+}
+
+# Since this is the reason that 99% of everybody is going to bother with a
+# pre-exec hook anyway, we'll include it in this module.
+
+# Change the title of the xterm.
+function preexec_xterm_title () {
+    local title="$1"
+    echo -ne "\033]0;$title\007" > /dev/stderr
+}
+
+function preexec_screen_title () {
+    local title="$1"
+    echo -ne "\033k$1\033\\" > /dev/stderr
+}
+
+# Abbreviate the "user@host" string as much as possible to preserve space in
+# screen titles.  Elide the host if the host is the same, elide the user if the
+# user is the same.
+function preexec_screen_user_at_host () {
+    local RESULT=""
+    if [[ "$SCREEN_RUN_HOST" == "$SCREEN_HOST" ]]
+    then
+        return
+    else
+        if [[ "$SCREEN_RUN_USER" == "$USER" ]]
+        then
+            echo -n "@${SCREEN_HOST}"
+        else
+            echo -n "${USER}@${SCREEN_HOST}"
+        fi
+    fi
+}
+
+function preexec_xterm_title_install () {
+    # These functions are defined here because they only make sense with the
+    # preexec_install below.
+    function precmd () {
+        preexec_xterm_title "${TERM} - ${USER}@${SCREEN_HOST} `dirs -0` $PROMPTCHAR"
+        if [[ "${TERM}" == screen ]]
+        then
+            preexec_screen_title "`preexec_screen_user_at_host`${PROMPTCHAR}"
+        fi
+    }
+
+    function preexec () {
+        preexec_xterm_title "${TERM} - $1 {`dirs -0`} (${USER}@${SCREEN_HOST})"
+        if [[ "${TERM}" == screen ]]
+        then
+            local cutit="$1"
+            local cmdtitle=`echo "$cutit" | cut -d " " -f 1`
+            if [[ "$cmdtitle" == "exec" ]]
+            then
+                local cmdtitle=`echo "$cutit" | cut -d " " -f 2`
+            fi
+            if [[ "$cmdtitle" == "screen" ]]
+            then
+                # Since stacked screens are quite common, it would be nice to
+                # just display them as '$$'.
+                local cmdtitle="${PROMPTCHAR}"
+            else
+                local cmdtitle=":$cmdtitle"
+            fi
+            preexec_screen_title "`preexec_screen_user_at_host`${PROMPTCHAR}$cmdtitle"
+        fi
+    }
+
+    preexec_install
+}
diff --git a/plugins/available/base.plugin.bash b/plugins/available/base.plugin.bash
index 7a6dc80..0a4e0c8 100644
--- a/plugins/available/base.plugin.bash
+++ b/plugins/available/base.plugin.bash
@@ -12,7 +12,7 @@
 
 function myip {
   res=$(curl -s checkip.dyndns.org | grep -Eo '[0-9\.]+')
-  echo "Your public IP is: ${bold_green} $res ${normal}"
+  echo -e "Your public IP is: ${echo_bold_green} $res ${echo_normal}"
 }
 
 pass() {
diff --git a/plugins/available/nvm.plugin.bash b/plugins/available/nvm.plugin.bash
index a5145ec..3f489dd 100644
--- a/plugins/available/nvm.plugin.bash
+++ b/plugins/available/nvm.plugin.bash
@@ -16,62 +16,61 @@
     export NVM_DIR=$(cd $(dirname ${BASH_SOURCE[0]:-$0}); pwd)
 fi
 
-# Emulate curl with wget, if necessary
-if [ ! `which curl` ]; then
-    if [ `which wget` ]; then
-        curl() {
-            ARGS="$* "
-            ARGS=${ARGS/-s /-q }
-            ARGS=${ARGS/-\# /}
-            ARGS=${ARGS/-C - /-c }
-            ARGS=${ARGS/-o /-O }
-
-            wget $ARGS
-        }
-    else
-        NOCURL='nocurl'
-        curl() { echo 'Need curl or wget to proceed.' >&2; }
-    fi
-fi
-
 # Expand a version using the version cache
 nvm_version()
 {
     PATTERN=$1
-    VERSION=''
+    # The default version is the current one
+    if [ ! "$PATTERN" ]; then
+        PATTERN='current'
+    fi
+
+    VERSION=`nvm_ls $PATTERN | tail -n1`
+    echo "$VERSION"
+
+    if [ "$VERSION" = 'N/A' ]; then
+        return 13
+    fi
+}
+
+nvm_ls()
+{
+    PATTERN=$1
+    VERSIONS=''
+    if [ "$PATTERN" = 'current' ]; then
+        echo `node -v 2>/dev/null`
+        return
+    fi
+
     if [ -f "$NVM_DIR/alias/$PATTERN" ]; then
         nvm_version `cat $NVM_DIR/alias/$PATTERN`
         return
     fi
     # If it looks like an explicit version, don't do anything funny
-    if [[ "$PATTERN" == v*.*.* ]]; then
-        VERSION="$PATTERN"
+    if [[ "$PATTERN" == v?*.?*.?* ]]; then
+        VERSIONS="$PATTERN"
+    else
+        VERSIONS=`(cd $NVM_DIR; \ls -d v${PATTERN}* 2>/dev/null) | sort -t. -k 1.2,1n -k 2,2n -k 3,3n`
     fi
-    # The default version is the current one
-    if [ ! "$PATTERN" -o "$PATTERN" = 'current' ]; then
-        VERSION=`node -v 2>/dev/null`
-    fi
-    if [ "$PATTERN" = 'stable' ]; then
-        PATTERN='*.*[02468].'
-    fi
-    if [ "$PATTERN" = 'latest' ]; then
-        PATTERN='*.*.'
-    fi
-    if [ "$PATTERN" = 'all' ]; then
-        (cd $NVM_DIR; \ls -dG v* 2>/dev/null || echo "N/A")
+    if [ ! "$VERSIONS" ]; then
+        echo "N/A"
         return
     fi
-    if [ ! "$VERSION" ]; then
-        VERSION=`(cd $NVM_DIR; \ls -d v${PATTERN}* 2>/dev/null) | sort -t. -k 2,1n -k 2,2n -k 3,3n | tail -n1`
-    fi
-    if [ ! "$VERSION" ]; then
-        echo "N/A"
-        return 13
-    elif [ -e "$NVM_DIR/$VERSION" ]; then
-        (cd $NVM_DIR; \ls -dG "$VERSION")
-    else
-        echo "$VERSION"
-    fi
+    echo "$VERSIONS"
+    return
+}
+
+print_versions()
+{
+    OUTPUT=''
+    for VERSION in $1; do
+        PADDED_VERSION=`printf '%10s' $VERSION`
+        if [[ -d "$NVM_DIR/$VERSION" ]]; then
+             PADDED_VERSION="\033[0;34m$PADDED_VERSION\033[0m"
+        fi
+        OUTPUT="$OUTPUT\n$PADDED_VERSION"
+    done
+    echo -e "$OUTPUT" | column
 }
 
 nvm()
@@ -90,30 +89,35 @@
       echo "    nvm install <version>       Download and install a <version>"
       echo "    nvm uninstall <version>     Uninstall a version"
       echo "    nvm use <version>           Modify PATH to use <version>"
-      echo "    nvm ls                      List versions (installed versions are blue)"
+      echo "    nvm run <version> [<args>]  Run <version> with <args> as arguments"
+      echo "    nvm ls                      List installed versions"
       echo "    nvm ls <version>            List versions matching a given description"
       echo "    nvm deactivate              Undo effects of NVM on current shell"
-      echo "    nvm sync                    Update the local cache of available versions"
       echo "    nvm alias [<pattern>]       Show all aliases beginning with <pattern>"
       echo "    nvm alias <name> <version>  Set an alias named <name> pointing to <version>"
       echo "    nvm unalias <name>          Deletes the alias named <name>"
       echo "    nvm copy-packages <version> Install global NPM packages contained in <version> to current version"
       echo
       echo "Example:"
-      echo "    nvm install v0.4.0          Install a specific version number"
-      echo "    nvm use stable              Use the stable release"
-      echo "    nvm install latest          Install the latest, possibly unstable version"
+      echo "    nvm install v0.4.12         Install a specific version number"
       echo "    nvm use 0.2                 Use the latest available 0.2.x release"
-      echo "    nvm alias default v0.4.0    Set v0.4.0 as the default"
+      echo "    nvm run 0.4.12 myApp.js     Run myApp.js using node v0.4.12"
+      echo "    nvm alias default 0.4       Auto use the latest installed v0.4.x version"
       echo
     ;;
     "install" )
+      if [ ! `which curl` ]; then
+        echo 'NVM Needs curl to proceed.' >&2;
+      fi
+
       if [ $# -ne 2 ]; then
         nvm help
         return
       fi
-      [ "$NOCURL" ] && curl && return
       VERSION=`nvm_version $2`
+
+      [ -d "$NVM_DIR/$VERSION" ] && echo "$VERSION is already installed." && return
+
       tarball=''
       if [ "`curl -Is "http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz" | grep '200 OK'`" != '' ]; then
         tarball="http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz"
@@ -124,7 +128,7 @@
         [ ! -z $tarball ] && \
         mkdir -p "$NVM_DIR/src" && \
         cd "$NVM_DIR/src" && \
-        curl -C - -# $tarball -o "node-$VERSION.tar.gz" && \
+        curl -C - --progress-bar $tarball -o "node-$VERSION.tar.gz" && \
         tar -xzf "node-$VERSION.tar.gz" && \
         cd "node-$VERSION" && \
         ./configure --prefix="$NVM_DIR/$VERSION" && \
@@ -136,8 +140,17 @@
         nvm use $VERSION
         if ! which npm ; then
           echo "Installing npm..."
-          # TODO: if node version 0.2.x add npm_install=0.2.19 before sh
-          curl http://npmjs.org/install.sh | clean=yes sh
+          if [[ "`expr match $VERSION '\(^v0\.1\.\)'`" != '' ]]; then
+            echo "npm requires node v0.2.3 or higher"
+          elif [[ "`expr match $VERSION '\(^v0\.2\.\)'`" != '' ]]; then
+            if [[ "`expr match $VERSION '\(^v0\.2\.[0-2]$\)'`" != '' ]]; then
+              echo "npm requires node v0.2.3 or higher"
+            else
+              curl http://npmjs.org/install.sh | clean=yes npm_install=0.2.19 sh
+            fi
+          else
+            curl http://npmjs.org/install.sh | clean=yes sh
+          fi
         fi
       else
         echo "nvm: install $VERSION failed!"
@@ -156,10 +169,9 @@
       fi
 
       # Delete all files related to target version.
-      (cd "$NVM_DIR" && \
-          rm -rf "node-$VERSION" 2>/dev/null && \
-          mkdir -p "$NVM_DIR/src" && \
+      (mkdir -p "$NVM_DIR/src" && \
           cd "$NVM_DIR/src" && \
+          rm -rf "node-$VERSION" 2>/dev/null && \
           rm -f "node-$VERSION.tar.gz" 2>/dev/null && \
           rm -rf "$NVM_DIR/$VERSION" 2>/dev/null)
       echo "Uninstalled node $VERSION"
@@ -170,8 +182,6 @@
         nvm unalias `basename $A`
       done
 
-      # Run sync in order to restore version stub file in $NVM_DIR.
-      nvm sync 1>/dev/null
     ;;
     "deactivate" )
       if [[ $PATH == *$NVM_DIR/*/bin* ]]; then
@@ -215,17 +225,27 @@
       export NVM_BIN="$NVM_DIR/$VERSION/bin"
       echo "Now using node $VERSION"
     ;;
-    "ls" )
-      if [ $# -ne 1 ]; then
-        nvm_version $2
+    "run" )
+      # run given version of node
+      if [ $# -lt 2 ]; then
+        nvm help
         return
       fi
-      nvm_version all
-      for P in {stable,latest,current}; do
-          echo -ne "$P: \t"; nvm_version $P
-      done
-      nvm alias
-      echo "# use 'nvm sync' to update from nodejs.org"
+      VERSION=`nvm_version $2`
+      if [ ! -d $NVM_DIR/$VERSION ]; then
+        echo "$VERSION version is not installed yet"
+        return;
+      fi
+      echo "Running node $VERSION"
+      $NVM_DIR/$VERSION/bin/node "${@:3}"
+    ;;
+    "ls" | "list" )
+      print_versions "`nvm_ls $2`"
+      if [ $# -eq 1 ]; then
+        echo -ne "current: \t"; nvm_version current
+        nvm alias
+      fi
+      return
     ;;
     "alias" )
       mkdir -p $NVM_DIR/alias
@@ -254,7 +274,6 @@
       echo $3 > "$NVM_DIR/alias/$2"
       if [ ! "$3" = "$VERSION" ]; then
           echo "$2 -> $3 (-> $VERSION)"
-          echo "! WARNING: Moving target. Aliases to implicit versions may change without warning."
       else
         echo "$2 -> $3"
       fi
@@ -266,21 +285,6 @@
       rm -f $NVM_DIR/alias/$2
       echo "Deleted alias $2"
     ;;
-    "sync" )
-        [ "$NOCURL" ] && curl && return
-        LATEST=`nvm_version latest`
-        STABLE=`nvm_version stable`
-        (cd $NVM_DIR
-        rm -f v* 2>/dev/null
-        printf "# syncing with nodejs.org..."
-        for VER in `curl -s http://nodejs.org/dist/ -o - | grep 'v[0-9].*' | sed -e 's/.*node-//' -e 's/\.tar\.gz.*//' -e 's/<[^>]*>//' -e 's/\/<[^>]*>.*//'`; do
-            touch $VER
-        done
-        echo " done."
-        )
-        [ "$STABLE" = `nvm_version stable` ] || echo "NEW stable: `nvm_version stable`"
-        [ "$LATEST" = `nvm_version latest` ] || echo "NEW latest: `nvm_version latest`"
-    ;;
     "copy-packages" )
         if [ $# -ne 2 ]; then
           nvm help
@@ -296,7 +300,7 @@
         echo "Cache cleared."
     ;;
     "version" )
-        nvm_version $2
+        print_versions "`nvm_version $2`"
     ;;
     * )
       nvm help
diff --git a/plugins/available/rbenv.plugin.bash b/plugins/available/rbenv.plugin.bash
new file mode 100644
index 0000000..bfac84d
--- /dev/null
+++ b/plugins/available/rbenv.plugin.bash
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# Load rbebv, if you are using it
+export PATH="$HOME/.rbenv/bin:$PATH"
+eval "$(rbenv init -)"
+
+# Load the auto-completion script if rbenv was loaded.
+source ~/.rbenv/completions/rbenv.bash
\ No newline at end of file
diff --git a/plugins/available/virtualenv.plugin.bash b/plugins/available/virtualenv.plugin.bash
index a0e7b3f..bb54e70 100644
--- a/plugins/available/virtualenv.plugin.bash
+++ b/plugins/available/virtualenv.plugin.bash
@@ -3,3 +3,8 @@
 # make sure virtualenvwrapper is enabled if availalbe
 [[ `which virtualenvwrapper.sh` ]] && . virtualenvwrapper.sh
 
+# create a new virtualenv for this directory
+function mkvenv {
+  cwd=`basename \`pwd\``
+  mkvirtualenv --no-site-packages --distribute $cwd
+}
diff --git a/plugins/available/xterm.plugins.bash b/plugins/available/xterm.plugins.bash
new file mode 100644
index 0000000..3e4ac9e
--- /dev/null
+++ b/plugins/available/xterm.plugins.bash
@@ -0,0 +1,17 @@
+set_xterm_title () {
+    local title="$1"
+    echo -ne "\e]0;$title\007"
+}
+
+
+precmd () {
+    set_xterm_title "${USER}@${HOSTNAME} `dirs -0` $PROMPTCHAR"
+}
+
+preexec () {
+    set_xterm_title "$1 {`dirs -0`} (${USER}@${HOSTNAME})"
+}
+
+case "$TERM" in
+    xterm*|rxvt*) preexec_install;;
+esac
diff --git a/plugins/available/z_autoenv.plugins.bash b/plugins/available/z_autoenv.plugins.bash
new file mode 100644
index 0000000..04efa85
--- /dev/null
+++ b/plugins/available/z_autoenv.plugins.bash
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+if [[ -n "${ZSH_VERSION}" ]]
+then __array_offset=0
+else __array_offset=1
+fi
+
+autoenv_init()
+{
+  typeset target home _file
+  typeset -a _files
+  target=$1
+  home="$(dirname $HOME)"
+
+  _files=( $(
+    while [[ "$PWD" != "/" && "$PWD" != "$home" ]]
+    do
+      _file="$PWD/.env"
+      if [[ -e "${_file}" ]]
+      then echo "${_file}"
+      fi
+      builtin cd ..
+    done
+  ) )
+
+  _file=${#_files[@]}
+  while (( _file > 0 ))
+  do
+    source "${_files[_file-__array_offset]}"
+    : $(( _file -= 1 ))
+  done
+}
+
+cd()
+{
+  if builtin cd "$@"
+  then
+    autoenv_init
+    return 0
+  else
+    echo "else?"
+    return $?
+  fi
+}
diff --git a/themes/base.theme.bash b/themes/base.theme.bash
index 05db36e..503fc57 100644
--- a/themes/base.theme.bash
+++ b/themes/base.theme.bash
@@ -24,6 +24,12 @@
 VIRTUALENV_THEME_PROMPT_PREFIX=' |'
 VIRTUALENV_THEME_PROMPT_SUFFIX='|'
 
+RBENV_THEME_PROMPT_PREFIX=' |'
+RBENV_THEME_PROMPT_SUFFIX='|'
+
+RBFU_THEME_PROMPT_PREFIX=' |'
+RBFU_THEME_PROMPT_SUFFIX='|'
+
 function scm {
   if [[ -d .git ]]; then SCM=$SCM_GIT
   elif [[ -n "$(git symbolic-ref HEAD 2> /dev/null)" ]]; then SCM=$SCM_GIT
@@ -113,6 +119,23 @@
   fi
 }
 
+function rbenv_version_prompt {
+  if which rbenv &> /dev/null; then
+    rbenv=$(rbenv global) || return
+    echo -e "$RBENV_THEME_PROMPT_PREFIX$rbenv$RBENV_THEME_PROMPT_SUFFIX"
+  fi
+}
+
+function rbfu_version_prompt {
+  if [[ $RBFU_RUBY_VERSION ]]; then
+    echo -e "${RBFU_THEME_PROMPT_PREFIX}${RBFU_RUBY_VERSION}${RBFU_THEME_PROMPT_SUFFIX}"
+  fi
+}
+
+function ruby_version_prompt {
+  echo -e "$(rbfu_version_prompt)$(rbenv_version_prompt)$(rvm_version_prompt)"
+}
+
 function virtualenv_prompt {
   if which virtualenv &> /dev/null; then
     virtualenv=$([ ! -z "$VIRTUAL_ENV" ] && echo "`basename $VIRTUAL_ENV`") || return
diff --git a/themes/bobby/bobby.theme.bash b/themes/bobby/bobby.theme.bash
index cb51fb8..4d15010 100644
--- a/themes/bobby/bobby.theme.bash
+++ b/themes/bobby/bobby.theme.bash
@@ -13,8 +13,8 @@
 RVM_THEME_PROMPT_SUFFIX="|"
 
 function prompt_command() {
-    #PS1="${bold_cyan}$(scm_char)${green}$(scm_prompt_info)${purple}$(rvm_version_prompt) ${yellow}\h ${reset_color}in ${green}\w ${reset_color}\n${green}→${reset_color} "
-    PS1="\n${yellow}$(rvm_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} "
+    #PS1="${bold_cyan}$(scm_char)${green}$(scm_prompt_info)${purple}$(ruby_version_prompt) ${yellow}\h ${reset_color}in ${green}\w ${reset_color}\n${green}→${reset_color} "
+    PS1="\n${yellow}$(ruby_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} "
 }
 
 PROMPT_COMMAND=prompt_command;
diff --git a/themes/colors.theme.bash b/themes/colors.theme.bash
index ff8776d..a04c8e4 100644
--- a/themes/colors.theme.bash
+++ b/themes/colors.theme.bash
@@ -1,44 +1,270 @@
 #!/bin/bash
 
-black="\[\e[0;30m\]"
-red="\[\e[0;31m\]"
-green="\[\e[0;32m\]"
-yellow="\[\e[0;33m\]"
-blue="\[\e[0;34m\]"
-purple="\[\e[0;35m\]"
-cyan="\[\e[0;36m\]"
-white="\[\e[1;37m\]"
-orange="\[\e[33;40m\]"
+function __ {
+  echo "$@"
+}
 
-bold_black="\[\e[1;30m\]"
-bold_red="\[\e[1;31m\]"
-bold_green="\[\e[1;32m\]"
-bold_yellow="\[\e[1;33m\]"
-bold_blue="\[\e[1;34m\]"
-bold_purple="\[\e[1;35m\]"
-bold_cyan="\[\e[1;36m\]"
-bold_white="\[\e[1;37m\]"
-bold_orange="\[\e[1;33;40m\]"
+function __make_ansi {
+  next=$1 && shift
+  echo "\[\e[$(__$next $@)m\]"
+}
 
-underline_black="\[\e[4;30m\]"
-underline_red="\[\e[4;31m\]"
-underline_green="\[\e[4;32m\]"
-underline_yellow="\[\e[4;33m\]"
-underline_blue="\[\e[4;34m\]"
-underline_purple="\[\e[4;35m\]"
-underline_cyan="\[\e[4;36m\]"
-underline_white="\[\e[4;37m\]"
-underline_orange="\[\e[4;33;40m\]"
-
-background_black="\[\e[40m\]"
-background_red="\[\e[41m\]"
-background_green="\[\e[42m\]"
-background_yellow="\[\e[43m\]"
-background_blue="\[\e[44m\]"
-background_purple="\[\e[45m\]"
-background_cyan="\[\e[46m\]"
-background_white="\[\e[47m\]"
+function __make_echo {
+  next=$1 && shift
+  echo "\033[$(__$next $@)m"
+}
 
 
-normal="\[\e[00m\]"
-reset_color="\[\e[39m\]"
+function __reset {
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "0${out:+;${out}}"
+}
+
+function __bold {
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "${out:+${out};}1"
+}
+
+function __faint {
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "${out:+${out};}2"
+}
+
+function __italic {
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "${out:+${out};}3"
+}
+
+function __underline {
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "${out:+${out};}4"
+}
+
+function __negative {
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "${out:+${out};}7"
+}
+
+function __crossed {
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "${out:+${out};}8"
+}
+
+
+function __color_normal_fg {
+  echo "3$1"
+}
+
+function __color_normal_bg {
+  echo "4$1"
+}
+
+function __color_bright_fg {
+  echo "9$1"
+}
+
+function __color_bright_bg {
+  echo "10$1"
+}
+
+
+function __color_black   {
+  echo "0"
+}
+
+function __color_red   {
+  echo "1"
+}
+
+function __color_green   {
+  echo "2"
+}
+
+function __color_yellow  {
+  echo "3"
+}
+
+function __color_blue  {
+  echo "4"
+}
+
+function __color_magenta {
+  echo "5"
+}
+
+function __color_cyan  {
+  echo "6"
+}
+
+function __color_white   {
+  echo "7"
+}
+
+function __color_rgb {
+  r=$1 && g=$2 && b=$3
+  [[ r == g && g == b ]] && echo $(( $r / 11 + 232 )) && return # gray range above 232
+  echo "8;5;$(( ($r * 36  + $b * 6 + $g) / 51 + 16 ))"
+}
+
+function __color {
+  color=$1 && shift
+  case "$1" in
+    fg|bg) side="$1" && shift ;;
+    *) side=fg;;
+  esac
+  case "$1" in
+    normal|bright) mode="$1" && shift;;
+    *) mode=normal;;
+  esac
+  [[ $color == "rgb" ]] && rgb="$1 $2 $3" && shift 3
+
+  next=$1 && shift
+  out="$(__$next $@)"
+  echo "$(__color_${mode}_${side} $(__color_${color} $rgb))${out:+;${out}}"
+}
+
+
+function __black   {
+  echo "$(__color black $@)"
+}
+
+function __red   {
+  echo "$(__color red $@)"
+}
+
+function __green   {
+  echo "$(__color green $@)"
+}
+
+function __yellow  {
+  echo "$(__color yellow $@)"
+}
+
+function __blue  {
+  echo "$(__color blue $@)"
+}
+
+function __magenta {
+  echo "$(__color magenta $@)"
+}
+
+function __cyan  {
+  echo "$(__color cyan $@)"
+}
+
+function __white   {
+  echo "$(__color white $@)"
+}
+
+function __rgb {
+  echo "$(__color rgb $@)"
+}
+
+
+function __color_parse {
+  next=$1 && shift
+  echo "$(__$next $@)"
+}
+
+function color {
+  echo "$(__color_parse make_ansi $@)"
+}
+
+function echo_color {
+  echo "$(__color_parse make_echo $@)"
+}
+
+
+black="$(color reset black)"
+red="$(color reset red)"
+green="$(color reset green)"
+yellow="$(color reset yellow)"
+blue="$(color reset blue)"
+purple="$(color reset magenta)"
+cyan="$(color reset cyan)"
+white="$(color reset white bold)"
+orange="$(color reset red fg bright)"
+
+bold_black="$(color black bold)"
+bold_red="$(color red bold)"
+bold_green="$(color green bold)"
+bold_yellow="$(color yellow bold)"
+bold_blue="$(color blue bold)"
+bold_purple="$(color magenta bold)"
+bold_cyan="$(color cyan bold)"
+bold_white="$(color white bold)"
+bold_orange="$(color red fg bright bold)"
+
+underline_black="$(color black underline)"
+underline_red="$(color red underline)"
+underline_green="$(color green underline)"
+underline_yellow="$(color yellow underline)"
+underline_blue="$(color blue underline)"
+underline_purple="$(color magenta underline)"
+underline_cyan="$(color cyan underline)"
+underline_white="$(color white underline)"
+underline_orange="$(color red fg bright underline)"
+
+background_black="$(color black bg)"
+background_red="$(color red bg)"
+background_green="$(color green bg)"
+background_yellow="$(color yellow bg)"
+background_blue="$(color blue bg)"
+background_purple="$(color magenta bg)"
+background_cyan="$(color cyan bg)"
+background_white="$(color white bg bold)"
+background_orange="$(color red bg bright)"
+
+normal="$(color reset)"
+reset_color="$(__make_ansi '' 39)"
+
+# These colors are meant to be used with `echo -e`
+echo_black="$(echo_color reset black)"
+echo_red="$(echo_color reset red)"
+echo_green="$(echo_color reset green)"
+echo_yellow="$(echo_color reset yellow)"
+echo_blue="$(echo_color reset blue)"
+echo_purple="$(echo_color reset magenta)"
+echo_cyan="$(echo_color reset cyan)"
+echo_white="$(echo_color reset white bold)"
+echo_orange="$(echo_color reset red fg bright)"
+
+echo_bold_black="$(echo_color black bold)"
+echo_bold_red="$(echo_color red bold)"
+echo_bold_green="$(echo_color green bold)"
+echo_bold_yellow="$(echo_color yellow bold)"
+echo_bold_blue="$(echo_color blue bold)"
+echo_bold_purple="$(echo_color magenta bold)"
+echo_bold_cyan="$(echo_color cyan bold)"
+echo_bold_white="$(echo_color white bold)"
+echo_bold_orange="$(echo_color red fg bright bold)"
+
+echo_underline_black="$(echo_color black underline)"
+echo_underline_red="$(echo_color red underline)"
+echo_underline_green="$(echo_color green underline)"
+echo_underline_yellow="$(echo_color yellow underline)"
+echo_underline_blue="$(echo_color blue underline)"
+echo_underline_purple="$(echo_color magenta underline)"
+echo_underline_cyan="$(echo_color cyan underline)"
+echo_underline_white="$(echo_color white underline)"
+echo_underline_orange="$(echo_color red fg bright underline)"
+
+echo_background_black="$(echo_color black bg)"
+echo_background_red="$(echo_color red bg)"
+echo_background_green="$(echo_color green bg)"
+echo_background_yellow="$(echo_color yellow bg)"
+echo_background_blue="$(echo_color blue bg)"
+echo_background_purple="$(echo_color magenta bg)"
+echo_background_cyan="$(echo_color cyan bg)"
+echo_background_white="$(echo_color white bg bold)"
+echo_background_orange="$(echo_color red bg bright)"
+
+echo_normal="$(echo_color reset)"
+echo_reset_color="$(__make_echo '' 39)"
diff --git a/themes/doubletime/doubletime.theme.bash b/themes/doubletime/doubletime.theme.bash
index c3bf453..c79ab5e 100644
--- a/themes/doubletime/doubletime.theme.bash
+++ b/themes/doubletime/doubletime.theme.bash
@@ -50,7 +50,7 @@
       clock=$THEME_PROMPT_CLOCK_FORMAT
   fi
   PS1="
-$clock $(scm_char) [$THEME_PROMPT_HOST_COLOR\u@${THEME_PROMPT_HOST}$reset_color] $(virtualenv_prompt)$(rvm_version_prompt)\w
+$clock $(scm_char) [$THEME_PROMPT_HOST_COLOR\u@${THEME_PROMPT_HOST}$reset_color] $(virtualenv_prompt)$(ruby_version_prompt)\w
 $(doubletime_scm_prompt)$reset_color $ "
   PS2='> '
   PS4='+ '
diff --git a/themes/doubletime_multiline/doubletime_multiline.theme.bash b/themes/doubletime_multiline/doubletime_multiline.theme.bash
new file mode 100644
index 0000000..b2215a8
--- /dev/null
+++ b/themes/doubletime_multiline/doubletime_multiline.theme.bash
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+source "$BASH_IT/themes/doubletime/doubletime.theme.bash"
+
+function prompt_setter() {
+  # Save history
+  history -a
+  history -c
+  history -r
+  if [[ -z "$THEME_PROMPT_CLOCK_FORMAT" ]]
+  then
+      clock="\t"
+  else
+      clock=$THEME_PROMPT_CLOCK_FORMAT
+  fi
+  PS1="
+$clock $(scm_char) [$THEME_PROMPT_HOST_COLOR\u@${THEME_PROMPT_HOST}$reset_color] $(virtualenv_prompt)$(ruby_version_prompt)
+\w
+$(doubletime_scm_prompt)$reset_color $ "
+  PS2='> '
+  PS4='+ '
+}
+
+PROMPT_COMMAND=prompt_setter
diff --git a/themes/envy/envy.theme.bash b/themes/envy/envy.theme.bash
new file mode 100644
index 0000000..d2f6a00
--- /dev/null
+++ b/themes/envy/envy.theme.bash
@@ -0,0 +1,16 @@
+#!/bin/bash
+SCM_THEME_PROMPT_DIRTY=" ${red}✗"
+SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓"
+SCM_THEME_PROMPT_PREFIX=" |"
+SCM_THEME_PROMPT_SUFFIX="${green}|"
+
+GIT_THEME_PROMPT_DIRTY=" ${red}✗"
+GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓"
+GIT_THEME_PROMPT_PREFIX=" ${green}|"
+GIT_THEME_PROMPT_SUFFIX="${green}|"
+
+function prompt_command() {
+    PS1="\n${yellow}$(ruby_version_prompt) ${purple}\h ${reset_color}in ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} "
+}
+
+PROMPT_COMMAND=prompt_command;
diff --git a/themes/hawaii50/hawaii50.theme.bash b/themes/hawaii50/hawaii50.theme.bash
index 93cef46..0b1fe3b 100644
--- a/themes/hawaii50/hawaii50.theme.bash
+++ b/themes/hawaii50/hawaii50.theme.bash
@@ -98,7 +98,7 @@
 # Displays virtual info prompt (virtualenv/rvm)
 function virtual_prompt_info() {
     local virtual_env_info=$(virtualenv_prompt)
-    local rvm_info=$(rvm_version_prompt)
+    local rvm_info=$(ruby_version_prompt)
     local virtual_prompt=""
 
     local prefix=${VIRTUAL_THEME_PROMPT_PREFIX}
diff --git a/themes/mbriggs/mbriggs.theme.bash b/themes/mbriggs/mbriggs.theme.bash
new file mode 100644
index 0000000..674085b
--- /dev/null
+++ b/themes/mbriggs/mbriggs.theme.bash
@@ -0,0 +1,34 @@
+# ------------------------------------------------------------------#
+#          FILE: mbriggs.zsh-theme                                  #
+#            BY: Matt Briggs (matt@mattbriggs.net)                  #
+#      BASED ON: smt by Stephen Tudor (stephen@tudorstudio.com)     #
+# ------------------------------------------------------------------#
+
+SCM_THEME_PROMPT_DIRTY="${red}⚡${reset_color}"
+SCM_THEME_PROMPT_AHEAD="${red}!${reset_color}"
+SCM_THEME_PROMPT_CLEAN="${green}✓${reset_color}"
+SCM_THEME_PROMPT_PREFIX=" "
+SCM_THEME_PROMPT_SUFFIX=""
+GIT_SHA_PREFIX=" ${yellow}"
+GIT_SHA_SUFFIX="${reset_color}"
+
+function git_short_sha() {
+  SHA=$(git rev-parse --short HEAD 2> /dev/null) && echo "$GIT_SHA_PREFIX$SHA$GIT_SHA_SUFFIX"
+}
+
+function prompt() {
+    local return_status=""
+    local ruby="${red}$(ruby_version_prompt)${reset_color}"
+    local user_host="${green}\h${reset_color}"
+    local current_path="\w"
+    local n_commands="\!"
+    local git_branch="$(git_short_sha)$(scm_prompt_info)"
+    local prompt_symbol='λ'
+    local open='('
+    local close=')'
+    local prompt_char=' \$ '
+
+    PS1="\n${n_commands} ${user_host} ${prompt_symbol} ${ruby} ${open}${current_path}${git_branch}${close}${return_status}\n${prompt_char}"
+}
+
+PROMPT_COMMAND=prompt
\ No newline at end of file
diff --git a/themes/pete/pete.theme.bash b/themes/pete/pete.theme.bash
index 7b6702c..cda451e 100644
--- a/themes/pete/pete.theme.bash
+++ b/themes/pete/pete.theme.bash
@@ -5,7 +5,7 @@
   history -a
   history -c
   history -r
-  PS1="(\t) $(scm_char) [$blue\u$reset_color@$green\H$reset_color] $yellow\w${reset_color}$(scm_prompt_info)$(rvm_version_prompt) $reset_color "
+  PS1="(\t) $(scm_char) [$blue\u$reset_color@$green\H$reset_color] $yellow\w${reset_color}$(scm_prompt_info)$(ruby_version_prompt) $reset_color "
   PS2='> '
   PS4='+ '
 }
diff --git a/themes/rainbowbrite/rainbowbrite.theme.bash b/themes/rainbowbrite/rainbowbrite.theme.bash
index e4424bb..1179230 100644
--- a/themes/rainbowbrite/rainbowbrite.theme.bash
+++ b/themes/rainbowbrite/rainbowbrite.theme.bash
@@ -11,9 +11,9 @@
   history -c
   history -r
   # displays user@server in purple
-  # PS1="$red$(scm_char) $purple\u@\h$reset_color:$blue\w$yellow$(scm_prompt_info)$(rvm_version_prompt) $black\$$reset_color "
+  # PS1="$red$(scm_char) $purple\u@\h$reset_color:$blue\w$yellow$(scm_prompt_info)$(ruby_version_prompt) $black\$$reset_color "
   # no user@server
-  PS1="$red$(scm_char) $blue\w$yellow$(scm_prompt_info)$(rvm_version_prompt) $black\$$reset_color "
+  PS1="$red$(scm_char) $blue\w$yellow$(scm_prompt_info)$(ruby_version_prompt) $black\$$reset_color "
   PS2='> '
   PS4='+ '
 }
diff --git a/themes/tylenol/tylenol.theme.bash b/themes/tylenol/tylenol.theme.bash
index c915f56..d8b63ef 100644
--- a/themes/tylenol/tylenol.theme.bash
+++ b/themes/tylenol/tylenol.theme.bash
@@ -14,7 +14,7 @@
 VIRTUALENV_THEME_PROMPT_SUFFIX='|'
 
 function prompt_command() {
-    PS1="\n${green}$(virtualenv_prompt)${red}$(rvm_version_prompt) ${reset_color}\h ${orange}in ${reset_color}\w\n${yellow}$(scm_char)$(scm_prompt_info) ${yellow}→${white} "
+    PS1="\n${green}$(virtualenv_prompt)${red}$(ruby_version_prompt) ${reset_color}\h ${orange}in ${reset_color}\w\n${yellow}$(scm_char)$(scm_prompt_info) ${yellow}→${white} "
 }
 
 PROMPT_COMMAND=prompt_command;