diff --git a/README.textile b/README.textile index 0a4545bac..1916d9f4e 100644 --- a/README.textile +++ b/README.textile @@ -1,5 +1,4 @@ -A handful of functions, auto-complete helpers, and stuff that makes you shout... - +oh-my-zsh is an open source, community-driven framework for managing your ZSH configuration. It comes bundled with a ton of helpful functions, helpers, plugins, themes, and few things that make you shout... bq. "OH MY ZSHELL!" @@ -63,6 +62,17 @@ If you want to override any of the default behavior, just add a new file (ending If you have many functions which go well together you can put them as a *.plugin.zsh file in the @custom/plugins/@ directory and then enable this plugin. If you would like to override the functionality of a plugin distributed with oh-my-zsh, create a plugin of the same name in the @custom/plugins/@ directory and it will be loaded instead of the one in @plugins/@. +h3. Updates + +By default you will be prompted to check for updates. If you would like oh-my-zsh to automatically update itself without prompting you, set the following in your ~/.zshrc + +@DISABLE_UPDATE_PROMPT=true@ + +To disable updates entirely, put this in your ~/.zshrc + +@DISABLE_AUTO_UPDATE=true@ + +To upgrade directly from the command line, just run @upgrade_oh_my_zsh@ h3. Uninstalling @@ -76,9 +86,7 @@ h3. (Don't) Send us your theme! (for now) -I'm hoping to collect a bunch of themes for our command prompts. You can see existing ones in the @themes/@ directory.- -We have enough themes for the time being. Please fork the project and add on in there, you can let people know how to grab it from there. - - +We have enough themes for the time being. Please fork the project and add on in there, you can let people know how to grab it from there. h2. Contributors diff --git a/lib/aliases.zsh b/lib/aliases.zsh index a7f699c19..9b3709172 100644 --- a/lib/aliases.zsh +++ b/lib/aliases.zsh @@ -17,7 +17,7 @@ alias history='fc -l 1' # List direcory contents alias lsa='ls -lah' -alias l='ls -lA1' +alias l='ls -la' alias ll='ls -l' alias la='ls -lA' alias sl=ls # often screw this up diff --git a/lib/completion.zsh b/lib/completion.zsh index ba839a067..e0cdcf626 100644 --- a/lib/completion.zsh +++ b/lib/completion.zsh @@ -34,8 +34,10 @@ cdpath=(.) # use /etc/hosts and known_hosts for hostname completion [ -r /etc/ssh/ssh_known_hosts ] && _global_ssh_hosts=(${${${${(f)"$( /dev/null) || \ - ref=$(git rev-parse --short HEAD 2> /dev/null) || return + ref=$(command git symbolic-ref HEAD 2> /dev/null) || \ + ref=$(command git rev-parse --short HEAD 2> /dev/null) || return echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX" } @@ -11,25 +11,31 @@ parse_git_dirty() { local SUBMODULE_SYNTAX='' local GIT_STATUS='' local CLEAN_MESSAGE='nothing to commit (working directory clean)' - if [[ "$(git config --get oh-my-zsh.hide-status)" != "1" ]]; then + if [[ "$(command git config --get oh-my-zsh.hide-status)" != "1" ]]; then if [[ $POST_1_7_2_GIT -gt 0 ]]; then SUBMODULE_SYNTAX="--ignore-submodules=dirty" - fi - GIT_STATUS=$(git status -s ${SUBMODULE_SYNTAX} 2> /dev/null | tail -n1) - if [[ -n $GIT_STATUS && "$GIT_STATUS" != "$CLEAN_MESSAGE" ]]; then + fi + if [[ "$DISABLE_UNTRACKED_FILES_DIRTY" == "true" ]]; then + GIT_STATUS=$(command git status -s ${SUBMODULE_SYNTAX} -uno 2> /dev/null | tail -n1) + else + GIT_STATUS=$(command git status -s ${SUBMODULE_SYNTAX} 2> /dev/null | tail -n1) + fi + if [[ -n $GIT_STATUS ]]; then echo "$ZSH_THEME_GIT_PROMPT_DIRTY" else echo "$ZSH_THEME_GIT_PROMPT_CLEAN" - fi - fi + fi + else + echo "$ZSH_THEME_GIT_PROMPT_CLEAN" + fi } # get the difference between the local and remote branches git_remote_status() { - remote=${$(git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/} + remote=${$(command git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/} if [[ -n ${remote} ]] ; then - ahead=$(git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l) - behind=$(git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l) + ahead=$(command git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l) + behind=$(command git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l) if [ $ahead -eq 0 ] && [ $behind -gt 0 ] then @@ -46,24 +52,24 @@ git_remote_status() { # Checks if there are commits ahead from remote function git_prompt_ahead() { - if $(echo "$(git log origin/$(current_branch)..HEAD 2> /dev/null)" | grep '^commit' &> /dev/null); then + if $(echo "$(command git log origin/$(current_branch)..HEAD 2> /dev/null)" | grep '^commit' &> /dev/null); then echo "$ZSH_THEME_GIT_PROMPT_AHEAD" fi } # Formats prompt string for current git commit short SHA function git_prompt_short_sha() { - SHA=$(git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" + SHA=$(command git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" } # Formats prompt string for current git commit long SHA function git_prompt_long_sha() { - SHA=$(git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" + SHA=$(command git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" } # Get the status of the working tree git_prompt_status() { - INDEX=$(git status --porcelain -b 2> /dev/null) + INDEX=$(command git status --porcelain -b 2> /dev/null) STATUS="" if $(echo "$INDEX" | grep -E '^\?\? ' &> /dev/null); then STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS" @@ -90,7 +96,7 @@ git_prompt_status() { elif $(echo "$INDEX" | grep '^AD ' &> /dev/null); then STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" fi - if $(git rev-parse --verify refs/stash >/dev/null 2>&1); then + if $(command git rev-parse --verify refs/stash >/dev/null 2>&1); then STATUS="$ZSH_THEME_GIT_PROMPT_STASHED$STATUS" fi if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then @@ -115,7 +121,7 @@ function git_compare_version() { local INPUT_GIT_VERSION=$1; local INSTALLED_GIT_VERSION INPUT_GIT_VERSION=(${(s/./)INPUT_GIT_VERSION}); - INSTALLED_GIT_VERSION=($(git --version 2>/dev/null)); + INSTALLED_GIT_VERSION=($(command git --version 2>/dev/null)); INSTALLED_GIT_VERSION=(${(s/./)INSTALLED_GIT_VERSION[3]}); for i in {1..3}; do diff --git a/lib/rbenv.zsh b/lib/rbenv.zsh new file mode 100644 index 000000000..a8b6c323c --- /dev/null +++ b/lib/rbenv.zsh @@ -0,0 +1,2 @@ +# using the rbenv plugin will override this with a real implementation +function rbenv_prompt_info() {} diff --git a/lib/termsupport.zsh b/lib/termsupport.zsh index c056989eb..80319e1a8 100644 --- a/lib/termsupport.zsh +++ b/lib/termsupport.zsh @@ -8,7 +8,7 @@ function title { fi if [[ "$TERM" == screen* ]]; then print -Pn "\ek$1:q\e\\" #set screen hardstatus, usually truncated at 20 chars - elif [[ "$TERM" == xterm* ]] || [[ $TERM == rxvt* ]] || [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then + elif [[ "$TERM" == xterm* ]] || [[ $TERM == rxvt* ]] || [[ $TERM == ansi ]] || [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then print -Pn "\e]2;$2:q\a" #set window name print -Pn "\e]1;$1:q\a" #set icon (=tab) name (will override window name on broken terminal) fi @@ -27,7 +27,9 @@ function omz_termsupport_preexec { emulate -L zsh setopt extended_glob local CMD=${1[(wr)^(*=*|sudo|ssh|rake|-*)]} #cmd name only, or if this is sudo or ssh, the next cmd - title "$CMD" "%100>...>${2:gs/%/%%}%<<" + local LINE="${2:gs/$/\\$}" + LINE="${LINE:gs/%/%%}" + title "$CMD" "%100>...>$LINE%<<" } autoload -U add-zsh-hook diff --git a/oh-my-zsh.sh b/oh-my-zsh.sh index 5b8e63e73..93c10e3d2 100644 --- a/oh-my-zsh.sh +++ b/oh-my-zsh.sh @@ -73,6 +73,9 @@ else if [ -f "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme" ] then source "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme" + elif [ -f "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme" ] + then + source "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme" else source "$ZSH/themes/$ZSH_THEME.zsh-theme" fi diff --git a/plugins/archlinux/archlinux.plugin.zsh b/plugins/archlinux/archlinux.plugin.zsh index ae92a0b4c..bffe9657a 100644 --- a/plugins/archlinux/archlinux.plugin.zsh +++ b/plugins/archlinux/archlinux.plugin.zsh @@ -8,7 +8,7 @@ if [[ -x `which yaourt` ]]; then } alias yaconf='yaourt -C' # Fix all configuration files with vimdiff # Pacman - https://wiki.archlinux.org/index.php/Pacman_Tips - alias yaupg='yaourt -Syu' # Synchronize with repositories before upgrading packages that are out of date on the local system. + alias yaupg='yaourt -Syua' # Synchronize with repositories before upgrading packages (AUR packages too) that are out of date on the local system. alias yasu='yaourt --sucre' # Same as yaupg, but without confirmation alias yain='yaourt -S' # Install specific package(s) from the repositories alias yains='yaourt -U' # Install specific package not from the repositories but from a file @@ -18,6 +18,8 @@ if [[ -x `which yaourt` ]]; then alias yareps='yaourt -Ss' # Search for package(s) in the repositories alias yaloc='yaourt -Qi' # Display information about a given package in the local database alias yalocs='yaourt -Qs' # Search for package(s) in the local database + alias yalst='yaourt -Qe' # List installed packages, even those installed from AUR (they're tagged as "local") + alias yaorph='yaourt -Qtd' # Remove orphans using yaourt # Additional yaourt alias examples if [[ -x `which abs` ]]; then alias yaupd='yaourt -Sy && sudo abs' # Update and refresh the local package and ABS databases against repositories diff --git a/plugins/autoenv/autoenv.plugin.zsh b/plugins/autoenv/autoenv.plugin.zsh new file mode 100644 index 000000000..ca5666979 --- /dev/null +++ b/plugins/autoenv/autoenv.plugin.zsh @@ -0,0 +1,18 @@ +# The use_env call below is a reusable command to activate/create a new Python +# virtualenv, requiring only a single declarative line of code in your .env files. +# It only performs an action if the requested virtualenv is not the current one. +use_env() { + typeset venv + venv="$1" + if [[ "${VIRTUAL_ENV:t}" != "$venv" ]]; then + if workon | grep -q "$venv"; then + workon "$venv" + else + echo -n "Create virtualenv $venv now? (Yn) " + read answer + if [[ "$answer" == "Y" ]]; then + mkvirtualenv "$venv" + fi + fi + fi +} diff --git a/plugins/autojump/autojump.plugin.zsh b/plugins/autojump/autojump.plugin.zsh index 3894ccd2f..f856f2f01 100644 --- a/plugins/autojump/autojump.plugin.zsh +++ b/plugins/autojump/autojump.plugin.zsh @@ -3,6 +3,8 @@ if [ $commands[autojump] ]; then # check if autojump is installed . /usr/share/autojump/autojump.zsh elif [ -f /etc/profile.d/autojump.zsh ]; then # manual installation . /etc/profile.d/autojump.zsh + elif [ -f /etc/profile.d/autojump.sh ]; then # gentoo installation + . /etc/profile.d/autojump.sh elif [ -f $HOME/.autojump/etc/profile.d/autojump.zsh ]; then # manual user-local installation . $HOME/.autojump/etc/profile.d/autojump.zsh elif [ -f /opt/local/etc/profile.d/autojump.zsh ]; then # mac os x with ports diff --git a/plugins/battery/battery.plugin.zsh b/plugins/battery/battery.plugin.zsh index 95f890632..66bf46d13 100644 --- a/plugins/battery/battery.plugin.zsh +++ b/plugins/battery/battery.plugin.zsh @@ -10,12 +10,16 @@ if [[ $(uname) == "Darwin" ]] ; then + function battery_pct() { + typeset -F maxcapacity=$(ioreg -rc "AppleSmartBattery"| grep '^.*"MaxCapacity"\ =\ ' | sed -e 's/^.*"MaxCapacity"\ =\ //') + typeset -F currentcapacity=$(ioreg -rc "AppleSmartBattery"| grep '^.*"CurrentCapacity"\ =\ ' | sed -e 's/^.*CurrentCapacity"\ =\ //') + integer i=$(((currentcapacity/maxcapacity) * 100)) + echo $i + } + function battery_pct_remaining() { if [[ $(ioreg -rc AppleSmartBattery | grep -c '^.*"ExternalConnected"\ =\ No') -eq 1 ]] ; then - typeset -F maxcapacity=$(ioreg -rc "AppleSmartBattery"| grep '^.*"MaxCapacity"\ =\ ' | sed -e 's/^.*"MaxCapacity"\ =\ //') - typeset -F currentcapacity=$(ioreg -rc "AppleSmartBattery"| grep '^.*"CurrentCapacity"\ =\ ' | sed -e 's/^.*CurrentCapacity"\ =\ //') - integer i=$(((currentcapacity/maxcapacity) * 100)) - echo $i + battery_pct else echo "External Power" fi @@ -42,17 +46,27 @@ if [[ $(uname) == "Darwin" ]] ; then fi echo "%{$fg[$color]%}[$(battery_pct_remaining)%%]%{$reset_color%}" else - echo "" + echo "∞" fi } elif [[ $(uname) == "Linux" ]] ; then - if [[ $(acpi 2&>/dev/null | grep -c '^Battery.*Discharging') -gt 0 ]] ; then - function battery_pct_remaining() { echo "$(acpi | cut -f2 -d ',' | tr -cd '[:digit:]')" } - function battery_time_remaining() { echo $(acpi | cut -f3 -d ',') } - function battery_pct_prompt() { - b=$(battery_pct_remaining) + function battery_pct_remaining() { + if [[ $(acpi 2&>/dev/null | grep -c '^Battery.*Discharging') -gt 0 ]] ; then + echo "$(acpi | cut -f2 -d ',' | tr -cd '[:digit:]')" + fi + } + + function battery_time_remaining() { + if [[ $(acpi 2&>/dev/null | grep -c '^Battery.*Discharging') -gt 0 ]] ; then + echo $(acpi | cut -f3 -d ',') + fi + } + + function battery_pct_prompt() { + b=$(battery_pct_remaining) + if [[ $(acpi 2&>/dev/null | grep -c '^Battery.*Discharging') -gt 0 ]] ; then if [ $b -gt 50 ] ; then color='green' elif [ $b -gt 20 ] ; then @@ -61,11 +75,8 @@ elif [[ $(uname) == "Linux" ]] ; then color='red' fi echo "%{$fg[$color]%}[$(battery_pct_remaining)%%]%{$reset_color%}" - } - else - error_msg='no battery' - function battery_pct_remaining() { echo $error_msg } - function battery_time_remaining() { echo $error_msg } - function battery_pct_prompt() { echo '' } - fi + else + echo "∞" + fi + } fi diff --git a/plugins/bower/bower.plugin.zsh b/plugins/bower/bower.plugin.zsh index ed9c04840..68a67a3cc 100644 --- a/plugins/bower/bower.plugin.zsh +++ b/plugins/bower/bower.plugin.zsh @@ -2,37 +2,80 @@ alias bi="bower install" alias bl="bower list" alias bs="bower search" -bower_package_list='' - +_bower_installed_packages () { + bower_package_list=$(bower ls --no-color 2>/dev/null| awk 'NR>3{print p}{p=$0}'| cut -d ' ' -f 2|sed 's/#.*//') +} _bower () { - local curcontext="$curcontext" state line - typeset -A opt_args + local -a _1st_arguments _no_color _dopts _save_dev _force_lastest _production + local expl + typeset -A opt_args - _arguments -C \ - ':command:->command' \ - '*::options:->options' + _no_color=('--no-color[Do not print colors (available in all commands)]') - case $state in - (command) + _dopts=( + '(--save)--save[Save installed packages into the project"s bower.json dependencies]' + '(--force)--force[Force fetching remote resources even if a local copy exists on disk]' + ) - local -a subcommands - subcommands=(${=$(bower help | grep help | sed -e 's/,//g')}) - _describe -t commands 'bower' subcommands - ;; + _save_dev=('(--save-dev)--save-dev[Save installed packages into the project"s bower.json devDependencies]') - (options) - case $line[1] in + _force_lastest=('(--force-latest)--force-latest[Force latest version on conflict]') + + _production=('(--production)--production[Do not install project devDependencies]') + + _1st_arguments=( + 'cache-clean:Clean the Bower cache, or the specified package caches' \ + 'help:Display help information about Bower' \ + 'info:Version info and description of a particular package' \ + 'init:Interactively create a bower.json file' \ + 'install:Install a package locally' \ + 'link:Symlink a package folder' \ + 'lookup:Look up a package URL by name' \ + 'register:Register a package' \ + 'search:Search for a package by name' \ + 'uninstall:Remove a package' \ + 'update:Update a package' \ + {ls,list}:'[List all installed packages]' + ) + _arguments \ + $_no_color \ + '*:: :->subcmds' && return 0 + + if (( CURRENT == 1 )); then + _describe -t commands "bower subcommand" _1st_arguments + return + fi + + case "$words[1]" in + install) + _arguments \ + $_dopts \ + $_save_dev \ + $_force_lastest \ + $_no_color \ + $_production + ;; + update) + _arguments \ + $_dopts \ + $_no_color \ + $_force_lastest + _bower_installed_packages + compadd "$@" $(echo $bower_package_list) + ;; + uninstall) + _arguments \ + $_no_color \ + $_dopts + _bower_installed_packages + compadd "$@" $(echo $bower_package_list) + ;; + *) + $_no_color \ + ;; + esac - (install) - if [ -z "$bower_package_list" ];then - bower_package_list=$(bower search | awk 'NR > 2' | cut -d '-' -f 2 | cut -d ' ' -f 2 | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g") - fi - compadd "$@" $(echo $bower_package_list) - ;; - esac - ;; - esac } compdef _bower bower diff --git a/plugins/brew/_brew b/plugins/brew/_brew index 1dcf0a4bf..e43ba2900 100644 --- a/plugins/brew/_brew +++ b/plugins/brew/_brew @@ -35,6 +35,7 @@ _1st_arguments=( 'update:freshen up links' 'upgrade:upgrade outdated formulae' 'uses:show formulas which depend on a formula' + 'versions:show all available formula versions' ) local expl @@ -71,7 +72,7 @@ case "$words[1]" in _brew_installed_formulae _wanted installed_formulae expl 'installed formulae' compadd -a installed_formulae fi ;; - install|home|homepage|log|info|abv|uses|cat|deps|edit|options) + install|home|homepage|log|info|abv|uses|cat|deps|edit|options|versions) _brew_all_formulae _wanted formulae expl 'all formulae' compadd -a formulae ;; remove|rm|uninstall|unlink|cleanup|link|ln) diff --git a/plugins/bundler/_bundler b/plugins/bundler/_bundler index 5d22cac9a..2ec3a5f9c 100644 --- a/plugins/bundler/_bundler +++ b/plugins/bundler/_bundler @@ -23,6 +23,7 @@ case $state in "viz[Generate a visual representation of your dependencies]" \ "init[Generate a simple Gemfile, placed in the current directory]" \ "gem[Create a simple gem, suitable for development with bundler]" \ + "clean[Cleans up unused gems in your bundler directory]" \ "help[Describe available tasks or one specific task]" ret=0 ;; @@ -62,6 +63,14 @@ case $state in exec) _normal && ret=0 ;; + clean) + _arguments \ + '(--force)--force[forces clean even if --path is not set]' \ + '(--dry-run)--dry-run[only print out changes, do not actually clean gems]' \ + '(--no-color)--no-color[Disable colorization in output]' \ + '(--verbose)--verbose[Enable verbose output mode]' + ret=0 + ;; (open|show) _gems=( $(bundle show 2> /dev/null | sed -e '/^ \*/!d; s/^ \* \([^ ]*\) .*/\1/') ) if [[ $_gems != "" ]]; then diff --git a/plugins/bundler/bundler.plugin.zsh b/plugins/bundler/bundler.plugin.zsh index bc21da134..c01241409 100644 --- a/plugins/bundler/bundler.plugin.zsh +++ b/plugins/bundler/bundler.plugin.zsh @@ -2,11 +2,12 @@ alias be="bundle exec" alias bi="bundle install" alias bl="bundle list" alias bp="bundle package" +alias bo="bundle open" alias bu="bundle update" # The following is based on https://github.com/gma/bundler-exec -bundled_commands=(annotate cap capify cucumber foreman guard middleman nanoc rackup rainbows rake rspec ruby shotgun spec spork thin thor unicorn unicorn_rails puma) +bundled_commands=(annotate berks cap capify cucumber foodcritic foreman guard jekyll kitchen knife middleman nanoc rackup rainbows rake rspec ruby shotgun spec spin spork strainer tailor thin thor unicorn unicorn_rails puma) ## Functions diff --git a/plugins/cabal/cabal.plugin.zsh b/plugins/cabal/cabal.plugin.zsh new file mode 100644 index 000000000..8d3c64587 --- /dev/null +++ b/plugins/cabal/cabal.plugin.zsh @@ -0,0 +1,36 @@ +function _cabal_commands() { + local ret=1 state + _arguments ':subcommand:->subcommand' && ret=0 + + case $state in + subcommand) + subcommands=( + "bench:Run the benchmark, if any (configure with UserHooks)" + "build:Make this package ready for installation" + "check:Check the package for common mistakes" + "clean:Clean up after a build" + "copy:Copy teh files into the install locations" + "configure:Prepare to build the package" + "fetch:Downloads packages for later installation" + "haddock:Generate HAddock HTML documentation" + "help:Help about commands" + "hscolour:Generate HsColour colourised code, in HTML format" + "info:Display detailed information about a particular package" + "init:Interactively create a .cabal file" + "install:Installs a list of packages" + "list:List packages matching a search string" + "register:Register this package with the compiler" + "report:Upload build reports to a remote server" + "sdist:Generate a source distribution file (.tar.gz)" + "test:Run the test suite, if any (configure with UserHooks)" + "unpack:Unpacks packages for user inspection" + "update:Updates list of known packages" + "upload:Uploads source packages to Hackage" + ) + _describe -t subcommands 'cabal subcommands' subcommands && ret=0 + esac + + return ret +} + +compdef _cabal_commands cabal diff --git a/plugins/capistrano/_capistrano b/plugins/capistrano/_capistrano index 1002dad96..3cadf3d54 100644 --- a/plugins/capistrano/_capistrano +++ b/plugins/capistrano/_capistrano @@ -4,7 +4,7 @@ if [[ -f config/deploy.rb || -f Capfile ]]; then if [[ ! -f .cap_tasks~ || config/deploy.rb -nt .cap_tasks~ ]]; then echo "\nGenerating .cap_tasks~..." > /dev/stderr - cap --tasks | grep '#' | cut -d " " -f 2 > .cap_tasks~ + cap -v --tasks | grep '#' | cut -d " " -f 2 > .cap_tasks~ fi compadd `cat .cap_tasks~` fi diff --git a/plugins/celery/_celery b/plugins/celery/_celery new file mode 100644 index 000000000..63af9fad5 --- /dev/null +++ b/plugins/celery/_celery @@ -0,0 +1,129 @@ +#compdef celery +#autoload + +#celery zsh completion + +_celery () { +local -a _1st_arguments ifargs dopts controlargs + +typeset -A opt_args + +_1st_arguments=('worker' 'events' 'beat' 'shell' 'multi' 'amqp' 'status' 'inspect' \ + 'control' 'purge' 'list' 'migrate' 'call' 'result' 'report') +ifargs=('--app=' '--broker=' '--loader=' '--config=' '--version') +dopts=('--detach' '--umask=' '--gid=' '--uid=' '--pidfile=' '--logfile=' '--loglevel=') +controlargs=('--timeout' '--destination') +_arguments \ + '(-A --app=)'{-A,--app}'[app instance to use (e.g. module.attr_name):APP]' \ + '(-b --broker=)'{-b,--broker}'[url to broker. default is "amqp://guest@localhost//":BROKER]' \ + '(--loader)--loader[name of custom loader class to use.:LOADER]' \ + '(--config)--config[Name of the configuration module:CONFIG]' \ + '(--workdir)--workdir[Optional directory to change to after detaching.:WORKING_DIRECTORY]' \ + '(-q --quiet)'{-q,--quiet}'[Don"t show as much output.]' \ + '(-C --no-color)'{-C,--no-color}'[Don"t display colors.]' \ + '(--version)--version[show program"s version number and exit]' \ + '(- : *)'{-h,--help}'[show this help message and exit]' \ + '*:: :->subcmds' && return 0 + +if (( CURRENT == 1 )); then + _describe -t commands "celery subcommand" _1st_arguments + return +fi + +case "$words[1]" in + worker) + _arguments \ + '(-C --concurrency=)'{-C,--concurrency=}'[Number of child processes processing the queue. The default is the number of CPUs.]' \ + '(--pool)--pool=:::(processes eventlet gevent threads solo)' \ + '(--purge --discard)'{--discard,--purge}'[Purges all waiting tasks before the daemon is started.]' \ + '(-f --logfile=)'{-f,--logfile=}'[Path to log file. If no logfile is specified, stderr is used.]' \ + '(--loglevel=)--loglevel=:::(critical error warning info debug)' \ + '(-N --hostname=)'{-N,--hostname=}'[Set custom hostname, e.g. "foo.example.com".]' \ + '(-B --beat)'{-B,--beat}'[Also run the celerybeat periodic task scheduler.]' \ + '(-s --schedule=)'{-s,--schedule=}'[Path to the schedule database if running with the -B option. Defaults to celerybeat-schedule.]' \ + '(-S --statedb=)'{-S,--statedb=}'[Path to the state database.Default: None]' \ + '(-E --events)'{-E,--events}'[Send events that can be captured by monitors like celeryev, celerymon, and others.]' \ + '(--time-limit=)--time-limit=[nables a hard time limit (in seconds int/float) for tasks]' \ + '(--soft-time-limit=)--soft-time-limit=[Enables a soft time limit (in seconds int/float) for tasks]' \ + '(--maxtasksperchild=)--maxtasksperchild=[Maximum number of tasks a pool worker can execute before it"s terminated and replaced by a new worker.]' \ + '(-Q --queues=)'{-Q,--queues=}'[List of queues to enable for this worker, separated by comma. By default all configured queues are enabled.]' \ + '(-I --include=)'{-I,--include=}'[Comma separated list of additional modules to import.]' \ + '(--pidfile=)--pidfile=[Optional file used to store the process pid.]' \ + '(--autoscale=)--autoscale=[Enable autoscaling by providing max_concurrency, min_concurrency.]' \ + '(--autoreload)--autoreload[Enable autoreloading.]' \ + '(--no-execv)--no-execv[Don"t do execv after multiprocessing child fork.]' + compadd -a ifargs + ;; + inspect) + _values -s \ + 'active[dump active tasks (being processed)]' \ + 'active_queues[dump queues being consumed from]' \ + 'ping[ping worker(s)]' \ + 'registered[dump of registered tasks]' \ + 'report[get bugreport info]' \ + 'reserved[dump reserved tasks (waiting to be processed)]' \ + 'revoked[dump of revoked task ids]' \ + 'scheduled[dump scheduled tasks (eta/countdown/retry)]' \ + 'stats[dump worker statistics]' + compadd -a controlargs ifargs + ;; + control) + _values -s \ + 'add_consumer[tell worker(s) to start consuming a queue]' \ + 'autoscale[change autoscale settings]' \ + 'cancel_consumer[tell worker(s) to stop consuming a queue]' \ + 'disable_events[tell worker(s) to disable events]' \ + 'enable_events[tell worker(s) to enable events]' \ + 'pool_grow[start more pool processes]' \ + 'pool_shrink[use less pool processes]' \ + 'rate_limit[tell worker(s) to modify the rate limit for a task type]' \ + 'time_limit[tell worker(s) to modify the time limit for a task type.]' + compadd -a controlargs ifargs + ;; + multi) + _values -s \ + '--nosplash[Don"t display program info.]' \ + '--verbose[Show more output.]' \ + '--no-color[Don"t display colors.]' \ + '--quiet[Don"t show as much output.]' \ + 'start' 'restart' 'stopwait' 'stop' 'show' \ + 'names' 'expand' 'get' 'kill' + compadd -a ifargs + ;; + amqp) + _values -s \ + 'queue.declare' 'queue.purge' 'exchange.delete' 'basic.publish' \ + 'exchange.declare' 'queue.delete' 'queue.bind' 'basic.get' + ;; + list) + _values -s, 'bindings' + ;; + shell) + _values -s \ + '--ipython[force iPython.]' \ + '--bpython[force bpython.]' \ + '--python[force default Python shell.]' \ + '--without-tasks[don"t add tasks to locals.]' \ + '--eventlet[use eventlet.]' \ + '--gevent[use gevent.]' + compadd -a ifargs + ;; + beat) + _arguments \ + '(-s --schedule=)'{-s,--schedule=}'[Path to the schedule database. Defaults to celerybeat-schedule.]' \ + '(-S --scheduler=)'{-S,--scheduler=}'[Scheduler class to use. Default is celery.beat.PersistentScheduler.]' \ + '(--max-interval)--max-interval[]' + compadd -a dopts fargs + ;; + events) + _arguments \ + '(-d --dump)'{-d,--dump}'[Dump events to stdout.]' \ + '(-c --camera=)'{-c,--camera=}'[Take snapshots of events using this camera.]' \ + '(-F --frequency=)'{-F,--frequency=}'[Camera: Shutter frequency. Default is every 1.0 seconds.]' \ + '(-r --maxrate=)'{-r,--maxrate=}'[Camera: Optional shutter rate limit (e.g. 10/m).]' + compadd -a dopts fargs + ;; + *) + ;; + esac +} diff --git a/plugins/coffee/_coffee b/plugins/coffee/_coffee index 5c8eb9a08..10b6b8164 100644 --- a/plugins/coffee/_coffee +++ b/plugins/coffee/_coffee @@ -35,27 +35,37 @@ # ------- # # * Mario Fernandez (https://github.com/sirech) +# * Dong Weiming (https://github.com/dongweiming) # # ------------------------------------------------------------------------------ -local curcontext="$curcontext" state line ret=1 +local curcontext="$curcontext" state line ret=1 version opts first second third typeset -A opt_args +version=(${(f)"$(_call_program version $words[1] --version)"}) +version=${${(z)${version[1]}}[3]} +first=$(echo $version|cut -d '.' -f 1) +second=$(echo $version|cut -d '.' -f 2) +third=$(echo $version|cut -d '.' -f 3) +if (( $first < 2 )) && (( $second < 7 )) && (( $third < 3 ));then + opts+=('(-l --lint)'{-l,--lint}'[pipe the compiled JavaScript through JavaScript Lint]' + '(-r --require)'{-r,--require}'[require a library before executing your script]:library') +fi + _arguments -C \ '(- *)'{-h,--help}'[display this help message]' \ '(- *)'{-v,--version}'[display the version number]' \ + $opts \ '(-b --bare)'{-b,--bare}'[compile without a top-level function wrapper]' \ '(-e --eval)'{-e,--eval}'[pass a string from the command line as input]:Inline Script' \ '(-i --interactive)'{-i,--interactive}'[run an interactive CoffeeScript REPL]' \ '(-j --join)'{-j,--join}'[concatenate the source CoffeeScript before compiling]:Destination JS file:_files -g "*.js"' \ - '(-l --lint)'{-l,--lint}'[pipe the compiled JavaScript through JavaScript Lint]' \ '(--nodejs)--nodejs[pass options directly to the "node" binary]' \ '(-c --compile)'{-c,--compile}'[compile to JavaScript and save as .js files]' \ '(-o --output)'{-o,--output}'[set the output directory for compiled JavaScript]:Output Directory:_files -/' \ '(-n -t -p)'{-n,--nodes}'[print out the parse tree that the parser produces]' \ '(-n -t -p)'{-p,--print}'[print out the compiled JavaScript]' \ '(-n -t -p)'{-t,--tokens}'[print out the tokens that the lexer/rewriter produce]' \ - '(-r --require)'{-r,--require}'[require a library before executing your script]:library' \ '(-s --stdio)'{-s,--stdio}'[listen for and compile scripts over stdio]' \ '(-w --watch)'{-w,--watch}'[watch scripts for changes and rerun commands]' \ '*:script or directory:_files' && ret=0 diff --git a/plugins/colorize/colorize.plugin.zsh b/plugins/colorize/colorize.plugin.zsh new file mode 100644 index 000000000..0696607d9 --- /dev/null +++ b/plugins/colorize/colorize.plugin.zsh @@ -0,0 +1,28 @@ +# Plugin for highligthing file content +# Plugin highlights file content based on the filename extension. +# If no highlighting method supported for given extension then it tries +# guess it by looking for file content. + +alias colorize='colorize_via_pygmentize' + +colorize_via_pygmentize() { + if [ ! -x $(which pygmentize) ]; then + echo package \'pygmentize\' is not installed! + exit -1 + fi + + if [ $# -eq 0 ]; then + pygmentize -g $@ + fi + + for FNAME in $@ + do + filename=$(basename "$FNAME") + lexer=`pygmentize -N \"$filename\"` + if [ "Z$lexer" != "Ztext" ]; then + pygmentize -l $lexer "$FNAME" + else + pygmentize -g "$FNAME" + fi + done +} \ No newline at end of file diff --git a/plugins/command-not-found/command-not-found.plugin.zsh b/plugins/command-not-found/command-not-found.plugin.zsh index 567da1b45..f3d7ec2df 100644 --- a/plugins/command-not-found/command-not-found.plugin.zsh +++ b/plugins/command-not-found/command-not-found.plugin.zsh @@ -3,3 +3,7 @@ # this is installed in Ubuntu [[ -e /etc/zsh_command_not_found ]] && source /etc/zsh_command_not_found + +# Arch Linux command-not-found support, you must have package pkgfile installed +# https://wiki.archlinux.org/index.php/Pkgfile#.22Command_not_found.22_hook +[[ -e /usr/share/doc/pkgfile/command-not-found.zsh ]] && source /usr/share/doc/pkgfile/command-not-found.zsh diff --git a/plugins/composer/composer.plugin.zsh b/plugins/composer/composer.plugin.zsh index 639677ba6..9975aaca4 100644 --- a/plugins/composer/composer.plugin.zsh +++ b/plugins/composer/composer.plugin.zsh @@ -10,9 +10,25 @@ _composer_get_command_list () { composer --no-ansi | sed "1,/Available commands/d" | awk '/^ [a-z]+/ { print $1 }' } +_composer_get_required_list () { + composer show -s --no-ansi | sed '1,/requires/d' | awk 'NF > 0 && !/^requires \(dev\)/{ print $1 }' +} + _composer () { + local curcontext="$curcontext" state line + typeset -A opt_args + _arguments \ + '1: :->command'\ + '*: :->args' if [ -f composer.json ]; then - compadd `_composer_get_command_list` + case $state in + command) + compadd `_composer_get_command_list` + ;; + *) + compadd `_composer_get_required_list` + ;; + esac else compadd create-project init search selfupdate show fi @@ -26,6 +42,7 @@ alias csu='composer self-update' alias cu='composer update' alias ci='composer install' alias ccp='composer create-project' +alias cdu='composer dump-autoload' # install composer in the current directory alias cget='curl -s https://getcomposer.org/installer | php' diff --git a/plugins/copyfile/copyfile.plugin.zsh b/plugins/copyfile/copyfile.plugin.zsh new file mode 100644 index 000000000..944a903c6 --- /dev/null +++ b/plugins/copyfile/copyfile.plugin.zsh @@ -0,0 +1,5 @@ +function copyfile { + [[ "$#" != 1 ]] && return 1 + local file_to_copy=$1 + cat $file_to_copy | pbcopy +} diff --git a/plugins/debian/debian.plugin.zsh b/plugins/debian/debian.plugin.zsh index 55b90e379..b51d0cd37 100644 --- a/plugins/debian/debian.plugin.zsh +++ b/plugins/debian/debian.plugin.zsh @@ -6,14 +6,14 @@ # Use aptitude if installed, or apt-get if not. # You can just set apt_pref='apt-get' to override it. -if [[ -e $( which aptitude 2>&1 ) ]]; then +if [[ -e $( which -p aptitude 2>&1 ) ]]; then apt_pref='aptitude' else apt_pref='apt-get' fi # Use sudo by default if it's installed -if [[ -e $( which sudo 2>&1 ) ]]; then +if [[ -e $( which -p sudo 2>&1 ) ]]; then use_sudo=1 fi diff --git a/plugins/django/django.plugin.zsh b/plugins/django/django.plugin.zsh index 0bbd031fe..9d898edca 100644 --- a/plugins/django/django.plugin.zsh +++ b/plugins/django/django.plugin.zsh @@ -20,6 +20,19 @@ _managepy-createcachetable(){ $nul_args && ret=0 } +_managepy-collectstatic(){ + _arguments -s : \ + '--link=-[Create a symbolic link to each file instead of copying.]:' \ + '--noinput=-[Do NOT prompt the user for input of any kind.]:' \ + '--no-post-process=-[Do NOT post process collected files.]:' \ + '--ignore=-[Ignore files or directories matching this glob-style pattern. Use multiple times to ignore more.]:' \ + '--dry-run=-[Do everything except modify the filesystem.]:' \ + '--clear=-[Clear the existing files using the storage before trying to copy or link the original file.]:' \ + '--link=-[Create a symbolic link to each file instead of copying.]:' \ + '--no-default-ignore=-[Do not ignore the common private glob-style patterns "CVS", ".*" and "*~".]:' \ + $nul_args && ret=0 +} + _managepy-dbshell(){ _arguments -s : \ $nul_args && ret=0 @@ -163,6 +176,7 @@ _managepy-commands() { commands=( 'adminindex:prints the admin-index template snippet for the given app name(s).' 'createcachetable:creates the table needed to use the SQL cache backend.' + 'collectstatic:Collect static files in a single location.' 'dbshell:runs the command-line client for the current DATABASE_ENGINE.' "diffsettings:displays differences between the current settings.py and Django's default settings." 'dumpdata:Output the contents of the database as a fixture of the given format.' @@ -220,4 +234,5 @@ _managepy() { compdef _managepy manage.py compdef _managepy django +compdef _managepy django-admin.py compdef _managepy django-manage diff --git a/plugins/fasd/fasd.plugin.zsh b/plugins/fasd/fasd.plugin.zsh index d42584f1a..8ad43fc23 100644 --- a/plugins/fasd/fasd.plugin.zsh +++ b/plugins/fasd/fasd.plugin.zsh @@ -1,5 +1,10 @@ if [ $commands[fasd] ]; then # check if fasd is installed - eval "$(fasd --init auto)" + fasd_cache="$HOME/.fasd-init-cache" + if [ "$(command -v fasd)" -nt "$fasd_cache" -o ! -s "$fasd_cache" ]; then + fasd --init auto >| "$fasd_cache" + fi + source "$fasd_cache" + unset fasd_cache alias v='f -e vim' alias o='a -e open' fi diff --git a/plugins/gem/_gem b/plugins/gem/_gem index 83cba40d1..975cec602 100644 --- a/plugins/gem/_gem +++ b/plugins/gem/_gem @@ -9,8 +9,9 @@ _gem_installed() { local -a _1st_arguments _1st_arguments=( + 'build:Build a gem from a gemspec' 'cert:Manage RubyGems certificates and signing settings' - 'check:Check installed gems' + 'check:Check a gem repository for added or missing files' 'cleanup:Clean up old versions of installed gems in the local repository' 'contents:Display the contents of the installed gems' 'dependency:Show the dependencies of an installed gem' @@ -21,7 +22,7 @@ _1st_arguments=( 'install:Install a gem into the local repository' 'list:Display gems whose name starts with STRING' 'lock:Generate a lockdown list of gems' - 'mirror:Mirror a gem repository' + 'mirror:Mirror all gem files (requires rubygems-mirror)' 'outdated:Display all gems that need updates' 'owner:Manage gem owners on RubyGems.org.' 'pristine:Restores installed gems to pristine condition from files located in the gem cache' @@ -35,8 +36,9 @@ _1st_arguments=( 'stale:List gems along with access times' 'uninstall:Uninstall gems from the local repository' 'unpack:Unpack an installed gem to the current directory' - 'update:Update the named gems (or all installed gems) in the local repository' + 'update:Update installed gems to the latest version' 'which:Find the location of a library file you can require' + 'yank:Remove a specific gem version release from RubyGems.org' ) local expl diff --git a/plugins/git-flow-avh/git-flow-avh.plugin.zsh b/plugins/git-flow-avh/git-flow-avh.plugin.zsh new file mode 100644 index 000000000..d76f55ef6 --- /dev/null +++ b/plugins/git-flow-avh/git-flow-avh.plugin.zsh @@ -0,0 +1,416 @@ +#!zsh +# +# Installation +# ------------ +# +# To achieve git-flow completion nirvana: +# +# 0. Update your zsh's git-completion module to the newest verion. +# From here. http://zsh.git.sourceforge.net/git/gitweb.cgi?p=zsh/zsh;a=blob_plain;f=Completion/Unix/Command/_git;hb=HEAD +# +# 1. Install this file. Either: +# +# a. Place it in your .zshrc: +# +# b. Or, copy it somewhere (e.g. ~/.git-flow-completion.zsh) and put the following line in +# your .zshrc: +# +# source ~/.git-flow-completion.zsh +# +# c. Or, use this file as a oh-my-zsh plugin. +# + +_git-flow () +{ + local curcontext="$curcontext" state line + typeset -A opt_args + + _arguments -C \ + ':command:->command' \ + '*::options:->options' + + case $state in + (command) + + local -a subcommands + subcommands=( + 'init:Initialize a new git repo with support for the branching model.' + 'feature:Manage your feature branches.' + 'config:Manage your configuration.' + 'release:Manage your release branches.' + 'hotfix:Manage your hotfix branches.' + 'support:Manage your support branches.' + 'version:Shows version information.' + ) + _describe -t commands 'git flow' subcommands + ;; + + (options) + case $line[1] in + + (init) + _arguments \ + -f'[Force setting of gitflow branches, even if already configured]' + ;; + + (version) + ;; + + (hotfix) + __git-flow-hotfix + ;; + + (release) + __git-flow-release + ;; + + (feature) + __git-flow-feature + ;; + (config) + __git-flow-config + ;; + + esac + ;; + esac +} + +__git-flow-release () +{ + local curcontext="$curcontext" state line + typeset -A opt_args + + _arguments -C \ + ':command:->command' \ + '*::options:->options' + + case $state in + (command) + + local -a subcommands + subcommands=( + 'start:Start a new release branch.' + 'finish:Finish a release branch.' + 'list:List all your release branches. (Alias to `git flow release`)' + 'publish:Publish release branch to remote.' + 'track:Checkout remote release branch.' + 'delet:Delete a release branch.' + ) + _describe -t commands 'git flow release' subcommands + _arguments \ + -v'[Verbose (more) output]' + ;; + + (options) + case $line[1] in + + (start) + _arguments \ + -F'[Fetch from origin before performing finish]'\ + ':version:__git_flow_version_list' + ;; + + (finish) + _arguments \ + -F'[Fetch from origin before performing finish]' \ + -s'[Sign the release tag cryptographically]'\ + -u'[Use the given GPG-key for the digital signature (implies -s)]'\ + -m'[Use the given tag message]'\ + -p'[Push to $ORIGIN after performing finish]'\ + ':version:__git_flow_version_list' + ;; + + (delete) + _arguments \ + -f'[Force deletion]' \ + -r'[Delete remote branch]' \ + ':version:__git_flow_version_list' + ;; + + (publish) + _arguments \ + ':version:__git_flow_version_list' + ;; + + (track) + _arguments \ + ':version:__git_flow_version_list' + ;; + + *) + _arguments \ + -v'[Verbose (more) output]' + ;; + esac + ;; + esac +} + +__git-flow-hotfix () +{ + local curcontext="$curcontext" state line + typeset -A opt_args + + _arguments -C \ + ':command:->command' \ + '*::options:->options' + + case $state in + (command) + + local -a subcommands + subcommands=( + 'start:Start a new hotfix branch.' + 'finish:Finish a hotfix branch.' + 'delete:Delete a hotfix branch.' + 'list:List all your hotfix branches. (Alias to `git flow hotfix`)' + ) + _describe -t commands 'git flow hotfix' subcommands + _arguments \ + -v'[Verbose (more) output]' + ;; + + (options) + case $line[1] in + + (start) + _arguments \ + -F'[Fetch from origin before performing finish]'\ + ':hotfix:__git_flow_version_list'\ + ':branch-name:__git_branch_names' + ;; + + (finish) + _arguments \ + -F'[Fetch from origin before performing finish]' \ + -s'[Sign the release tag cryptographically]'\ + -u'[Use the given GPG-key for the digital signature (implies -s)]'\ + -m'[Use the given tag message]'\ + -p'[Push to $ORIGIN after performing finish]'\ + ':hotfix:__git_flow_hotfix_list' + ;; + + (delete) + _arguments \ + -f'[Force deletion]' \ + -r'[Delete remote branch]' \ + ':hotfix:__git_flow_hotfix_list' + ;; + + *) + _arguments \ + -v'[Verbose (more) output]' + ;; + esac + ;; + esac +} + +__git-flow-feature () +{ + local curcontext="$curcontext" state line + typeset -A opt_args + + _arguments -C \ + ':command:->command' \ + '*::options:->options' + + case $state in + (command) + + local -a subcommands + subcommands=( + 'start:Start a new feature branch.' + 'finish:Finish a feature branch.' + 'delete:Delete a feature branch.' + 'list:List all your feature branches. (Alias to `git flow feature`)' + 'publish:Publish feature branch to remote.' + 'track:Checkout remote feature branch.' + 'diff:Show all changes.' + 'rebase:Rebase from integration branch.' + 'checkout:Checkout local feature branch.' + 'pull:Pull changes from remote.' + ) + _describe -t commands 'git flow feature' subcommands + _arguments \ + -v'[Verbose (more) output]' + ;; + + (options) + case $line[1] in + + (start) + _arguments \ + -F'[Fetch from origin before performing finish]'\ + ':feature:__git_flow_feature_list'\ + ':branch-name:__git_branch_names' + ;; + + (finish) + _arguments \ + -F'[Fetch from origin before performing finish]' \ + -r'[Rebase instead of merge]'\ + ':feature:__git_flow_feature_list' + ;; + + (delete) + _arguments \ + -f'[Force deletion]' \ + -r'[Delete remote branch]' \ + ':feature:__git_flow_feature_list' + ;; + + (publish) + _arguments \ + ':feature:__git_flow_feature_list'\ + ;; + + (track) + _arguments \ + ':feature:__git_flow_feature_list'\ + ;; + + (diff) + _arguments \ + ':branch:__git_branch_names'\ + ;; + + (rebase) + _arguments \ + -i'[Do an interactive rebase]' \ + ':branch:__git_branch_names' + ;; + + (checkout) + _arguments \ + ':branch:__git_flow_feature_list'\ + ;; + + (pull) + _arguments \ + ':remote:__git_remotes'\ + ':branch:__git_branch_names' + ;; + + *) + _arguments \ + -v'[Verbose (more) output]' + ;; + esac + ;; + esac +} + +__git-flow-config () +{ + local curcontext="$curcontext" state line + typeset -A opt_args + + _arguments -C \ + ':command:->command' \ + '*::options:->options' + + case $state in + (command) + + local -a subcommands + subcommands=( + 'list:List the configuration. (Alias to `git flow config`)' + 'set:Set the configuration option' + ) + _describe -t commands 'git flow config' subcommands + ;; + + (options) + case $line[1] in + + (set) + _arguments \ + --local'[Use repository config file]' \ + --global'[Use global config file]'\ + --system'[Use system config file]'\ + --file'[Use given config file]'\ + ':option:(master develop feature hotfix release support versiontagprefix)' + ;; + + *) + _arguments \ + --local'[Use repository config file]' \ + --global'[Use global config file]'\ + --system'[Use system config file]'\ + --file'[Use given config file]' + ;; + esac + ;; + esac +} +__git_flow_version_list () +{ + local expl + declare -a versions + + versions=(${${(f)"$(_call_program versions git flow release list 2> /dev/null | tr -d ' |*')"}}) + __git_command_successful || return + + _wanted versions expl 'version' compadd $versions +} + +__git_flow_feature_list () +{ + local expl + declare -a features + + features=(${${(f)"$(_call_program features git flow feature list 2> /dev/null | tr -d ' |*')"}}) + __git_command_successful || return + + _wanted features expl 'feature' compadd $features +} + +__git_remotes () { + local expl gitdir remotes + + gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null) + __git_command_successful || return + + remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]}) + __git_command_successful || return + + # TODO: Should combine the two instead of either or. + if (( $#remotes > 0 )); then + _wanted remotes expl remote compadd $* - $remotes + else + _wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*" + fi +} + +__git_flow_hotfix_list () +{ + local expl + declare -a hotfixes + + hotfixes=(${${(f)"$(_call_program hotfixes git flow hotfix list 2> /dev/null | tr -d ' |*')"}}) + __git_command_successful || return + + _wanted hotfixes expl 'hotfix' compadd $hotfixes +} + +__git_branch_names () { + local expl + declare -a branch_names + + branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/}) + __git_command_successful || return + + _wanted branch-names expl branch-name compadd $* - $branch_names +} + +__git_command_successful () { + if (( ${#pipestatus:#0} > 0 )); then + _message 'not a git repository' + return 1 + fi + return 0 +} + +zstyle ':completion:*:*:git:*' user-commands flow:'provide high-level repository operations' diff --git a/plugins/git-flow/git-flow.plugin.zsh b/plugins/git-flow/git-flow.plugin.zsh index ec21019e6..ab9c0c848 100644 --- a/plugins/git-flow/git-flow.plugin.zsh +++ b/plugins/git-flow/git-flow.plugin.zsh @@ -88,6 +88,8 @@ __git-flow-release () 'start:Start a new release branch.' 'finish:Finish a release branch.' 'list:List all your release branches. (Alias to `git flow release`)' + 'publish: public' + 'track: track' ) _describe -t commands 'git flow release' subcommands _arguments \ @@ -115,6 +117,16 @@ __git-flow-release () ':version:__git_flow_version_list' ;; + (publish) + _arguments \ + ':version:__git_flow_version_list'\ + ;; + + (track) + _arguments \ + ':version:__git_flow_version_list'\ + ;; + *) _arguments \ -v'[Verbose (more) output]' diff --git a/plugins/git-remote-branch/git-remote-branch.plugin.zsh b/plugins/git-remote-branch/git-remote-branch.plugin.zsh index ff98cbf87..6c5ab8f70 100644 --- a/plugins/git-remote-branch/git-remote-branch.plugin.zsh +++ b/plugins/git-remote-branch/git-remote-branch.plugin.zsh @@ -6,7 +6,8 @@ _git_remote_branch() { compadd create publish rename delete track elif (( CURRENT == 3 )); then # second arg: remote branch name - compadd `git branch -r | grep -v HEAD | sed "s/.*\///" | sed "s/ //g"` + remotes=`git remote | tr '\n' '|' | sed "s/\|$//g"` + compadd `git branch -r | grep -v HEAD | sed "s/$remotes\///" | sed "s/ //g"` elif (( CURRENT == 4 )); then # third arg: remote name compadd `git remote` diff --git a/plugins/git/README.md b/plugins/git/README.md new file mode 100644 index 000000000..8462dda1c --- /dev/null +++ b/plugins/git/README.md @@ -0,0 +1,4 @@ +## git +**Maintainer:** [Stibbons](https://github.com/Stibbons) + +This plugin adds several git aliases and increase the completion function provided by zsh diff --git a/plugins/git/_git-branch b/plugins/git/_git-branch new file mode 100644 index 000000000..86d03bc30 --- /dev/null +++ b/plugins/git/_git-branch @@ -0,0 +1,62 @@ +#compdef git-branch + +_git-branch () +{ + declare l c m d + + l='--color --no-color -r -a --all -v --verbose --abbrev --no-abbrev' + c='-l -f --force -t --track --no-track --set-upstream --contains --merged --no-merged' + m='-m -M' + d='-d -D' + + declare -a dependent_creation_args + if (( words[(I)-r] == 0 )); then + dependent_creation_args=( + "($l $m $d): :__git_branch_names" + "::start-point:__git_revisions") + fi + + declare -a dependent_deletion_args + if (( words[(I)-d] || words[(I)-D] )); then + dependent_creation_args= + dependent_deletion_args=( + '-r[delete only remote-tracking branches]') + if (( words[(I)-r] )); then + dependent_deletion_args+='*: :__git_ignore_line_inside_arguments __git_remote_branch_names' + else + dependent_deletion_args+='*: :__git_ignore_line_inside_arguments __git_branch_names' + fi + fi + + declare -a dependent_modification_args + if (( words[(I)-m] || words[(I)-M] )); then + dependent_creation_args= + dependent_modification_args=( + ':old or new branch name:__git_branch_names' + '::new branch name:__git_branch_names') + fi + + _arguments -w -S -s \ + "($c $m $d --no-color :)--color=-[turn on branch coloring]:: :__git_color_whens" \ + "($c $m $d : --color)--no-color[turn off branch coloring]" \ + "($c $m -a --all)-r[list or delete only remote-tracking branches]" \ + "($c $m $d : -r)"{-a,--all}"[list both remote-tracking branches and local branches]" \ + "($c $m $d : -v --verbose)"{-v,--verbose}'[show SHA1 and commit subject line for each head]' \ + "($c $m $d :)--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length" \ + "($c $m $d :)--no-abbrev[do not abbreviate sha1s]" \ + "($l $m $d)-l[create the branch's reflog]" \ + "($l $m $d -f --force)"{-f,--force}"[force the creation of a new branch]" \ + "($l $m $d -t --track)"{-t,--track}"[set up configuration so that pull merges from the start point]" \ + "($l $m $d)--no-track[override the branch.autosetupmerge configuration variable]" \ + "($l $m $d)--set-upstream[set up configuration so that pull merges]" \ + "($l $m $d)--contains=[only list branches which contain the specified commit]: :__git_committishs" \ + "($l $m $d)--merged=[only list branches which are fully contained by HEAD]: :__git_committishs" \ + "($l $m $d)--no-merged=[do not list branches which are fully contained by HEAD]: :__git_committishs" \ + $dependent_creation_args \ + "($l $c $d -M)-m[rename a branch and the corresponding reflog]" \ + "($l $c $d -m)-M[rename a branch even if the new branch-name already exists]" \ + $dependent_modification_args \ + "($l $c $m -D)-d[delete a fully merged branch]" \ + "($l $c $m -d)-D[delete a branch]" \ + $dependent_deletion_args +} diff --git a/plugins/git/_git-remote b/plugins/git/_git-remote new file mode 100644 index 000000000..4ba62a357 --- /dev/null +++ b/plugins/git/_git-remote @@ -0,0 +1,74 @@ +#compdef git-remote + +# NOTE: --track is undocumented. +# TODO: --track, -t, --master, and -m should take remote branches, I guess. +# NOTE: --master is undocumented. +# NOTE: --fetch is undocumented. +_git-remote () { + local curcontext=$curcontext state line + declare -A opt_args + + _arguments -C \ + ':command:->command' \ + '*::options:->options' && ret=0 + + case $state in + (command) + declare -a commands + + commands=( + 'add:add a new remote' + 'show:show information about a given remote' + 'prune:delete all stale tracking branches for a given remote' + 'update:fetch updates for a set of remotes' + 'rm:remove a remote from .git/config and all associated tracking branches' + 'rename:rename a remote from .git/config and update all associated tracking branches' + 'set-head:sets or deletes the default branch' + 'set-branches:changes the list of branches tracked by the named remote.' + 'set-url:changes URL remote points to.' + ) + + _describe -t commands 'sub-command' commands && ret=0 + ;; + (options) + case $line[1] in + (add) + _arguments \ + '*'{--track,-t}'[track given branch instead of default glob refspec]:branch:__git_branch_names' \ + '(--master -m)'{--master,-m}'[set the remote'\''s HEAD to point to given master branch]:branch:__git_branch_names' \ + '(--fetch -f)'{--fetch,-f}'[run git-fetch on the new remote after it has been created]' \ + ':branch name:__git_remotes' \ + ':url:_urls' && ret=0 + ;; + (show) + _arguments \ + '-n[do not contact the remote for a list of branches]' \ + ':remote:__git_remotes' && ret=0 + ;; + (prune) + _arguments \ + '(--dry-run -n)'{-n,--dry-run}'[do not actually prune, only list what would be done]' \ + ':remote:__git_remotes' && ret=0 + ;; + (update) + __git_remote-groups && ret=0 + ;; + (rm) + __git_remotes && ret=0 + ;; + (rename) + __git_remotes && ret=0 + ;; + (set-url) + _arguments \ + '*--push[manipulate push URLs]' \ + '(--add)--add[add URL]' \ + '(--delete)--delete[delete URLs]' \ + ':branch name:__git_remotes' \ + ':url:_urls' && ret=0 + ;; + + esac + ;; + esac +} diff --git a/plugins/git/git.plugin.zsh b/plugins/git/git.plugin.zsh index 15f901f86..2ecc74eb6 100644 --- a/plugins/git/git.plugin.zsh +++ b/plugins/git/git.plugin.zsh @@ -3,6 +3,8 @@ alias g='git' compdef g=git alias gst='git status' compdef _git gst=git-status +alias gd='git diff' +compdef _git gd=git-diff alias gl='git pull' compdef _git gl=git-pull alias gup='git pull --rebase' @@ -35,6 +37,12 @@ alias grset='git remote set-url' compdef _git grset=git-remote alias grup='git remote update' compdef _git grset=git-remote +alias grbi='git rebase -i' +compdef _git grbi=git-rebase +alias grbc='git rebase --continue' +compdef _git grbc=git-rebase +alias grba='git rebase --abort' +compdef _git grba=git-rebase alias gb='git branch' compdef _git gb=git-branch alias gba='git branch -a' @@ -50,6 +58,8 @@ alias glgg='git log --graph --max-count=5' compdef _git glgg=git-log alias glgga='git log --graph --decorate --all' compdef _git glgga=git-log +alias glo='git log --oneline' +compdef _git glo=git-log alias gss='git status -s' compdef _git gss=git-status alias ga='git add' @@ -58,9 +68,17 @@ alias gm='git merge' compdef _git gm=git-merge alias grh='git reset HEAD' alias grhh='git reset HEAD --hard' +alias gclean='git reset --hard && git clean -dfx' alias gwc='git whatchanged -p --abbrev-commit --pretty=medium' alias gf='git ls-files | grep' alias gpoat='git push origin --all && git push origin --tags' +alias gmt='git mergetool --no-prompt' +compdef _git gm=git-mergetool + +alias gg='git gui citool' +alias gga='git gui citool --amend' +alias gk='gitk --all --branches' +alias gsts='git stash show --text' # Will cd into the top of the current repository # or submodule. @@ -91,7 +109,18 @@ function current_repository() { # these aliases take advantage of the previous function alias ggpull='git pull origin $(current_branch)' compdef ggpull=git +alias ggpur='git pull --rebase origin $(current_branch)' +compdef ggpur=git alias ggpush='git push origin $(current_branch)' compdef ggpush=git alias ggpnp='git pull origin $(current_branch) && git push origin $(current_branch)' compdef ggpnp=git + +# Pretty log messages +function _git_log_prettily(){ + if ! [ -z $1 ]; then + git log --pretty=$1 + fi +} +alias glp="_git_log_prettily" +compdef _git glp=git-log diff --git a/plugins/gitfast/_git b/plugins/gitfast/_git index 45775021f..cf8116d47 100644 --- a/plugins/gitfast/_git +++ b/plugins/gitfast/_git @@ -60,6 +60,15 @@ __gitcomp_nl () compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 } +__gitcomp_file () +{ + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -p "${2-}" -f -- ${=1} && _ret=0 +} + _git () { local _ret=1 diff --git a/plugins/gitfast/git-completion.bash b/plugins/gitfast/git-completion.bash index be800e09b..93eba4675 100644 --- a/plugins/gitfast/git-completion.bash +++ b/plugins/gitfast/git-completion.bash @@ -13,6 +13,7 @@ # *) .git/remotes file names # *) git 'subcommands' # *) tree paths within 'ref:path/to/file' expressions +# *) file paths within current working directory and index # *) common --long-options # # To use these routines: @@ -23,10 +24,6 @@ # 3) Consider changing your PS1 to also show the current branch, # see git-prompt.sh for details. -if [[ -n ${ZSH_VERSION-} ]]; then - autoload -U +X bashcompinit && bashcompinit -fi - case "$COMP_WORDBREAKS" in *:*) : great ;; *) COMP_WORDBREAKS="$COMP_WORDBREAKS:" @@ -169,7 +166,6 @@ __git_reassemble_comp_words_by_ref() } if ! type _get_comp_words_by_ref >/dev/null 2>&1; then -if [[ -z ${ZSH_VERSION:+set} ]]; then _get_comp_words_by_ref () { local exclude cur_ words_ cword_ @@ -197,32 +193,6 @@ _get_comp_words_by_ref () shift done } -else -_get_comp_words_by_ref () -{ - while [ $# -gt 0 ]; do - case "$1" in - cur) - cur=${COMP_WORDS[COMP_CWORD]} - ;; - prev) - prev=${COMP_WORDS[COMP_CWORD-1]} - ;; - words) - words=("${COMP_WORDS[@]}") - ;; - cword) - cword=$COMP_CWORD - ;; - -n) - # assume COMP_WORDBREAKS is already set sanely - shift - ;; - esac - shift - done -} -fi fi # Generates completion reply with compgen, appending a space to possible @@ -264,6 +234,124 @@ __gitcomp_nl () COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$1" -- "${3-$cur}")) } +# Generates completion reply with compgen from newline-separated possible +# completion filenames. +# It accepts 1 to 3 arguments: +# 1: List of possible completion filenames, separated by a single newline. +# 2: A directory prefix to be added to each possible completion filename +# (optional). +# 3: Generate possible completion matches for this word (optional). +__gitcomp_file () +{ + local IFS=$'\n' + + # XXX does not work when the directory prefix contains a tilde, + # since tilde expansion is not applied. + # This means that COMPREPLY will be empty and Bash default + # completion will be used. + COMPREPLY=($(compgen -P "${2-}" -W "$1" -- "${3-$cur}")) + + # Tell Bash that compspec generates filenames. + compopt -o filenames 2>/dev/null +} + +__git_index_file_list_filter_compat () +{ + local path + + while read -r path; do + case "$path" in + ?*/*) echo "${path%%/*}/" ;; + *) echo "$path" ;; + esac + done +} + +__git_index_file_list_filter_bash () +{ + local path + + while read -r path; do + case "$path" in + ?*/*) + # XXX if we append a slash to directory names when using + # `compopt -o filenames`, Bash will append another slash. + # This is pretty stupid, and this the reason why we have to + # define a compatible version for this function. + echo "${path%%/*}" ;; + *) + echo "$path" ;; + esac + done +} + +# Process path list returned by "ls-files" and "diff-index --name-only" +# commands, in order to list only file names relative to a specified +# directory, and append a slash to directory names. +__git_index_file_list_filter () +{ + # Default to Bash >= 4.x + __git_index_file_list_filter_bash +} + +# Execute git ls-files, returning paths relative to the directory +# specified in the first argument, and using the options specified in +# the second argument. +__git_ls_files_helper () +{ + ( + test -n "${CDPATH+set}" && unset CDPATH + # NOTE: $2 is not quoted in order to support multiple options + cd "$1" && git ls-files --exclude-standard $2 + ) 2>/dev/null +} + + +# Execute git diff-index, returning paths relative to the directory +# specified in the first argument, and using the tree object id +# specified in the second argument. +__git_diff_index_helper () +{ + ( + test -n "${CDPATH+set}" && unset CDPATH + cd "$1" && git diff-index --name-only --relative "$2" + ) 2>/dev/null +} + +# __git_index_files accepts 1 or 2 arguments: +# 1: Options to pass to ls-files (required). +# Supported options are --cached, --modified, --deleted, --others, +# and --directory. +# 2: A directory path (optional). +# If provided, only files within the specified directory are listed. +# Sub directories are never recursed. Path must have a trailing +# slash. +__git_index_files () +{ + local dir="$(__gitdir)" root="${2-.}" + + if [ -d "$dir" ]; then + __git_ls_files_helper "$root" "$1" | __git_index_file_list_filter | + sort | uniq + fi +} + +# __git_diff_index_files accepts 1 or 2 arguments: +# 1) The id of a tree object. +# 2) A directory path (optional). +# If provided, only files within the specified directory are listed. +# Sub directories are never recursed. Path must have a trailing +# slash. +__git_diff_index_files () +{ + local dir="$(__gitdir)" root="${2-.}" + + if [ -d "$dir" ]; then + __git_diff_index_helper "$root" "$1" | __git_index_file_list_filter | + sort | uniq + fi +} + __git_heads () { local dir="$(__gitdir)" @@ -321,7 +409,7 @@ __git_refs () if [[ "$ref" == "$cur"* ]]; then echo "$ref" fi - done | uniq -u + done | sort | uniq -u fi return fi @@ -428,7 +516,7 @@ __git_complete_revlist_file () *) pfx="$ref:$pfx" ;; esac - __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \ + __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \ | sed '/^100... blob /{ s,^.* ,, s,$, , @@ -461,6 +549,46 @@ __git_complete_revlist_file () } +# __git_complete_index_file requires 1 argument: the options to pass to +# ls-file +__git_complete_index_file () +{ + local pfx cur_="$cur" + + case "$cur_" in + ?*/*) + pfx="${cur_%/*}" + cur_="${cur_##*/}" + pfx="${pfx}/" + + __gitcomp_file "$(__git_index_files "$1" "$pfx")" "$pfx" "$cur_" + ;; + *) + __gitcomp_file "$(__git_index_files "$1")" "" "$cur_" + ;; + esac +} + +# __git_complete_diff_index_file requires 1 argument: the id of a tree +# object +__git_complete_diff_index_file () +{ + local pfx cur_="$cur" + + case "$cur_" in + ?*/*) + pfx="${cur_%/*}" + cur_="${cur_##*/}" + pfx="${pfx}/" + + __gitcomp_file "$(__git_diff_index_files "$1" "$pfx")" "$pfx" "$cur_" + ;; + *) + __gitcomp_file "$(__git_diff_index_files "$1")" "" "$cur_" + ;; + esac +} + __git_complete_file () { __git_complete_revlist_file @@ -562,10 +690,19 @@ __git_complete_strategy () return 1 } +__git_commands () { + if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}" + then + printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" + else + git help -a|egrep '^ [a-zA-Z0-9]' + fi +} + __git_list_all_commands () { local i IFS=" "$'\n' - for i in $(git help -a|egrep '^ [a-zA-Z0-9]') + for i in $(__git_commands) do case $i in *--*) : helper pattern;; @@ -585,7 +722,7 @@ __git_list_porcelain_commands () { local i IFS=" "$'\n' __git_compute_all_commands - for i in "help" $__git_all_commands + for i in $__git_all_commands do case $i in *--*) : helper pattern;; @@ -594,6 +731,7 @@ __git_list_porcelain_commands () archimport) : import;; cat-file) : plumbing;; check-attr) : plumbing;; + check-ignore) : plumbing;; check-ref-format) : plumbing;; checkout-index) : plumbing;; commit-tree) : plumbing;; @@ -753,6 +891,43 @@ __git_has_doubledash () return 1 } +# Try to count non option arguments passed on the command line for the +# specified git command. +# When options are used, it is necessary to use the special -- option to +# tell the implementation were non option arguments begin. +# XXX this can not be improved, since options can appear everywhere, as +# an example: +# git mv x -n y +# +# __git_count_arguments requires 1 argument: the git command executed. +__git_count_arguments () +{ + local word i c=0 + + # Skip "git" (first argument) + for ((i=1; i < ${#words[@]}; i++)); do + word="${words[i]}" + + case "$word" in + --) + # Good; we can assume that the following are only non + # option arguments. + ((c = 0)) + ;; + "$1") + # Skip the specified git command and discard git + # main options + ((c = 0)) + ;; + ?*) + ((c++)) + ;; + esac + done + + printf "%d" $c +} + __git_whitespacelist="nowarn warn error error-all fix" _git_am () @@ -801,8 +976,6 @@ _git_apply () _git_add () { - __git_has_doubledash && return - case "$cur" in --*) __gitcomp " @@ -811,7 +984,9 @@ _git_add () " return esac - COMPREPLY=() + + # XXX should we check for --update and --all options ? + __git_complete_index_file "--others --modified" } _git_archive () @@ -961,15 +1136,15 @@ _git_cherry_pick () _git_clean () { - __git_has_doubledash && return - case "$cur" in --*) __gitcomp "--dry-run --quiet" return ;; esac - COMPREPLY=() + + # XXX should we check for -x option ? + __git_complete_index_file "--others" } _git_clone () @@ -989,6 +1164,8 @@ _git_clone () --upload-pack --template= --depth + --single-branch + --branch " return ;; @@ -998,7 +1175,19 @@ _git_clone () _git_commit () { - __git_has_doubledash && return + case "$prev" in + -c|-C) + __gitcomp_nl "$(__git_refs)" "" "${cur}" + return + ;; + esac + + case "$prev" in + -c|-C) + __gitcomp_nl "$(__git_refs)" "" "${cur}" + return + ;; + esac case "$cur" in --cleanup=*) @@ -1027,7 +1216,13 @@ _git_commit () " return esac - COMPREPLY=() + + if git rev-parse --verify --quiet HEAD >/dev/null; then + __git_complete_diff_index_file "HEAD" + else + # This is the first commit + __git_complete_index_file "--cached" + fi } _git_describe () @@ -1043,6 +1238,8 @@ _git_describe () __gitcomp_nl "$(__git_refs)" } +__git_diff_algorithms="myers minimal patience histogram" + __git_diff_common_options="--stat --numstat --shortstat --summary --patch-with-stat --name-only --name-status --color --no-color --color-words --no-renames --check @@ -1053,10 +1250,11 @@ __git_diff_common_options="--stat --numstat --shortstat --summary --no-ext-diff --no-prefix --src-prefix= --dst-prefix= --inter-hunk-context= - --patience + --patience --histogram --minimal --raw --dirstat --dirstat= --dirstat-by-file --dirstat-by-file= --cumulative + --diff-algorithm= " _git_diff () @@ -1064,6 +1262,10 @@ _git_diff () __git_has_doubledash && return case "$cur" in + --diff-algorithm=*) + __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}" + return + ;; --*) __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex --base --ours --theirs --no-index @@ -1116,6 +1318,14 @@ _git_fetch () __git_complete_remote_or_refspec } +__git_format_patch_options=" + --stdout --attach --no-attach --thread --thread= --output-directory + --numbered --start-number --numbered-files --keep-subject --signoff + --signature --no-signature --in-reply-to= --cc= --full-index --binary + --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix= + --inline --suffix= --ignore-if-in-upstream --subject-prefix= +" + _git_format_patch () { case "$cur" in @@ -1126,21 +1336,7 @@ _git_format_patch () return ;; --*) - __gitcomp " - --stdout --attach --no-attach --thread --thread= - --output-directory - --numbered --start-number - --numbered-files - --keep-subject - --signoff --signature --no-signature - --in-reply-to= --cc= - --full-index --binary - --not --all - --cover-letter - --no-prefix --src-prefix= --dst-prefix= - --inline --suffix= --ignore-if-in-upstream - --subject-prefix= - " + __gitcomp "$__git_format_patch_options" return ;; esac @@ -1251,8 +1447,6 @@ _git_init () _git_ls_files () { - __git_has_doubledash && return - case "$cur" in --*) __gitcomp "--cached --deleted --modified --others --ignored @@ -1265,7 +1459,10 @@ _git_ls_files () return ;; esac - COMPREPLY=() + + # XXX ignore options like --modified and always suggest all cached + # files. + __git_complete_index_file "--cached" } _git_ls_remote () @@ -1397,7 +1594,14 @@ _git_mv () return ;; esac - COMPREPLY=() + + if [ $(__git_count_arguments "mv") -gt 0 ]; then + # We need to show both cached and untracked files (including + # empty directories) since this may not be the last argument. + __git_complete_index_file "--cached --others --directory" + else + __git_complete_index_file "--cached" + fi } _git_name_rev () @@ -1554,6 +1758,12 @@ _git_send_email () __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}" return ;; + --thread=*) + __gitcomp " + deep shallow + " "" "${cur##--thread=}" + return + ;; --*) __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to --compose --confirm= --dry-run --envelope-sender @@ -1563,11 +1773,12 @@ _git_send_email () --signed-off-by-cc --smtp-pass --smtp-server --smtp-server-port --smtp-encryption= --smtp-user --subject --suppress-cc= --suppress-from --thread --to - --validate --no-validate" + --validate --no-validate + $__git_format_patch_options" return ;; esac - COMPREPLY=() + __git_complete_revlist } _git_stage () @@ -1581,7 +1792,7 @@ __git_config_get_set_variables () while [ $c -gt 1 ]; do word="${words[c]}" case "$word" in - --global|--system|--file=*) + --system|--global|--local|--file=*) config_file="$word" break ;; @@ -1687,7 +1898,7 @@ _git_config () case "$cur" in --*) __gitcomp " - --global --system --file= + --system --global --local --file= --list --replace-all --get --get-all --get-regexp --add --unset --unset-all @@ -1860,6 +2071,7 @@ _git_config () diff.suppressBlankEmpty diff.tool diff.wordRegex + diff.algorithm difftool. difftool.prompt fetch.recurseSubmodules @@ -2096,15 +2308,14 @@ _git_revert () _git_rm () { - __git_has_doubledash && return - case "$cur" in --*) __gitcomp "--cached --dry-run --ignore-unmatch --quiet" return ;; esac - COMPREPLY=() + + __git_complete_index_file "--cached" } _git_shortlog () @@ -2134,6 +2345,10 @@ _git_show () " "" "${cur#*=}" return ;; + --diff-algorithm=*) + __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}" + return + ;; --*) __gitcomp "--pretty= --format= --abbrev-commit --oneline $__git_diff_common_options @@ -2429,20 +2644,88 @@ __gitk_main () __git_complete_revlist } +if [[ -n ${ZSH_VERSION-} ]]; then + echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2 + + autoload -U +X compinit && compinit + + __gitcomp () + { + emulate -L zsh + + local cur_="${3-$cur}" + + case "$cur_" in + --*=) + ;; + *) + local c IFS=$' \t\n' + local -a array + for c in ${=1}; do + c="$c${4-}" + case $c in + --*=*|*.) ;; + *) c="$c " ;; + esac + array[$#array+1]="$c" + done + compset -P '*[=:]' + compadd -Q -S '' -p "${2-}" -a -- array && _ret=0 + ;; + esac + } + + __gitcomp_nl () + { + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 + } + + __gitcomp_file () + { + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -p "${2-}" -f -- ${=1} && _ret=0 + } + + __git_zsh_helper () + { + emulate -L ksh + local cur cword prev + cur=${words[CURRENT-1]} + prev=${words[CURRENT-2]} + let cword=CURRENT-1 + __${service}_main + } + + _git () + { + emulate -L zsh + local _ret=1 + __git_zsh_helper + let _ret && _default -S '' && _ret=0 + return _ret + } + + compdef _git git gitk + return +elif [[ -n ${BASH_VERSION-} ]]; then + if ((${BASH_VERSINFO[0]} < 4)); then + # compopt is not supported + __git_index_file_list_filter () + { + __git_index_file_list_filter_compat + } + fi +fi + __git_func_wrap () { - if [[ -n ${ZSH_VERSION-} ]]; then - emulate -L bash - setopt KSH_TYPESET - - # workaround zsh's bug that leaves 'words' as a special - # variable in versions < 4.3.12 - typeset -h words - - # workaround zsh's bug that quotes spaces in the COMPREPLY - # array if IFS doesn't contain spaces. - typeset -h IFS - fi local cur words cword prev _get_comp_words_by_ref -n =: cur words cword prev $1 diff --git a/plugins/gitfast/git-prompt.sh b/plugins/gitfast/git-prompt.sh index afd76e86e..65f8368f1 100644 --- a/plugins/gitfast/git-prompt.sh +++ b/plugins/gitfast/git-prompt.sh @@ -10,9 +10,22 @@ # 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh). # 2) Add the following line to your .bashrc/.zshrc: # source ~/.git-prompt.sh -# 3) Change your PS1 to also show the current branch: -# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' -# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# 3a) Change your PS1 to call __git_ps1 as +# command-substitution: +# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' +# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# the optional argument will be used as format string. +# 3b) Alternatively, if you are using bash, __git_ps1 can be +# used for PROMPT_COMMAND with two parameters,
 and
+#        , which are strings you would put in $PS1 before
+#        and after the status string generated by the git-prompt
+#        machinery.  e.g.
+#           PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
+#        will show username, at-sign, host, colon, cwd, then
+#        various status string, followed by dollar and SP, as
+#        your prompt.
+#        Optionally, you can supply a third argument with a printf
+#        format string to finetune the output of the branch status
 #
 # The argument to __git_ps1 will be displayed only if you are currently
 # in a git repository.  The %s token will be the name of the current
@@ -30,7 +43,10 @@
 #
 # If you would like to see if there're untracked files, then you can set
 # GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
-# files, then a '%' will be shown next to the branch name.
+# files, then a '%' will be shown next to the branch name.  You can
+# configure this per-repository with the bash.showUntrackedFiles
+# variable, which defaults to true once GIT_PS1_SHOWUNTRACKEDFILES is
+# enabled.
 #
 # If you would like to see the difference between HEAD and its upstream,
 # set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates you are behind, ">"
@@ -49,6 +65,19 @@
 # find one, or @{upstream} otherwise.  Once you have set
 # GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
 # setting the bash.showUpstream config variable.
+#
+# If you would like to see more information about the identity of
+# commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE
+# to one of these values:
+#
+#     contains      relative to newer annotated tag (v1.6.3.2~35)
+#     branch        relative to newer tag or branch (master~4)
+#     describe      relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
+#     default       exactly matching tag
+#
+# If you would like a colored hint about the current dirty state, set
+# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
+# the colored output of "git status -sb".
 
 # __gitdir accepts 0 or 1 arguments (i.e., location)
 # returns location of .git repo
@@ -195,11 +224,43 @@ __git_ps1_show_upstream ()
 
 
 # __git_ps1 accepts 0 or 1 arguments (i.e., format string)
-# returns text to add to bash PS1 prompt (includes branch name)
+# when called from PS1 using command substitution
+# in this mode it prints text to add to bash PS1 prompt (includes branch name)
+#
+# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc)
+# in that case it _sets_ PS1. The arguments are parts of a PS1 string.
+# when two arguments are given, the first is prepended and the second appended
+# to the state string when assigned to PS1.
+# The optional third parameter will be used as printf format string to further
+# customize the output of the git-status string.
+# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
 __git_ps1 ()
 {
+	local pcmode=no
+	local detached=no
+	local ps1pc_start='\u@\h:\w '
+	local ps1pc_end='\$ '
+	local printf_format=' (%s)'
+
+	case "$#" in
+		2|3)	pcmode=yes
+			ps1pc_start="$1"
+			ps1pc_end="$2"
+			printf_format="${3:-$printf_format}"
+		;;
+		0|1)	printf_format="${1:-$printf_format}"
+		;;
+		*)	return
+		;;
+	esac
+
 	local g="$(__gitdir)"
-	if [ -n "$g" ]; then
+	if [ -z "$g" ]; then
+		if [ $pcmode = yes ]; then
+			#In PC mode PS1 always needs to be set
+			PS1="$ps1pc_start$ps1pc_end"
+		fi
+	else
 		local r=""
 		local b=""
 		if [ -f "$g/rebase-merge/interactive" ]; then
@@ -226,7 +287,7 @@ __git_ps1 ()
 			fi
 
 			b="$(git symbolic-ref HEAD 2>/dev/null)" || {
-
+				detached=yes
 				b="$(
 				case "${GIT_PS1_DESCRIBE_STYLE-}" in
 				(contains)
@@ -259,24 +320,25 @@ __git_ps1 ()
 				b="GIT_DIR!"
 			fi
 		elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
-			if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
-				if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
-					git diff --no-ext-diff --quiet --exit-code || w="*"
-					if git rev-parse --quiet --verify HEAD >/dev/null; then
-						git diff-index --cached --quiet HEAD -- || i="+"
-					else
-						i="#"
-					fi
+			if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
+			   [ "$(git config --bool bash.showDirtyState)" != "false" ]
+			then
+				git diff --no-ext-diff --quiet --exit-code || w="*"
+				if git rev-parse --quiet --verify HEAD >/dev/null; then
+					git diff-index --cached --quiet HEAD -- || i="+"
+				else
+					i="#"
 				fi
 			fi
 			if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
 				git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
 			fi
 
-			if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
-				if [ -n "$(git ls-files --others --exclude-standard)" ]; then
-					u="%%"
-				fi
+			if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
+			   [ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
+			   [ -n "$(git ls-files --others --exclude-standard)" ]
+			then
+				u="%%"
 			fi
 
 			if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
@@ -285,6 +347,53 @@ __git_ps1 ()
 		fi
 
 		local f="$w$i$s$u"
-		printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
+		if [ $pcmode = yes ]; then
+			local gitstring=
+			if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+				local c_red='\e[31m'
+				local c_green='\e[32m'
+				local c_lblue='\e[1;34m'
+				local c_clear='\e[0m'
+				local bad_color=$c_red
+				local ok_color=$c_green
+				local branch_color="$c_clear"
+				local flags_color="$c_lblue"
+				local branchstring="$c${b##refs/heads/}"
+
+				if [ $detached = no ]; then
+					branch_color="$ok_color"
+				else
+					branch_color="$bad_color"
+				fi
+
+				# Setting gitstring directly with \[ and \] around colors
+				# is necessary to prevent wrapping issues!
+				gitstring="\[$branch_color\]$branchstring\[$c_clear\]"
+
+				if [ -n "$w$i$s$u$r$p" ]; then
+					gitstring="$gitstring "
+				fi
+				if [ "$w" = "*" ]; then
+					gitstring="$gitstring\[$bad_color\]$w"
+				fi
+				if [ -n "$i" ]; then
+					gitstring="$gitstring\[$ok_color\]$i"
+				fi
+				if [ -n "$s" ]; then
+					gitstring="$gitstring\[$flags_color\]$s"
+				fi
+				if [ -n "$u" ]; then
+					gitstring="$gitstring\[$bad_color\]$u"
+				fi
+				gitstring="$gitstring\[$c_clear\]$r$p"
+			else
+				gitstring="$c${b##refs/heads/}${f:+ $f}$r$p"
+			fi
+			gitstring=$(printf -- "$printf_format" "$gitstring")
+			PS1="$ps1pc_start$gitstring$ps1pc_end"
+		else
+			# NO color option unless in PROMPT_COMMAND mode
+			printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p"
+		fi
 	fi
 }
diff --git a/plugins/gitfast/gitfast.plugin.zsh b/plugins/gitfast/gitfast.plugin.zsh
index 7e50cf721..dba1b1315 100644
--- a/plugins/gitfast/gitfast.plugin.zsh
+++ b/plugins/gitfast/gitfast.plugin.zsh
@@ -3,5 +3,6 @@ source $dir/../git/git.plugin.zsh
 source $dir/git-prompt.sh
 
 function git_prompt_info() {
-  __git_ps1 "${ZSH_THEME_GIT_PROMPT_PREFIX//\%/%%}%s${ZSH_THEME_GIT_PROMPT_SUFFIX//\%/%%}"
+  dirty="$(parse_git_dirty)"
+  __git_ps1 "${ZSH_THEME_GIT_PROMPT_PREFIX//\%/%%}%s${dirty//\%/%%}${ZSH_THEME_GIT_PROMPT_SUFFIX//\%/%%}"
 }
diff --git a/plugins/go/go.plugin.zsh b/plugins/go/go.plugin.zsh
new file mode 100644
index 000000000..23afa9656
--- /dev/null
+++ b/plugins/go/go.plugin.zsh
@@ -0,0 +1,151 @@
+# install in /etc/zsh/zshrc or your personal .zshrc
+
+# gc
+prefixes=(5 6 8)
+for p in $prefixes; do
+	compctl -g "*.${p}" ${p}l
+	compctl -g "*.go" ${p}g
+done
+
+# standard go tools
+compctl -g "*.go" gofmt
+
+# gccgo
+compctl -g "*.go" gccgo
+
+# go tool
+__go_tool_complete() {
+  typeset -a commands build_flags
+  commands+=(
+    'build[compile packages and dependencies]'
+    'clean[remove object files]'
+    'doc[run godoc on package sources]'
+    'fix[run go tool fix on packages]'
+    'fmt[run gofmt on package sources]'
+    'get[download and install packages and dependencies]'
+    'help[display help]'
+    'install[compile and install packages and dependencies]'
+    'list[list packages]'
+    'run[compile and run Go program]'
+    'test[test packages]'
+    'tool[run specified go tool]'
+    'version[print Go version]'
+    'vet[run go tool vet on packages]'
+  )
+  if (( CURRENT == 2 )); then
+    # explain go commands
+    _values 'go tool commands' ${commands[@]}
+    return
+  fi
+  build_flags=(
+    '-a[force reinstallation of packages that are already up-to-date]'
+    '-n[print the commands but do not run them]'
+    "-p[number of parallel builds]:number"
+    '-x[print the commands]'
+    "-work[print temporary directory name and keep it]"
+    "-gcflags[flags for 5g/6g/8g]:flags"
+    "-ldflags[flags for 5l/6l/8l]:flags"
+    "-gccgoflags[flags for gccgo]:flags"
+  )
+  __go_list() {
+      local expl importpaths
+      declare -a importpaths
+      importpaths=($(go list ${words[$CURRENT]}... 2>/dev/null))
+      _wanted importpaths expl 'import paths' compadd "$@" - "${importpaths[@]}"
+  }
+  case ${words[2]} in
+  clean|doc)
+      _arguments -s -w : '*:importpaths:__go_list'
+      ;;
+  fix|fmt|list|vet)
+      _alternative ':importpaths:__go_list' ':files:_path_files -g "*.go"'
+      ;;
+  install)
+      _arguments -s -w : ${build_flags[@]} \
+        "-v[show package names]" \
+	'*:importpaths:__go_list'
+      ;;
+  get)
+      _arguments -s -w : \
+        ${build_flags[@]}
+      ;;
+  build)
+      _arguments -s -w : \
+        ${build_flags[@]} \
+        "-v[show package names]" \
+        "-o[output file]:file:_files" \
+        "*:args:{ _alternative ':importpaths:__go_list' ':files:_path_files -g \"*.go\"' }"
+      ;;
+  test)
+      _arguments -s -w : \
+        ${build_flags[@]} \
+        "-c[do not run, compile the test binary]" \
+        "-i[do not run, install dependencies]" \
+        "-v[print test output]" \
+        "-x[print the commands]" \
+        "-short[use short mode]" \
+        "-parallel[number of parallel tests]:number" \
+        "-cpu[values of GOMAXPROCS to use]:number list" \
+        "-run[run tests and examples matching regexp]:regexp" \
+        "-bench[run benchmarks matching regexp]:regexp" \
+        "-benchtime[run each benchmark during n seconds]:duration" \
+        "-timeout[kill test after that duration]:duration" \
+        "-cpuprofile[write CPU profile to file]:file:_files" \
+        "-memprofile[write heap profile to file]:file:_files" \
+        "-memprofilerate[set heap profiling rate]:number" \
+        "*:args:{ _alternative ':importpaths:__go_list' ':files:_path_files -g \"*.go\"' }"
+      ;;
+  help)
+      _values "${commands[@]}" \
+        'gopath[GOPATH environment variable]' \
+        'importpath[description of import paths]' \
+        'remote[remote import path syntax]' \
+        'testflag[description of testing flags]' \
+        'testfunc[description of testing functions]'
+      ;;
+  run)
+      _arguments -s -w : \
+          ${build_flags[@]} \
+          '*:file:_path_files -g "*.go"'
+      ;;
+  tool)
+      if (( CURRENT == 3 )); then
+          _values "go tool" $(go tool)
+          return
+      fi
+      case ${words[3]} in
+      [568]g)
+          _arguments -s -w : \
+              '-I[search for packages in DIR]:includes:_path_files -/' \
+              '-L[show full path in file:line prints]' \
+              '-S[print the assembly language]' \
+              '-V[print the compiler version]' \
+              '-e[no limit on number of errors printed]' \
+              '-h[panic on an error]' \
+              '-l[disable inlining]' \
+              '-m[print optimization decisions]' \
+              '-o[file specify output file]:file' \
+              '-p[assumed import path for this code]:importpath' \
+              '-u[disable package unsafe]' \
+              "*:file:_files -g '*.go'"
+          ;;
+      [568]l)
+          local O=${words[3]%l}
+          _arguments -s -w : \
+              '-o[file specify output file]:file' \
+              '-L[search for packages in DIR]:includes:_path_files -/' \
+              "*:file:_files -g '*.[ao$O]'"
+          ;;
+      dist)
+          _values "dist tool" banner bootstrap clean env install version
+          ;;
+      *)
+          # use files by default
+          _files
+          ;;
+      esac
+      ;;
+  esac
+}
+
+compdef __go_tool_complete go
diff --git a/plugins/gpg-agent/gpg-agent.plugin.zsh b/plugins/gpg-agent/gpg-agent.plugin.zsh
index 8cc71fd57..4071334cb 100644
--- a/plugins/gpg-agent/gpg-agent.plugin.zsh
+++ b/plugins/gpg-agent/gpg-agent.plugin.zsh
@@ -1,26 +1,38 @@
-# Based on ssh-agent code
-
 local GPG_ENV=$HOME/.gnupg/gpg-agent.env
 
-function start_agent {
-  /usr/bin/env gpg-agent --daemon --enable-ssh-support --write-env-file ${GPG_ENV} > /dev/null
-  chmod 600 ${GPG_ENV}
-  . ${GPG_ENV} > /dev/null
+function start_agent_nossh {
+    eval $(/usr/bin/env gpg-agent --quiet --daemon --write-env-file ${GPG_ENV} 2> /dev/null)
+    chmod 600 ${GPG_ENV}
+    export GPG_AGENT_INFO
 }
 
-# Source GPG agent settings, if applicable
-if [ -f "${GPG_ENV}" ]; then
-  . ${GPG_ENV} > /dev/null
-  ps -ef | grep ${SSH_AGENT_PID} | grep gpg-agent > /dev/null || {
-    start_agent;
-  }
-else
-  start_agent;
-fi
+function start_agent_withssh {
+    eval $(/usr/bin/env gpg-agent --quiet --daemon --enable-ssh-support --write-env-file ${GPG_ENV} 2> /dev/null)
+    chmod 600 ${GPG_ENV}
+    export GPG_AGENT_INFO
+    export SSH_AUTH_SOCK
+    export SSH_AGENT_PID
+}
 
-export GPG_AGENT_INFO
-export SSH_AUTH_SOCK
-export SSH_AGENT_PID
+# check if another agent is running
+if ! gpg-connect-agent --quiet /bye > /dev/null 2> /dev/null; then
+    # source settings of old agent, if applicable
+    if [ -f "${GPG_ENV}" ]; then
+        . ${GPG_ENV} > /dev/null
+    fi
+
+    # check again if another agent is running using the newly sourced settings
+    if ! gpg-connect-agent --quiet /bye > /dev/null 2> /dev/null; then
+        # check for existing ssh-agent
+        if ssh-add -l > /dev/null 2> /dev/null; then
+            # ssh-agent running, start gpg-agent without ssh support
+            start_agent_nossh;
+        else
+            # otherwise start gpg-agent with ssh support
+            start_agent_withssh;
+        fi
+    fi
+fi
 
 GPG_TTY=$(tty)
 export GPG_TTY
diff --git a/plugins/jira/jira.plugin.zsh b/plugins/jira/jira.plugin.zsh
index b91f93c95..9aa192c1e 100644
--- a/plugins/jira/jira.plugin.zsh
+++ b/plugins/jira/jira.plugin.zsh
@@ -3,7 +3,7 @@
 #         .jira-url in the current directory takes precedence
 #
 # If you use Rapid Board, set:
-#JIRA_RAPID_BOARD="yes"
+#JIRA_RAPID_BOARD="true"
 # in you .zshrc
 #
 # Setup: cd to/my/project
@@ -11,6 +11,13 @@
 # Usage: jira           # opens a new issue
 #        jira ABC-123   # Opens an existing issue
 open_jira_issue () {
+  local open_cmd
+  if [[ $(uname -s) == 'Darwin' ]]; then
+    open_cmd='open'
+  else
+    open_cmd='xdg-open'
+  fi
+
   if [ -f .jira-url ]; then
     jira_url=$(cat .jira-url)
   elif [ -f ~/.jira-url ]; then
@@ -27,10 +34,10 @@ open_jira_issue () {
     `open $jira_url/secure/CreateIssue!default.jspa`
   else
     echo "Opening issue #$1"
-    if [[ "x$JIRA_RAPID_BOARD" = "yes" ]]; then
-      `open $jira_url/issues/$1`
+    if [[ "x$JIRA_RAPID_BOARD" = "xtrue" ]]; then
+      $open_cmd  "$jira_url/issues/$1"
     else
-      `open $jira_url/browse/$1`
+      $open_cmd  "$jira_url/browse/$1"
     fi
   fi
 }
diff --git a/plugins/knife/_knife b/plugins/knife/_knife
index 9f5b406af..b44283f78 100644
--- a/plugins/knife/_knife
+++ b/plugins/knife/_knife
@@ -31,7 +31,7 @@ _knife() {
   
   case $state in
   knifecmd)
-    compadd -Q "$@" bootstrap client configure cookbook "cookbook site" "data bag" exec environment index node recipe role search ssh status windows $cloudproviders
+    compadd -Q "$@" bootstrap client configure cookbook "cookbook site" "data bag" diff exec environment index node recipe role search ssh status upload windows $cloudproviders
   ;;
   knifesubcmd)
     case $words[2] in
@@ -47,9 +47,12 @@ _knife() {
     cookbook)
       compadd -Q "$@" test list create download delete "metadata from" show "bulk delete" metadata upload
     ;;
-  environment)
+    diff)
+      _arguments '*:file or directory:_files -g "*"'
+    ;;
+    environment)
       compadd -Q "$@" list create delete edit show "from file"
-      ;;
+    ;;
     node)
      compadd -Q "$@" "from file" create show edit delete list run_list "bulk delete"
     ;;
@@ -59,6 +62,9 @@ _knife() {
     role)
       compadd -Q "$@" "bulk delete" create delete edit "from file" list show
     ;; 
+    upload)
+     _arguments '*:file or directory:_files -g "*"'
+    ;;
     windows)
       compadd "$@" bootstrap
     ;;
diff --git a/plugins/knife_ssh/knife_ssh.plugin.zsh b/plugins/knife_ssh/knife_ssh.plugin.zsh
new file mode 100644
index 000000000..7fdd42a1e
--- /dev/null
+++ b/plugins/knife_ssh/knife_ssh.plugin.zsh
@@ -0,0 +1,18 @@
+function knife_ssh() {
+  grep -q $1 ~/.knife_comp~ 2> /dev/null || rm -f ~/.knife_comp~;
+  ssh $(knife node show $1 | awk '/IP:/{print $2}')
+}
+
+_knife_ssh() {
+  if hash knife 2>/dev/null; then
+    if [[ ! -f ~/.knife_comp~ ]]; then
+      echo "\nGenerating ~/.knife_comp~..." >/dev/stderr
+      knife node list > ~/.knife_comp~
+    fi
+    compadd $(<~/.knife_comp~)
+  else
+    echo "Could not find knife" > /dev/stderr;
+  fi
+}
+
+compdef _knife_ssh knife_ssh
diff --git a/plugins/mercurial/mercurial.plugin.zsh b/plugins/mercurial/mercurial.plugin.zsh
index 30e4be5b5..c18aa726c 100644
--- a/plugins/mercurial/mercurial.plugin.zsh
+++ b/plugins/mercurial/mercurial.plugin.zsh
@@ -1,8 +1,8 @@
-
 # Mercurial
 alias hgc='hg commit'
 alias hgb='hg branch'
 alias hgba='hg branches'
+alias hgbk='hg bookmarks'
 alias hgco='hg checkout'
 alias hgd='hg diff'
 alias hged='hg diffmerge'
@@ -16,8 +16,48 @@ alias hgs='hg status'
 # this is the 'git commit --amend' equivalent
 alias hgca='hg qimport -r tip ; hg qrefresh -e ; hg qfinish tip'
 
-function hg_current_branch() {
-  if [ -d .hg ]; then
-    echo hg:$(hg branch)
+function in_hg() {
+  if [[ -d .hg ]] || $(hg summary > /dev/null 2>&1); then
+    echo 1
   fi
 }
+
+function hg_get_branch_name() {
+  if [ $(in_hg) ]; then
+    echo $(hg branch)
+  fi
+}
+
+function hg_prompt_info {
+  if [ $(in_hg) ]; then
+    _DISPLAY=$(hg_get_branch_name)
+    echo "$ZSH_PROMPT_BASE_COLOR$ZSH_THEME_HG_PROMPT_PREFIX\
+$ZSH_THEME_REPO_NAME_COLOR$_DISPLAY$ZSH_PROMPT_BASE_COLOR$ZSH_THEME_HG_PROMPT_SUFFIX$ZSH_PROMPT_BASE_COLOR$(hg_dirty)$ZSH_PROMPT_BASE_COLOR"
+    unset _DISPLAY
+  fi
+}
+
+function hg_dirty_choose {
+  if [ $(in_hg) ]; then
+    hg status 2> /dev/null | grep -Eq '^\s*[ACDIM!?L]'
+    if [ $pipestatus[-1] -eq 0 ]; then
+      # Grep exits with 0 when "One or more lines were selected", return "dirty".
+      echo $1
+    else
+      # Otherwise, no lines were found, or an error occurred. Return clean.
+      echo $2
+    fi
+  fi
+}
+
+function hg_dirty {
+  hg_dirty_choose $ZSH_THEME_HG_PROMPT_DIRTY $ZSH_THEME_HG_PROMPT_CLEAN
+}
+
+function hgic() {
+    hg incoming "$@" | grep "changeset" | wc -l
+}
+
+function hgoc() {
+    hg outgoing "$@" | grep "changeset" | wc -l
+}
diff --git a/plugins/mix/_mix b/plugins/mix/_mix
new file mode 100644
index 000000000..602f5ffa0
--- /dev/null
+++ b/plugins/mix/_mix
@@ -0,0 +1,63 @@
+#compdef mix 
+#autoload
+
+# Elixir mix zsh completion
+
+local -a _1st_arguments
+_1st_arguments=(
+    'archive:Archive this project into a .ez file'
+    'clean:Clean generated application files'
+    'compile:Compile source files'
+    'deps:List dependencies and their status'
+    "deps.clean:Remove dependencies' files"
+    'deps.compile:Compile dependencies'
+    'deps.get:Get all out of date dependencies'
+    'deps.unlock:Unlock the given dependencies'
+    'deps.update:Update dependencies'
+    'do:Executes the commands separated by comma'
+    'escriptize:Generates an escript for the project'
+    'help:Print help information for tasks'
+    'local:List local tasks'
+    'local.install:Install a task or an archive locally'
+    'local.rebar:Install rebar locally'
+    'local.uninstall:Uninstall local tasks or archives'
+    'new:Creates a new Elixir project'
+    'run:Run the given file or expression'
+    "test:Run a project's tests"
+    '--help:Describe available tasks'
+    '--version:Prints the Elixir version information'
+)
+
+__task_list ()
+{
+    local expl
+    declare -a tasks
+
+    tasks=(archive clean compile deps deps.clean deps.compile deps.get deps.unlock deps.update do escriptize help local local.install local.rebar local.uninstall new run test)
+
+    _wanted tasks expl 'help' compadd $tasks
+}
+
+local expl
+
+local curcontext="$curcontext" state line
+typeset -A opt_args
+
+_arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+case $state in
+  (command)
+      _describe -t commands "mix subcommand" _1st_arguments
+      return
+  ;;
+
+  (options)
+    case $line[1] in
+      (help)
+         _arguments ':feature:__task_list' 
+    esac
+  ;;
+esac
+
diff --git a/plugins/mvn/mvn.plugin.zsh b/plugins/mvn/mvn.plugin.zsh
index c2d8e7ed7..799f6fc8c 100644
--- a/plugins/mvn/mvn.plugin.zsh
+++ b/plugins/mvn/mvn.plugin.zsh
@@ -114,7 +114,7 @@ function listMavenCompletions {
         # jboss
         jboss:start jboss:stop jboss:deploy jboss:undeploy jboss:redeploy
         # tomcat
-        tomcat:start tomcat:stop tomcat:deploy tomcat:undeploy tomcat:undeploy
+        tomcat:start tomcat:stop tomcat:deploy tomcat:undeploy tomcat:redeploy
         # tomcat6
         tomcat6:run tomcat6:run-war tomcat6:run-war-only tomcat6:stop tomcat6:deploy tomcat6:undeploy
         # tomcat7
diff --git a/plugins/osx/osx.plugin.zsh b/plugins/osx/osx.plugin.zsh
index 51cd7c143..dd785f911 100644
--- a/plugins/osx/osx.plugin.zsh
+++ b/plugins/osx/osx.plugin.zsh
@@ -6,7 +6,7 @@
 # ------------------------------------------------------------------------------
 
 function tab() {
-  local command="cd \\\"$PWD\\\""
+  local command="cd \\\"$PWD\\\"; clear; "
   (( $# > 0 )) && command="${command}; $*"
 
   the_app=$(
@@ -34,7 +34,7 @@ EOF
           launch session "Default Session"
           set current_session to current session
           tell current_session
-            write text "${command}; clear;"
+            write text "${command}"
           end tell
         end tell
       end tell
diff --git a/plugins/postgres/postgres.plugin.zsh b/plugins/postgres/postgres.plugin.zsh
new file mode 100644
index 000000000..cdd142e92
--- /dev/null
+++ b/plugins/postgres/postgres.plugin.zsh
@@ -0,0 +1,6 @@
+# Aliases to stop, start and restart Postgres
+# Paths noted below are for Postgress installed via Homebrew on OSX
+
+alias startpost='pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start'
+alias stoppost='pg_ctl -D /usr/local/var/postgres stop -s -m fast'
+alias restartpost='stoppost && sleep 1 && startpost'
\ No newline at end of file
diff --git a/plugins/rails/rails.plugin.zsh b/plugins/rails/rails.plugin.zsh
index d3849b4f4..dd8b174b2 100644
--- a/plugins/rails/rails.plugin.zsh
+++ b/plugins/rails/rails.plugin.zsh
@@ -10,6 +10,11 @@ alias migrate='rake db:migrate && rake db:test:prepare'
 alias sc='ruby script/console'
 alias sd='ruby script/server --debugger'
 alias devlog='tail -f log/development.log'
+alias testlog='tail -f log/test.log'
+alias prodlog='tail -f log/production.log'
+alias -g RET='RAILS_ENV=test'
+alias -g REP='RAILS_ENV=production'
+alias -g RED='RAILS_ENV=development'
 
 function remote_console() {
   /usr/bin/env ssh $1 "( cd $2 && ruby script/console production )"
diff --git a/plugins/rails3/_rails3 b/plugins/rails3/_rails3
new file mode 100644
index 000000000..97915e68b
--- /dev/null
+++ b/plugins/rails3/_rails3
@@ -0,0 +1,56 @@
+#compdef rails
+#autoload
+
+# rails 3 zsh completion, based on homebrew completion
+# Extracted from https://github.com/robbyrussell/oh-my-zsh/blob/30620d463850c17f86e7a56fbf6a8b5e793a4e07/plugins/rails3/_rails3
+# Published by Christopher Chow
+
+local -a _1st_arguments
+_1st_arguments=(
+    'generate:Generate new code (short-cut alias: "g")'
+    'console:Start the Rails console (short-cut alias: "c")'
+    'server:Start the Rails server (short-cut alias: "s")'
+    'dbconsole:Start a console for the database specified in config/database.yml (short-cut alias: "db")'
+    'new:Create a new Rails application. "rails new my_app" creates a new application called MyApp in "./my_app"'
+    'application:Generate the Rails application code'
+    'destroy:Undo code generated with "generate"'
+    'benchmarker:See how fast a piece of code runs'
+    'profiler:Get profile information from a piece of code'
+    'plugin:Install a plugin'
+)
+
+_rails_generate_arguments() {
+    generate_arguments=(
+        controller
+        generator
+        helper
+        integration_test
+        mailer
+        migration
+        model
+        observer
+        performance_test
+        plugin
+        resource
+        scaffold
+        scaffold_controller
+        session_migration
+        stylesheets
+    )
+}
+
+_arguments \
+    '(--version)--version[show version]' \
+    '(--help)--help[show help]' \
+    '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "rails subcommand" _1st_arguments
+  return
+fi
+
+case "$words[1]" in
+  generate)
+    _rails_generate_arguments
+    _wanted generate_arguments expl 'all generate' compadd -a generate_arguments ;;
+esac
diff --git a/plugins/rails3/rails3.plugin.zsh b/plugins/rails3/rails3.plugin.zsh
index 237d0594b..2555fab67 100644
--- a/plugins/rails3/rails3.plugin.zsh
+++ b/plugins/rails3/rails3.plugin.zsh
@@ -19,5 +19,10 @@ alias ru='_rails_command runner'
 alias rs='_rails_command server'
 alias rsd='_rails_command server --debugger'
 alias devlog='tail -f log/development.log'
+alias testlog='tail -f log/test.log'
+alias prodlog='tail -f log/production.log'
 alias rdm='rake db:migrate'
 alias rdr='rake db:rollback'
+alias -g RET='RAILS_ENV=test'
+alias -g REP='RAILS_ENV=production'
+alias -g RED='RAILS_ENV=development'
diff --git a/plugins/rails4/rails4.plugin.zsh b/plugins/rails4/rails4.plugin.zsh
new file mode 100644
index 000000000..cb6cf816d
--- /dev/null
+++ b/plugins/rails4/rails4.plugin.zsh
@@ -0,0 +1,32 @@
+# Rails 4 aliases
+
+function _rails_command () {
+  if [ -e "script/server" ]; then
+    ruby script/$@
+  elif [ -e "script/rails" ]; then
+    ruby script/rails $@
+  else
+    ruby bin/rails $@  
+  fi
+}
+
+alias rc='_rails_command console'
+alias rd='_rails_command destroy'
+alias rdb='_rails_command dbconsole'
+alias rdbm='rake db:migrate db:test:clone'
+alias rg='_rails_command generate'
+alias rgm='_rails_command generate migration'
+alias rp='_rails_command plugin'
+alias ru='_rails_command runner'
+alias rs='_rails_command server'
+alias rsd='_rails_command server --debugger'
+alias devlog='tail -f log/development.log'
+alias testlog='tail -f log/test.log'
+alias prodlog='tail -f log/production.log'
+alias rdm='rake db:migrate'
+alias rdc='rake db:create'
+alias rdr='rake db:rollback'
+alias rds='rake db:seed'
+alias rlc='rake log:clear'
+alias rn='rake notes'
+alias rr='rake routes'
diff --git a/plugins/rand-quote/rand-quote.plugin.zsh b/plugins/rand-quote/rand-quote.plugin.zsh
new file mode 100644
index 000000000..5544ca565
--- /dev/null
+++ b/plugins/rand-quote/rand-quote.plugin.zsh
@@ -0,0 +1,17 @@
+# Get a random quote fron the site http://www.quotationspage.com/random.php3
+# Created by Eduardo San Martin Morote aka Posva
+# http://posva.github.io
+# Sun Jun 09 10:59:36 CEST 2013 
+# Don't remove this header, thank you
+# Usage: quote
+
+if [[ -x `which curl` ]]; then
+    function quote()
+    {
+        Q=$(curl -s --connect-timeout 2 "http://www.quotationspage.com/random.php3" | grep -m 1 "dt ")
+        TXT=$(echo "$Q" | sed -e 's/<\/dt>.*//g' -e 's/.*html//g' -e 's/^[^a-zA-Z]*//' -e 's/<\/a..*$//g')
+        W=$(echo "$Q" | sed -e 's/.*\/quotes\///g' -e 's/<.*//g' -e 's/.*">//g')
+        echo "\e[0;33m${W}\e[0;30m: \e[0;35m“${TXT}”\e[m"
+    }
+    #quote
+fi
diff --git a/plugins/repo/README.md b/plugins/repo/README.md
new file mode 100644
index 000000000..0b77e6d48
--- /dev/null
+++ b/plugins/repo/README.md
@@ -0,0 +1,7 @@
+## repo
+**Maintainer:** [Stibbons](https://github.com/Stibbons)
+
+This plugin mainly add support automatic completion for the repo command line tool:
+http://code.google.com/p/git-repo/
+
+* `r` aliases `repo`
diff --git a/plugins/repo/_repo b/plugins/repo/_repo
new file mode 100644
index 000000000..59e39c954
--- /dev/null
+++ b/plugins/repo/_repo
@@ -0,0 +1,272 @@
+#compdef repo
+
+
+__git_apply_whitespace_strategies ()
+{
+  declare -a strategies
+
+  strategies=(
+    'nowarn:turn off the trailing-whitespace warning'
+    'warn:output trailing-whitespace warning, but apply patch'
+    'fix:output trailing-whitespace warning and strip trailing whitespace'
+    'error:output trailing-whitespace warning and refuse to apply patch'
+    'error-all:same as "error", but output warnings for all files')
+
+  _describe -t strategies 'trailing-whitespace resolution strategy' strategies $*
+}
+
+
+_repo()
+{
+  local context state state_descr line curcontext="$curcontext"
+  typeset -A opt_args
+
+  local ret=1
+
+  _arguments -C \
+    '(- 1 *)--help[show usage]'\
+    '1:command:->command'\
+    '*::args:->args' && ret=0
+
+  case $state in
+    (command)
+      repo list  2> /dev/null > /dev/null
+      if [[ $? == 0 ]]; then
+        local commands;
+        commands=(
+          'abandon:Permanently abandon a development branch'
+          'branch:View current topic branches'
+          'branches:View current topic branches'
+          'checkout:Checkout a branch for development'
+          'cherry-pick:Cherry-pick a change.'
+          'diff:Show changes between commit and working tree'
+          'download:Download and checkout a change'
+          'forall:execute command on several project'
+          'grep:Print lines matching a pattern'
+          'help:Display detailed help on a command'
+          'init:Initialize repo in the current directory'
+          'list:List projects and their associated directories'
+          'manifest:Manifest inspection utility'
+          'overview:Display overview of unmerged project branches'
+          'prune:Prune (delete) already merged topics'
+          'rebase:Rebase local branches on upstream branch'
+          'selfupdate:Update repo to the latest version'
+          'smartsync:Update working tree to the latest known good revision'
+          'stage:Stage file(s) for commit'
+          'start:Start a new branch for development'
+          'status:Show the working tree status'
+          'sync:Update working tree to the latest revision'
+          'upload:Upload changes for code review'
+          'version:Display the version of repo'
+        )
+        _describe -t commands 'command' commands && ret=0
+      else
+        local commands;
+        commands=(
+          'init:Install repo in the current working directory'
+          'help:Display detailed help on a command'
+        )
+        _describe -t commands 'command' commands && ret=0
+      fi
+      ;;
+    (args)
+      case $words[1] in
+        (branch | branches)
+          # TODO : list available projects and add them in list to feed compadd with
+          _arguments  : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     ': :__repo_projects' \
+                      && ret=0
+         ;;
+        (abandon)
+          # TODO : list available projects and add them in list to feed compadd with
+          _arguments  : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     ':branch name:__repo_branch' \
+                     ': :__repo_projects'\
+                      && ret=0
+          ;;
+        (checkout)
+          # TODO : list available projects and add them in list to feed compadd with
+          _arguments  : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     ':branch name:__repo_branch' \
+                     ': :__repo_projects'\
+                     && ret=0
+          ;;
+        (init)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-q --quiet)"{-q,--quiet}"[be quiet]" \
+                     "(-u --manifest-url)"{-u,--manifest-url=}"[manifest repository location]":url:__repo_url_prompt \
+                     "(-b --manifest-branch)"{-b,--manifest-branch=}"[manifest branch or revision]":branch:__repo_branch\
+                     "(-m --manifest-name)"{-m,--manifest-name=}"[initial manifest file]":manifest_name:__repo_manifest_name\
+                     "(--mirror)--mirror[mirror the forrest]"\
+                     "(--reference)--reference=[location of mirror directory]":dir:_dirs\
+                     "(--depth)--depth=[create a shallow clone with given depth; see git clone]":depth:__repo_depth_prompt\
+                     "(-g --group=)"{-g,--group=}"[restrict manifest projects to ones with a specified group]":group:_group\
+                     "(-p --platform=)"{-p,--platform=}"[restrict manifest projects to ones with a specified platform group(auto|all|none|linux|darwin|...)]":platform:"(auto all none linux darwin)"\
+                     "(--repo-url)--repo-url=[repo repository location]":url:__repo_url_prompt\
+                     "(--repo-branch)--repo-branch[repo branch or revision]":branch_or_rev:__repo__repo_branch_or_rev\
+                     "(--no-repo-verify)--no-repo-verify[do not verify repo source code]"\
+                     "(--config-name)--config-name[Always prompt for name/e-mail]"\
+                     && ret=0
+          ;;
+        (start)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(--all)--all=[begin branch in all projects]"\
+                    ':branch name:__repo_new__repo_branch_name' \
+                    ':projects:__repo_projects_or_all' \
+                    && ret=0
+          ;;
+        (rebase)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-i --interactive)"{-i,--interactive}"[interactive rebase (single project only)]: :__repo_projects" \
+                     "(-f --force-rebase)"{-f,--force-rebase}"[Pass --force-rebase to git rebase]" \
+                     "(--no-ff)--no-ff=[Pass --no-ff to git rebase]"\
+                     "(-q --quiet)"{-q,--quiet}"[Pass --quiet to git rebase]" \
+                     "(--autosquash)--no-ff[Pass --autosquash to git rebase]"\
+                     "(--whitespace=)--whitespace=[Pass --whitespace to git rebase]: :__git_apply_whitespace_strategies"\
+                     "(--auto-stash)--auto-stash[Stash local modifications before starting]"\
+                     && ret=0
+          ;;
+        (checkout)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                    ':branch name:__git_branch_names' \
+                    ':projects:__repo_projects' \
+                    && ret=0
+          ;;
+        (list)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                    && ret=0
+          ;;
+        (status)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-j --jobs)"{-j,--jobs}"[number of projects to check simultaneously]" \
+                    ':projects:__repo_projects' \
+                    && ret=0
+          ;;
+        (sync)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(--no-force-broken)--no-force-broken[stop sync if a project fails to sync (probably because of permissions)]" \
+                     "(-l --local-only)"{-l,--local-only}"[only update working tree, don't fetch]" \
+                     "(-n --network-only)"{-n,--network-branch}"[fetch only, don't update working tree]" \
+                     "(-d --detach)"{-d,--detach}"[detach projects back to manifest revision]" \
+                     "(-c --current-branch)"{-c,--current-branch}"[fetch only current branch from server]" \
+                     "(-q --quiet)"{-q,--quiet}"[be more quiet]" \
+                     "(-j --jobs=)"{-j,--jobs=}"[projects to fetch simultaneously (default 1) (limited to 5)]:projects to fetch simultaneously (default 1) (limited to 5)" \
+                     "(-m --manifest-name=)"{-m,--manifest-name=}"[temporary manifest to use for this sync]:manifest xml file:_files -g *.xml" \
+                     "(--no-clone-bundle)--no-clone-bundle[disable use of /clone.bundle on HTTP/HTTPS]" \
+                     "(-s --smart-sync)"{-s,--smart-sync=}"[smart sync using manifest from a known tag]:tag:" \
+                     '(--no-repo-verify)--no-repo-verify[do not verify repo source code]' \
+                     ': :__repo_projects' \
+                     && ret=0
+          ;;
+        (upload)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-t)-t[Send local branch name to Gerrit Code Review]" \
+                     "(--re= --reviewers=)"{--re=,--reviewers=}"[Request reviews from these people]:Request reviews from these people:" \
+                     "(--cc=)--cc=[Also send email to these email addresses.]:email addresses:_email_addresses" \
+                     "(--br=)--br=[Branch to upload.]:branch:__repo_branch" \
+                     "(--cbr --current-branch)"{--cbr,--current-branch}"[Upload current git branch]" \
+                     "(-d --draft)"{-d,--draft}"[If specified, upload as a draft.]" \
+                     "(--verify --no-verify)--no-verify[Do not run the upload hook.]" \
+                     '(--verify --no-verify)--verify[Run the upload hook without prompting]' \
+                     ': :__repo_projects' \
+                     && ret=0
+          ;;
+        (forall)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-v --verbose)"{-v,--verbose}"[Show command error messages]" \
+                     '(-p)-p[Show project headers before output]' \
+                     ': :__repo_projects_mandatory' \
+                     "(-c --command -h --help -v --verbose -p)"{-c,--command}"[Command (and arguments) to execute]" \
+                     && ret=0
+          ;;
+        *)
+          ret=0
+      esac
+      ;;
+  esac
+
+  return $ret
+}
+
+__repo_reviewers()
+{
+ # _message -e url 'reviewers'
+}
+
+__repo_url_prompt()
+{
+  _message -e url 'url'
+}
+
+__repo_manifest_name()
+{
+  _message -e manifest_name 'manifest name'
+}
+
+_group()
+{
+  _message -e group 'group'
+}
+
+__repo_branch()
+{
+  #_message -e branch 'Repo branch'
+  branches=($(repo branches| cut -c4- | grep '|' | cut -d' ' -f1))
+  _describe -t branches 'Select repo branch' branches
+}
+
+__repo__repo_branch_or_rev()
+{
+  _message -e branch_or_rev 'repo branch or revision'
+}
+
+__repo_depth_prompt()
+{
+  _message -e depth 'depth'
+}
+
+__repo_projects()
+{
+  _message -e depth 'Optional option : ...'
+  projects=($(repo list | cut -d' ' -f1))
+  _describe -t projects 'Select projects (keep empty for selecting all projects)' projects
+}
+
+__repo_projects_mandatory()
+{
+  projects=($(repo list | cut -d' ' -f1))
+  #_describe -t projects 'Select projects to apply commands' projects
+  _values -s ' ' "Select projects to apply commands" $projects
+}
+
+__repo_new__repo_branch_name()
+{
+  branches=($(repo branches| cut -c4- | grep '|' | cut -d' ' -f1))
+  _describe "" branches
+  _message -e "branch name" 'Enter new branch name or select an existing repo branch'
+}
+
+__repo_projects_or_all()
+{
+  #_message -e depth '[--all | ...]'
+
+  projects=(--all $(repo list | cut -d' ' -f1))
+  _describe -t projects 'Select projects or --all' projects
+  _describe -t --all 'All projects'
+}
+
+_repo "$@"
+return $?
+
diff --git a/plugins/repo/repo.plugin.zsh b/plugins/repo/repo.plugin.zsh
new file mode 100644
index 000000000..9cc336959
--- /dev/null
+++ b/plugins/repo/repo.plugin.zsh
@@ -0,0 +1,2 @@
+# Aliases
+alias r='repo'
diff --git a/plugins/rvm/rvm.plugin.zsh b/plugins/rvm/rvm.plugin.zsh
index 5000a49b3..e6ad6450d 100644
--- a/plugins/rvm/rvm.plugin.zsh
+++ b/plugins/rvm/rvm.plugin.zsh
@@ -3,9 +3,9 @@ fpath=($rvm_path/scripts/zsh/Completion $fpath)
 alias rubies='rvm list rubies'
 alias gemsets='rvm gemset list'
 
-local ruby18='ruby-1.8.7-p334'
-local ruby19='ruby-1.9.3-p385'
-local ruby20='ruby-2.0.0-rc2'
+local ruby18='ruby-1.8.7'
+local ruby19='ruby-1.9.3'
+local ruby20='ruby-2.0.0'
 
 function rb18 {
 	if [ -z "$1" ]; then
@@ -42,7 +42,6 @@ compdef _rb20 rb20
 
 function rvm-update {
 	rvm get head
-	rvm reload # TODO: Reload rvm completion?
 }
 
 # TODO: Make this usable w/o rvm.
diff --git a/plugins/safe-paste/safe-paste.plugin.zsh b/plugins/safe-paste/safe-paste.plugin.zsh
index 0aa97965f..17c212c19 100644
--- a/plugins/safe-paste/safe-paste.plugin.zsh
+++ b/plugins/safe-paste/safe-paste.plugin.zsh
@@ -43,12 +43,12 @@ function _paste_insert() {
 
 function _zle_line_init() {
   # Tell terminal to send escape codes around pastes.
-  [[ $TERM == rxvt-unicode || $TERM == xterm || $TERM = xterm-256color ]] && printf '\e[?2004h'
+  [[ $TERM == rxvt-unicode || $TERM == xterm || $TERM = xterm-256color || $TERM = screen || $TERM = screen-256color ]] && printf '\e[?2004h'
 }
 
 function _zle_line_finish() {
   # Tell it to stop when we leave zle, so pasting in other programs
   # doesn't get the ^[[200~ codes around the pasted text.
-  [[ $TERM == rxvt-unicode || $TERM == xterm || $TERM = xterm-256color ]] && printf '\e[?2004l'
+  [[ $TERM == rxvt-unicode || $TERM == xterm || $TERM = xterm-256color || $TERM = screen || $TERM = screen-256color ]] && printf '\e[?2004l'
 }
 
diff --git a/plugins/ssh-agent/ssh-agent.plugin.zsh b/plugins/ssh-agent/ssh-agent.plugin.zsh
index 7468749f8..3b0042a7d 100644
--- a/plugins/ssh-agent/ssh-agent.plugin.zsh
+++ b/plugins/ssh-agent/ssh-agent.plugin.zsh
@@ -9,7 +9,7 @@
 #   To load multiple identities use the identities style, For
 #   example:
 #
-#     zstyle :omz:plugins:ssh-agent id_rsa id_rsa2 id_github
+#     zstyle :omz:plugins:ssh-agent identities id_rsa id_rsa2 id_github
 #
 #   To set the maximum lifetime of the identities, use the
 #   lifetime style. The lifetime may be specified in seconds
diff --git a/plugins/sublime/sublime.plugin.zsh b/plugins/sublime/sublime.plugin.zsh
index 7a5ada337..82faf87c9 100755
--- a/plugins/sublime/sublime.plugin.zsh
+++ b/plugins/sublime/sublime.plugin.zsh
@@ -2,10 +2,11 @@
 
 local _sublime_darwin_paths > /dev/null 2>&1
 _sublime_darwin_paths=(
-	"$HOME/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"
+	"/usr/local/bin/subl"
 	"$HOME/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl"
-	"/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"
+	"$HOME/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"
 	"/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl"
+	"/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"
 )
 
 if [[ $('uname') == 'Linux' ]]; then
@@ -21,6 +22,7 @@ elif  [[ $('uname') == 'Darwin' ]]; then
 	for _sublime_path in $_sublime_darwin_paths; do
 		if [[ -a $_sublime_path ]]; then
 			alias st="'$_sublime_path'"
+			break
 		fi
 	done
 fi
diff --git a/plugins/svn/svn.plugin.zsh b/plugins/svn/svn.plugin.zsh
index e38e8920b..4f008ba4e 100644
--- a/plugins/svn/svn.plugin.zsh
+++ b/plugins/svn/svn.plugin.zsh
@@ -1,62 +1,76 @@
-
-function svn_prompt_info {
-    if [ $(in_svn) ]; then
-        if [ "x$SVN_SHOW_BRANCH" = "xtrue" ]; then
-            unset SVN_SHOW_BRANCH
-            _DISPLAY=$(svn_get_branch_name)
-        else
-            _DISPLAY=$(svn_get_repo_name)
-        fi
-        echo "$ZSH_PROMPT_BASE_COLOR$ZSH_THEME_SVN_PROMPT_PREFIX\
-$ZSH_THEME_REPO_NAME_COLOR$_DISPLAY$ZSH_PROMPT_BASE_COLOR$ZSH_THEME_SVN_PROMPT_SUFFIX$ZSH_PROMPT_BASE_COLOR$(svn_dirty)$ZSH_PROMPT_BASE_COLOR"
-        unset _DISPLAY
+# vim:ft=zsh ts=2 sw=2 sts=2
+#
+function svn_prompt_info() {
+  if in_svn; then
+    if [ "x$SVN_SHOW_BRANCH" = "xtrue" ]; then
+      unset SVN_SHOW_BRANCH
+      _DISPLAY=$(svn_get_branch_name)
+    else
+      _DISPLAY=$(svn_get_repo_name)
     fi
+    echo "$ZSH_PROMPT_BASE_COLOR$ZSH_THEME_SVN_PROMPT_PREFIX\
+$ZSH_THEME_REPO_NAME_COLOR$_DISPLAY$ZSH_PROMPT_BASE_COLOR$ZSH_THEME_SVN_PROMPT_SUFFIX$ZSH_PROMPT_BASE_COLOR$(svn_dirty)$ZSH_PROMPT_BASE_COLOR"
+    unset _DISPLAY
+  fi
 }
 
 
 function in_svn() {
-    if [[ -d .svn ]]; then
-        echo 1
-    fi
+  if $(svn info >/dev/null 2>&1); then
+    return 0
+  fi
+  return 1
 }
 
-function svn_get_repo_name {
-    if [ $(in_svn) ]; then
-        svn info | sed -n 's/Repository\ Root:\ .*\///p' | read SVN_ROOT
-
-        svn info | sed -n "s/URL:\ .*$SVN_ROOT\///p"
-    fi
+function svn_get_repo_name() {
+  if in_svn; then
+    svn info | sed -n 's/Repository\ Root:\ .*\///p' | read SVN_ROOT
+    svn info | sed -n "s/URL:\ .*$SVN_ROOT\///p"
+  fi
 }
 
-function svn_get_branch_name {
-    _DISPLAY=$(svn info 2> /dev/null | awk -F/ '/^URL:/ { for (i=0; i<=NF; i++) { if ($i == "branches" || $i == "tags" ) { print $(i+1); break }; if ($i == "trunk") { print $i; break } } }')
-    if [ "x$_DISPLAY" = "x" ]; then
-        svn_get_repo_name
+function svn_get_branch_name() {
+  _DISPLAY=$(
+    svn info 2> /dev/null | \
+      awk -F/ \
+      '/^URL:/ { \
+        for (i=0; i<=NF; i++) { \
+          if ($i == "branches" || $i == "tags" ) { \
+            print $(i+1); \
+            break;\
+          }; \
+          if ($i == "trunk") { print $i; break; } \
+        } \
+      }'
+  )
+  
+  if [ "x$_DISPLAY" = "x" ]; then
+    svn_get_repo_name
+  else
+    echo $_DISPLAY
+  fi
+  unset _DISPLAY
+}
+
+function svn_get_rev_nr() {
+  if in_svn; then
+    svn info 2> /dev/null | sed -n 's/Revision:\ //p'
+  fi
+}
+
+function svn_dirty_choose() {
+  if in_svn; then
+    root=`svn info 2> /dev/null | sed -n 's/^Working Copy Root Path: //p'`
+    if $(svn status $root 2> /dev/null | grep -Eq '^\s*[ACDIM!?L]'); then
+      # Grep exits with 0 when "One or more lines were selected", return "dirty".
+      echo $1
     else
-        echo $_DISPLAY
+      # Otherwise, no lines were found, or an error occurred. Return clean.
+      echo $2
     fi
-    unset _DISPLAY
+  fi
 }
 
-function svn_get_rev_nr {
-    if [ $(in_svn) ]; then
-        svn info 2> /dev/null | sed -n s/Revision:\ //p
-    fi
-}
-
-function svn_dirty_choose {
-    if [ $(in_svn) ]; then
-        svn status 2> /dev/null | grep -Eq '^\s*[ACDIM!?L]'
-        if [ $pipestatus[-1] -eq 0 ]; then
-            # Grep exits with 0 when "One or more lines were selected", return "dirty".
-            echo $1
-        else
-            # Otherwise, no lines were found, or an error occurred. Return clean.
-            echo $2
-        fi
-    fi
-}
-
-function svn_dirty {
-    svn_dirty_choose $ZSH_THEME_SVN_PROMPT_DIRTY $ZSH_THEME_SVN_PROMPT_CLEAN
+function svn_dirty() {
+  svn_dirty_choose $ZSH_THEME_SVN_PROMPT_DIRTY $ZSH_THEME_SVN_PROMPT_CLEAN
 }
diff --git a/plugins/symfony/symfony.plugin.zsh b/plugins/symfony/symfony.plugin.zsh
index 9de767548..f070e9e47 100644
--- a/plugins/symfony/symfony.plugin.zsh
+++ b/plugins/symfony/symfony.plugin.zsh
@@ -1,7 +1,7 @@
 # symfony basic command completion
 
 _symfony_get_command_list () {
-    ./symfony | sed "1,/Available tasks/d" | awk 'BEGIN { cat=null; } /^[A-Za-z]+$/ { cat = $1; } /^  :[a-z]+/ { print cat $1; }'
+    php symfony | sed "1,/Available tasks/d" | awk 'BEGIN { cat=null; } /^[A-Za-z]+$/ { cat = $1; } /^  :[a-z]+/ { print cat $1; }'
 }
 
 _symfony () {
diff --git a/plugins/symfony2/symfony2.plugin.zsh b/plugins/symfony2/symfony2.plugin.zsh
index 45d6165aa..0d2bb68c3 100644
--- a/plugins/symfony2/symfony2.plugin.zsh
+++ b/plugins/symfony2/symfony2.plugin.zsh
@@ -1,7 +1,7 @@
 # Symfony2 basic command completion
 
 _symfony2_get_command_list () {
-	app/console --no-ansi | sed "1,/Available commands/d" | awk '/^  [a-z]+/ { print $1 }'
+	php app/console --no-ansi | sed "1,/Available commands/d" | awk '/^  [a-z]+/ { print $1 }'
 }
 
 _symfony2 () {
diff --git a/plugins/textmate/textmate.plugin.zsh b/plugins/textmate/textmate.plugin.zsh
index a11a097f5..773c4f8d2 100644
--- a/plugins/textmate/textmate.plugin.zsh
+++ b/plugins/textmate/textmate.plugin.zsh
@@ -6,7 +6,16 @@ alias etts='mate app config lib db public script spec test vendor/plugins vendor
 # Edit Ruby app in TextMate
 alias mr='mate CHANGELOG app config db lib public script spec test'
 
+# If the tm command is called without an argument, open TextMate in the current directory
+# If tm is passed a directory, cd to it and open it in TextMate
+# If tm is passed a file, open it in TextMate
 function tm() {
-  cd $1
-  mate $1
+	if [[ -z $1 ]]; then
+		mate .
+	else
+		mate $1
+		if [[ -d $1 ]]; then
+			cd $1
+		fi
+	fi
 }
diff --git a/plugins/tmux/tmux.plugin.zsh b/plugins/tmux/tmux.plugin.zsh
index 465f5b053..3ecc2ac69 100644
--- a/plugins/tmux/tmux.plugin.zsh
+++ b/plugins/tmux/tmux.plugin.zsh
@@ -14,6 +14,8 @@ if which tmux &> /dev/null
 	[[ -n "$ZSH_TMUX_AUTOQUIT" ]] || ZSH_TMUX_AUTOQUIT=$ZSH_TMUX_AUTOSTART
 	# Set term to screen or screen-256color based on current terminal support
 	[[ -n "$ZSH_TMUX_FIXTERM" ]] || ZSH_TMUX_FIXTERM=true
+	# Set '-CC' option for iTerm2 tmux integration
+	[[ -n "$ZSH_TMUX_ITERM2" ]] || ZSH_TMUX_ITERM2=false
 	# The TERM to use for non-256 color terminals.
 	# Tmux states this should be screen, but you may need to change it on
 	# systems without the proper terminfo
@@ -36,7 +38,7 @@ if which tmux &> /dev/null
 	fi
 
 	# Set the correct local config file to use.
-	if [[ -f $HOME/.tmux.conf || -h $HOME/.tmux.conf ]]
+    if [[ "$ZSH_TMUX_ITERM2" == "false" ]] && (( [[ -f $HOME/.tmux.conf ]] || -h $HOME/.tmux.conf ]] ))
 	then
 		#use this when they have a ~/.tmux.conf
 		export _ZSH_TMUX_FIXED_CONFIG="$zsh_tmux_plugin_path/tmux.extra.conf"
@@ -55,11 +57,11 @@ if which tmux &> /dev/null
 		# Try to connect to an existing session.
 		elif [[ "$ZSH_TMUX_AUTOCONNECT" == "true" ]]
 		then
-			\tmux attach || \tmux `[[ "$ZSH_TMUX_FIXTERM" == "true" ]] && echo '-f '$_ZSH_TMUX_FIXED_CONFIG`  new-session
+			\tmux `[[ "$ZSH_TMUX_ITERM2" == "true" ]] && echo '-CC '` attach || \tmux `[[ "$ZSH_TMUX_ITERM2" == "true" ]] && echo '-CC '` `[[ "$ZSH_TMUX_FIXTERM" == "true" ]] && echo '-f '$_ZSH_TMUX_FIXED_CONFIG` new-session
 			[[ "$ZSH_TMUX_AUTOQUIT" == "true" ]] && exit
 		# Just run tmux, fixing the TERM variable if requested.
 		else
-			\tmux `[[ "$ZSH_TMUX_FIXTERM" == "true" ]] && echo '-f '$_ZSH_TMUX_FIXED_CONFIG`
+			\tmux `[[ "$ZSH_TMUX_ITERM2" == "true" ]] && echo '-CC '` `[[ "$ZSH_TMUX_FIXTERM" == "true" ]] && echo '-f '$_ZSH_TMUX_FIXED_CONFIG`
 			[[ "$ZSH_TMUX_AUTOQUIT" == "true" ]] && exit
 		fi
 	}
diff --git a/plugins/virtualenv/virtualenv.plugin.zsh b/plugins/virtualenv/virtualenv.plugin.zsh
new file mode 100644
index 000000000..8e06450b1
--- /dev/null
+++ b/plugins/virtualenv/virtualenv.plugin.zsh
@@ -0,0 +1,8 @@
+function virtualenv_prompt_info(){
+  if [[ -n $VIRTUAL_ENV ]]; then
+    printf "%s[%s] " "%{${fg[yellow]}%}" ${${VIRTUAL_ENV}:t}
+  fi
+}
+
+# disables prompt mangling in virtual_env/bin/activate
+export VIRTUAL_ENV_DISABLE_PROMPT=1
diff --git a/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh b/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh
index 0ed2565b4..670c287bd 100644
--- a/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh
+++ b/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh
@@ -1,40 +1,55 @@
-wrapsource=`which virtualenvwrapper_lazy.sh`
-
-if [[ -f "$wrapsource" ]]; then
-  source $wrapsource
+virtualenvwrapper='virtualenvwrapper_lazy.sh'
+if (( $+commands[$virtualenvwrapper] )); then
+  source ${${virtualenvwrapper}:c}
 
   if [[ ! $DISABLE_VENV_CD -eq 1 ]]; then
-    # Automatically activate Git projects' virtual environments based on the
+    # Automatically activate Git projects's virtual environments based on the
     # directory name of the project. Virtual environment name can be overridden
     # by placing a .venv file in the project root with a virtualenv name in it
     function workon_cwd {
-        # Check that this is a Git repo
-        PROJECT_ROOT=`git rev-parse --show-toplevel 2> /dev/null`
-        if (( $? == 0 )); then
+        if [ ! $WORKON_CWD ]; then
+            WORKON_CWD=1
+            # Check if this is a Git repo
+            PROJECT_ROOT=`git rev-parse --show-toplevel 2> /dev/null`
+            if (( $? != 0 )); then
+                PROJECT_ROOT="."
+            fi
             # Check for virtualenv name override
-            ENV_NAME=`basename "$PROJECT_ROOT"`
             if [[ -f "$PROJECT_ROOT/.venv" ]]; then
                 ENV_NAME=`cat "$PROJECT_ROOT/.venv"`
+            elif [[ "$PROJECT_ROOT" != "." ]]; then
+                ENV_NAME=`basename "$PROJECT_ROOT"`
+            else
+                ENV_NAME=""
             fi
-            # Activate the environment only if it is not already active
-            if [[ "$VIRTUAL_ENV" != "$WORKON_HOME/$ENV_NAME" ]]; then
-                if [[ -e "$WORKON_HOME/$ENV_NAME/bin/activate" ]]; then
-                    workon "$ENV_NAME" && export CD_VIRTUAL_ENV="$ENV_NAME"
+            if [[ "$ENV_NAME" != "" ]]; then
+                # Activate the environment only if it is not already active
+                if [[ "$VIRTUAL_ENV" != "$WORKON_HOME/$ENV_NAME" ]]; then
+                    if [[ -e "$WORKON_HOME/$ENV_NAME/bin/activate" ]]; then
+                        workon "$ENV_NAME" && export CD_VIRTUAL_ENV="$ENV_NAME"
+                    fi
                 fi
+            elif [ $CD_VIRTUAL_ENV ]; then
+                # We've just left the repo, deactivate the environment
+                # Note: this only happens if the virtualenv was activated automatically
+                deactivate && unset CD_VIRTUAL_ENV
             fi
-        elif [ $CD_VIRTUAL_ENV ]; then
-            # We've just left the repo, deactivate the environment
-            # Note: this only happens if the virtualenv was activated automatically
-            deactivate && unset CD_VIRTUAL_ENV
+            unset PROJECT_ROOT
+            unset WORKON_CWD
         fi
-        unset PROJECT_ROOT
     }
 
-    # New cd function that does the virtualenv magic
-    function cd {
-        builtin cd "$@" && workon_cwd
-    }
+    # Append workon_cwd to the chpwd_functions array, so it will be called on cd
+    # http://zsh.sourceforge.net/Doc/Release/Functions.html
+    # TODO: replace with 'add-zsh-hook chpwd workon_cwd' when oh-my-zsh min version is raised above 4.3.4
+    if (( ${+chpwd_functions} )); then
+        if (( $chpwd_functions[(I)workon_cwd] == 0 )); then
+            set -A chpwd_functions $chpwd_functions workon_cwd
+        fi
+    else
+        set -A chpwd_functions workon_cwd
+    fi
   fi
 else
-  print "zsh virtualenvwrapper plugin: Cannot find virtualenvwrapper_lazy.sh. Please install with \`pip install virtualenvwrapper\`."
+  print "zsh virtualenvwrapper plugin: Cannot find ${virtualenvwrapper}. Please install with \`pip install virtualenvwrapper\`."
 fi
diff --git a/plugins/web-search/web-search.plugin.zsh b/plugins/web-search/web-search.plugin.zsh
new file mode 100644
index 000000000..6b6de2b15
--- /dev/null
+++ b/plugins/web-search/web-search.plugin.zsh
@@ -0,0 +1,43 @@
+# web_search from terminal
+
+function web_search() {
+
+  # get the open command
+  local open_cmd
+  if [[ $(uname -s) == 'Darwin' ]]; then
+    open_cmd='open'
+  else
+    open_cmd='xdg-open'
+  fi
+
+  # check whether the search engine is supported
+  if [[ ! $1 =~ '(google|bing|yahoo)' ]];
+  then
+    echo "Search engine $1 not supported."
+    return 1
+  fi
+
+  local url="http://www.$1.com"
+
+  # no keyword provided, simply open the search engine homepage
+  if [[ $# -le 1 ]]; then
+    $open_cmd "$url"
+    return
+  fi
+
+  url="${url}/search?q="
+  shift   # shift out $1
+
+  while [[ $# -gt 0 ]]; do
+    url="${url}$1+"
+    shift
+  done
+
+  url="${url%?}" # remove the last '+'
+
+  $open_cmd "$url"
+}
+
+alias bing='web_search bing'
+alias google='web_search google'
+alias yahoo='web_search yahoo'
diff --git a/plugins/zeus/_zeus b/plugins/zeus/_zeus
new file mode 100644
index 000000000..5a13bd9ec
--- /dev/null
+++ b/plugins/zeus/_zeus
@@ -0,0 +1,34 @@
+#compdef zeus
+#autoload
+
+# in order to make this work, you will need to have the gem zeus installed
+
+# zeus zsh completion, based on adb completion
+
+local -a _1st_arguments
+_1st_arguments=(
+'console:Lets you interact with your Rails application from the command line. (alias = c)'
+'cucumber:Runs cucumber.'
+'dbconsole:Figures out which database you are using and drops you into whichever command line interface.'
+'destroy:Figures out what generate did, and undoes it. (alias = d)'
+'generate:Uses templates to create a whole lot of things. (alias = g)'
+'rake:Execute rake tasks.'
+'runner:Runs Ruby code in the context of Rails non-interactively. (alias = r)'
+'server:Launches a small web server named WEBrick which comes bundled with Ruby. (alias = s)'
+'start:Preloads the zeus environment'
+'test:Runs RSpec tests. (alias = rspec, testrb)'
+'version:Shows the version number.'
+)
+
+local expl
+local -a pkgs installed_pkgs
+
+_arguments \
+	'*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+	_describe -t commands "zeus subcommand" _1st_arguments
+	return
+fi
+
+_files
diff --git a/templates/zshrc.zsh-template b/templates/zshrc.zsh-template
index 2ea9934af..d4dded73a 100644
--- a/templates/zshrc.zsh-template
+++ b/templates/zshrc.zsh-template
@@ -17,7 +17,7 @@ ZSH_THEME="robbyrussell"
 # Comment this out to disable bi-weekly auto-update checks
 # DISABLE_AUTO_UPDATE="true"
 
-# Uncomment to change how many often would you like to wait before auto-updates occur? (in days)
+# Uncomment to change how often before auto-updates occur? (in days)
 # export UPDATE_ZSH_DAYS=13
 
 # Uncomment following line if you want to disable colors in ls
@@ -26,9 +26,17 @@ ZSH_THEME="robbyrussell"
 # Uncomment following line if you want to disable autosetting terminal title.
 # DISABLE_AUTO_TITLE="true"
 
+# Uncomment following line if you want to disable command autocorrection
+# DISABLE_CORRECTION="true"
+
 # Uncomment following line if you want red dots to be displayed while waiting for completion
 # COMPLETION_WAITING_DOTS="true"
 
+# Uncomment following line if you want to disable marking untracked files under
+# VCS as dirty. This makes repository status check for large repositories much,
+# much faster.
+# DISABLE_UNTRACKED_FILES_DIRTY="true"
+
 # Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
 # Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
 # Example format: plugins=(rails git textmate ruby lighthouse)
diff --git a/themes/agnoster.zsh-theme b/themes/agnoster.zsh-theme
index 75e095776..c7a59ad0d 100644
--- a/themes/agnoster.zsh-theme
+++ b/themes/agnoster.zsh-theme
@@ -26,7 +26,7 @@
 # A few utility functions to make it easy and re-usable to draw segmented prompts
 
 CURRENT_BG='NONE'
-SEGMENT_SEPARATOR='⮀'
+SEGMENT_SEPARATOR=''
 
 # Begin a segment
 # Takes two arguments, background and foreground. Both can be omitted,
@@ -71,7 +71,6 @@ prompt_context() {
 prompt_git() {
   local ref dirty
   if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
-    ZSH_THEME_GIT_PROMPT_DIRTY='±'
     dirty=$(parse_git_dirty)
     ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="➦ $(git show-ref --head -s --abbrev |head -n1 2> /dev/null)"
     if [[ -n $dirty ]]; then
@@ -79,7 +78,19 @@ prompt_git() {
     else
       prompt_segment green black
     fi
-    echo -n "${ref/refs\/heads\//⭠ }$dirty"
+
+    setopt promptsubst
+    autoload -Uz vcs_info
+
+    zstyle ':vcs_info:*' enable git
+    zstyle ':vcs_info:*' get-revision true
+    zstyle ':vcs_info:*' check-for-changes true
+    zstyle ':vcs_info:*' stagedstr '✚'
+    zstyle ':vcs_info:git:*' unstagedstr '●'
+    zstyle ':vcs_info:*' formats ' %u%c'
+    zstyle ':vcs_info:*' actionformats '%u%c'
+    vcs_info
+    echo -n "${ref/refs\/heads\// }${vcs_info_msg_0_}"
   fi
 }
 
@@ -99,7 +110,7 @@ prompt_hg() {
 				# if working copy is clean
 				prompt_segment green black
 			fi
-			echo -n $(hg prompt "⭠ {rev}@{branch}") $st
+			echo -n $(hg prompt " {rev}@{branch}") $st
 		else
 			st=""
 			rev=$(hg id -n 2>/dev/null | sed 's/[^-0-9]//g')
@@ -113,7 +124,7 @@ prompt_hg() {
 			else
 				prompt_segment green black
 			fi
-			echo -n "⭠ $rev@$branch" $st
+			echo -n " $rev@$branch" $st
 		fi
 	fi
 }
@@ -123,6 +134,14 @@ prompt_dir() {
   prompt_segment blue black '%~'
 }
 
+# Virtualenv: current working virtualenv
+prompt_virtualenv() {
+  local virtualenv_path="$VIRTUAL_ENV"
+  if [[ -n $virtualenv_path ]]; then
+    prompt_segment blue black "(`basename $virtualenv_path`)"
+  fi
+}
+
 # Status:
 # - was there an error
 # - am I root
@@ -141,6 +160,7 @@ prompt_status() {
 build_prompt() {
   RETVAL=$?
   prompt_status
+  prompt_virtualenv
   prompt_context
   prompt_dir
   prompt_git
diff --git a/themes/avit.zsh-theme b/themes/avit.zsh-theme
new file mode 100644
index 000000000..51f5e375a
--- /dev/null
+++ b/themes/avit.zsh-theme
@@ -0,0 +1,120 @@
+#
+# Author:: Andrew Vit ()
+#
+# AVIT ZSH Theme
+#
+# Copyright 2011, Andrew Vit
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PROMPT='
+$(_user_host)${_current_dir} $(git_prompt_info) $(_ruby_version)
+▶ '
+
+PROMPT2='%{$fg[grey]%}◀%{$reset_color%} '
+
+RPROMPT='$(_vi_status)%{$(echotc UP 1)%}$(_git_time_since_commit) $(git_prompt_status) ${_return_status}%{$(echotc DO 1)%}'
+
+local _current_dir="%{$fg[blue]%}%3~%{$reset_color%} "
+local _return_status="%{$fg[red]%}%(?..⍉)%{$reset_color%}"
+local _hist_no="%{$fg[grey]%}%h%{$reset_color%}"
+
+function _user_host() {
+  if [[ -n $SSH_CONNECTION ]]; then
+    me="%n@%m"
+  elif [[ $LOGNAME != $USER ]]; then
+    me="%n"
+  fi
+  if [[ -n $me ]]; then
+    echo "%{$fg[cyan]%}$me%{$reset_color%}:"
+  fi
+}
+
+function _vi_status() {
+  if {echo $fpath | grep -q "plugins/vi-mode"}; then
+    echo "$(vi_mode_prompt_info)"
+  fi
+}
+
+function _ruby_version() {
+  if {echo $fpath | grep -q "plugins/rvm"}; then
+    echo "%{$fg[grey]%}$(rvm_prompt_info)%{$reset_color%}"
+  fi
+}
+
+# Determine the time since last commit. If branch is clean,
+# use a neutral color, otherwise colors will vary according to time.
+function _git_time_since_commit() {
+  if git rev-parse --git-dir > /dev/null 2>&1; then
+    # Only proceed if there is actually a commit.
+    if [[ $(git log 2>&1 > /dev/null | grep -c "^fatal: bad default revision") == 0 ]]; then
+      # Get the last commit.
+      last_commit=$(git log --pretty=format:'%at' -1 2> /dev/null)
+      now=$(date +%s)
+      seconds_since_last_commit=$((now-last_commit))
+
+      # Totals
+      minutes=$((seconds_since_last_commit / 60))
+      hours=$((seconds_since_last_commit/3600))
+
+      # Sub-hours and sub-minutes
+      days=$((seconds_since_last_commit / 86400))
+      sub_hours=$((hours % 24))
+      sub_minutes=$((minutes % 60))
+
+      if [ $hours -gt 24 ]; then
+          commit_age="${days}d"
+      elif [ $minutes -gt 60 ]; then
+          commit_age="${sub_hours}h${sub_minutes}m"
+      else
+          commit_age="${minutes}m"
+      fi
+
+      color=$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL
+      echo "$color$commit_age%{$reset_color%}"
+    fi
+  fi
+}
+
+if [[ $USER == "root" ]]; then
+  CARETCOLOR="red"
+else
+  CARETCOLOR="white"
+fi
+
+MODE_INDICATOR="%{$fg_bold[yellow]%}❮%{$reset_color%}%{$fg[yellow]%}❮❮%{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%}✚ "
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%}⚑ "
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%}✖ "
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%}▴ "
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[cyan]%}§ "
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[grey]%}◒ "
+
+# Colors vary depending on time lapsed.
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT="%{$fg[green]%}"
+ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM="%{$fg[yellow]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG="%{$fg[red]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[grey]%}"
+
+# LS colors, made with http://geoff.greer.fm/lscolors/
+export LSCOLORS="exfxcxdxbxegedabagacad"
+export LS_COLORS='di=34;40:ln=35;40:so=32;40:pi=33;40:ex=31;40:bd=34;46:cd=34;43:su=0;41:sg=0;46:tw=0;42:ow=0;43:'
+export GREP_COLOR='1;33'
+
diff --git a/themes/crunch.zsh-theme b/themes/crunch.zsh-theme
index b2759a1b0..2fc066381 100644
--- a/themes/crunch.zsh-theme
+++ b/themes/crunch.zsh-theme
@@ -29,7 +29,7 @@ ZSH_THEME_GIT_PROMPT_DIRTY=" $CRUNCH_GIT_DIRTY_COLOR✗"
 
 # Our elements:
 CRUNCH_TIME_="$CRUNCH_BRACKET_COLOR{$CRUNCH_TIME_COLOR%T$CRUNCH_BRACKET_COLOR}%{$reset_color%}"
-if which rvm-prompt &> /dev/null; then
+if [ -e ~/.rvm/bin/rvm-prompt ]; then
   CRUNCH_RVM_="$CRUNCH_BRACKET_COLOR"["$CRUNCH_RVM_COLOR\${\$(~/.rvm/bin/rvm-prompt i v g)#ruby-}$CRUNCH_BRACKET_COLOR"]"%{$reset_color%}"
 else
   if which rbenv &> /dev/null; then
diff --git a/themes/dallas.zsh-theme b/themes/dallas.zsh-theme
index c9e335521..e9e86177b 100644
--- a/themes/dallas.zsh-theme
+++ b/themes/dallas.zsh-theme
@@ -3,7 +3,7 @@
 # Grab the current date (%D) and time (%T) wrapped in {}: {%D %T}
 DALLAS_CURRENT_TIME_="%{$fg[white]%}{%{$fg[yellow]%}%D %T%{$fg[white]%}}%{$reset_color%}"
 # Grab the current version of ruby in use (via RVM): [ruby-1.8.7]
-if which rvm-prompt &> /dev/null; then
+if [ -e ~/.rvm/bin/rvm-prompt ]; then
   DALLAS_CURRENT_RUBY_="%{$fg[white]%}[%{$fg[magenta]%}\$(~/.rvm/bin/rvm-prompt i v)%{$fg[white]%}]%{$reset_color%}"
 else
   if which rbenv &> /dev/null; then
diff --git a/themes/essembeh.zsh-theme b/themes/essembeh.zsh-theme
new file mode 100644
index 000000000..8c98ea1ed
--- /dev/null
+++ b/themes/essembeh.zsh-theme
@@ -0,0 +1,31 @@
+# Theme with full path names and hostname
+# Handy if you work on different servers all the time;
+
+
+local return_code="%(?..%{$fg_bold[red]%}%? ↵%{$reset_color%})"
+
+function my_git_prompt_info() {
+	ref=$(git symbolic-ref HEAD 2> /dev/null) || return
+	GIT_STATUS=$(git_prompt_status)
+	[[ -n $GIT_STATUS ]] && GIT_STATUS=" $GIT_STATUS"
+	echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$GIT_STATUS$ZSH_THEME_GIT_PROMPT_SUFFIX"
+}
+
+# Colored prompt
+ZSH_THEME_COLOR_USER="green" 
+ZSH_THEME_COLOR_HOST="green" 
+ZSH_THEME_COLOR_PWD="yellow" 
+test -n "$SSH_CONNECTION" && ZSH_THEME_COLOR_USER="red" && ZSH_THEME_COLOR_HOST="red"
+test `id -u` = 0 && ZSH_THEME_COLOR_USER="magenta" && ZSH_THEME_COLOR_HOST="magenta"
+PROMPT='%{$fg_bold[$ZSH_THEME_COLOR_USER]%}%n@%{$fg_bold[$ZSH_THEME_COLOR_HOST]%}%M%{$reset_color%}:%{$fg_bold[$ZSH_THEME_COLOR_PWD]%}%~%{$reset_color%} $(my_git_prompt_info)%(!.#.$) '
+RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[cyan]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=") %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%%"
+ZSH_THEME_GIT_PROMPT_ADDED="+"
+ZSH_THEME_GIT_PROMPT_MODIFIED="*"
+ZSH_THEME_GIT_PROMPT_RENAMED="~"
+ZSH_THEME_GIT_PROMPT_DELETED="!"
+ZSH_THEME_GIT_PROMPT_UNMERGED="?"
+
diff --git a/themes/fishy.zsh-theme b/themes/fishy.zsh-theme
index e9f78a54e..8b24172a2 100644
--- a/themes/fishy.zsh-theme
+++ b/themes/fishy.zsh-theme
@@ -1,8 +1,13 @@
 # ZSH Theme emulating the Fish shell's default prompt.
 
 _fishy_collapsed_wd() {
-  echo $(pwd | perl -pe "s|^$HOME|~|g; s|/([^/])[^/]*(?=/)|/\$1|g")
-}
+  echo $(pwd | perl -pe "
+   BEGIN {
+      binmode STDIN,  ':encoding(UTF-8)';
+      binmode STDOUT, ':encoding(UTF-8)';
+   }; s|^$HOME|~|g; s|/([^/])[^/]*(?=/)|/\$1|g
+")
+} 
 
 local user_color='green'; [ $UID -eq 0 ] && user_color='red'
 PROMPT='%n@%m %{$fg[$user_color]%}$(_fishy_collapsed_wd)%{$reset_color%}%(!.#.>) '
diff --git a/themes/half-life.zsh-theme b/themes/half-life.zsh-theme
new file mode 100644
index 000000000..c8d09ce47
--- /dev/null
+++ b/themes/half-life.zsh-theme
@@ -0,0 +1,99 @@
+# prompt style and colors based on Steve Losh's Prose theme:
+# http://github.com/sjl/oh-my-zsh/blob/master/themes/prose.zsh-theme
+#
+# vcs_info modifications from Bart Trojanowski's zsh prompt:
+# http://www.jukie.net/bart/blog/pimping-out-zsh-prompt
+#
+# git untracked files modification from Brian Carper:
+# http://briancarper.net/blog/570/git-info-in-your-zsh-prompt
+
+function virtualenv_info {
+    [ $VIRTUAL_ENV ] && echo '('`basename $VIRTUAL_ENV`') '
+}
+PR_GIT_UPDATE=1
+
+setopt prompt_subst
+autoload colors
+colors
+
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+#use extended color pallete if available
+if [[ $TERM = *256color* || $TERM = *rxvt* ]]; then
+    turquoise="%F{81}"
+    orange="%F{166}"
+    purple="%F{135}"
+    hotpink="%F{161}"
+    limegreen="%F{118}"
+else
+    turquoise="$fg[cyan]"
+    orange="$fg[yellow]"
+    purple="$fg[magenta]"
+    hotpink="$fg[red]"
+    limegreen="$fg[green]"
+fi
+
+# enable VCS systems you use
+zstyle ':vcs_info:*' enable git svn
+
+# check-for-changes can be really slow.
+# you should disable it, if you work with large repositories
+zstyle ':vcs_info:*:prompt:*' check-for-changes true
+
+# set formats
+# %b - branchname
+# %u - unstagedstr (see below)
+# %c - stagedstr (see below)
+# %a - action (e.g. rebase-i)
+# %R - repository path
+# %S - path in the repository
+PR_RST="%{${reset_color}%}"
+FMT_BRANCH=" on %{$turquoise%}%b%u%c${PR_RST}"
+FMT_ACTION=" performing a %{$limegreen%}%a${PR_RST}"
+FMT_UNSTAGED="%{$orange%}●"
+FMT_STAGED="%{$limegreen%}●"
+
+zstyle ':vcs_info:*:prompt:*' unstagedstr   "${FMT_UNSTAGED}"
+zstyle ':vcs_info:*:prompt:*' stagedstr     "${FMT_STAGED}"
+zstyle ':vcs_info:*:prompt:*' actionformats "${FMT_BRANCH}${FMT_ACTION}"
+zstyle ':vcs_info:*:prompt:*' formats       "${FMT_BRANCH}"
+zstyle ':vcs_info:*:prompt:*' nvcsformats   ""
+
+
+function steeef_preexec {
+    case "$(history $HISTCMD)" in
+        *git*)
+            PR_GIT_UPDATE=1
+            ;;
+        *svn*)
+            PR_GIT_UPDATE=1
+            ;;
+    esac
+}
+add-zsh-hook preexec steeef_preexec
+
+function steeef_chpwd {
+    PR_GIT_UPDATE=1
+}
+add-zsh-hook chpwd steeef_chpwd
+
+function steeef_precmd {
+    if [[ -n "$PR_GIT_UPDATE" ]] ; then
+        # check for untracked files or updated submodules, since vcs_info doesn't
+        if [[ ! -z $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then
+            PR_GIT_UPDATE=1
+            FMT_BRANCH="${PM_RST} on %{$turquoise%}%b%u%c%{$hotpink%}●${PR_RST}"
+        else
+            FMT_BRANCH="${PM_RST} on %{$turquoise%}%b%u%c${PR_RST}"
+        fi
+        zstyle ':vcs_info:*:prompt:*' formats       "${FMT_BRANCH}"
+
+        vcs_info 'prompt'
+        PR_GIT_UPDATE=
+    fi
+}
+add-zsh-hook precmd steeef_precmd
+
+PROMPT=$'
+%{$purple%}%n%{$reset_color%} in %{$limegreen%}%~%{$reset_color%}$(rvm-prompt " with%{$fg[red]%} " v g "%{$reset_color%}")$vcs_info_msg_0_%{$orange%} λ%{$reset_color%} '
diff --git a/themes/macovsky-ruby.zsh-theme b/themes/macovsky-ruby.zsh-theme
index 045376761..69d80d588 100644
--- a/themes/macovsky-ruby.zsh-theme
+++ b/themes/macovsky-ruby.zsh-theme
@@ -1,7 +1,7 @@
 # ZSH Theme - Preview: http://gyazo.com/8becc8a7ed5ab54a0262a470555c3eed.png
 local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
 
-if which rvm-prompt &> /dev/null; then
+if [ -e ~/.rvm/bin/rvm-prompt ]; then
   PROMPT='%{$fg[green]%}%~%{$reset_color%} %{$fg[red]%}‹$(~/.rvm/bin/rvm-prompt i v)› %{$reset_color%} $(git_prompt_info)%{$reset_color%}%B$%b '
 else
   if which rbenv &> /dev/null; then
diff --git a/themes/macovsky.zsh-theme b/themes/macovsky.zsh-theme
index b6978b929..2e6dce42d 100644
--- a/themes/macovsky.zsh-theme
+++ b/themes/macovsky.zsh-theme
@@ -1,7 +1,7 @@
 # ZSH Theme - Preview: http://gyazo.com/8becc8a7ed5ab54a0262a470555c3eed.png
 local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
 
-if which rvm-prompt &> /dev/null; then
+if [ -e ~/.rvm/bin/rvm-prompt ]; then
   PROMPT='%{$fg[green]%}%~%{$reset_color%} %{$fg[red]%}‹$(~/.rvm/bin/rvm-prompt i v)› %{$reset_color%} $(git_prompt_info)%{$reset_color%}%B$%b '
 else
   if which rbenv &> /dev/null; then
diff --git a/themes/rkj-repos.zsh-theme b/themes/rkj-repos.zsh-theme
index 318c315bb..4ab3bc757 100644
--- a/themes/rkj-repos.zsh-theme
+++ b/themes/rkj-repos.zsh-theme
@@ -22,8 +22,10 @@ function mygit() {
   echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$( git_prompt_status )%{$reset_color%}$ZSH_THEME_GIT_PROMPT_SUFFIX"
 }
 
+function retcode() {}
+
 # alternate prompt with git & hg
 PROMPT=$'%{\e[0;34m%}%B┌─[%b%{\e[0m%}%{\e[1;32m%}%n%{\e[1;30m%}@%{\e[0m%}%{\e[0;36m%}%m%{\e[0;34m%}%B]%b%{\e[0m%} - %b%{\e[0;34m%}%B[%b%{\e[1;37m%}%~%{\e[0;34m%}%B]%b%{\e[0m%} - %{\e[0;34m%}%B[%b%{\e[0;33m%}'%D{"%Y-%m-%d %I:%M:%S"}%b$'%{\e[0;34m%}%B]%b%{\e[0m%}
-%{\e[0;34m%}%B└─%B[%{\e[1;35m%}$%{\e[0;34m%}%B] <$(mygit)$(hg_prompt_info)>%{\e[0m%}%b '
+%{\e[0;34m%}%B└─%B[%{\e[1;35m%}%?$(retcode)%{\e[0;34m%}%B] <$(mygit)$(hg_prompt_info)>%{\e[0m%}%b '
 PS2=$' \e[0;34m%}%B>%{\e[0m%}%b '
 
diff --git a/themes/rkj.zsh-theme b/themes/rkj.zsh-theme
index 81b701e07..fe06161c8 100644
--- a/themes/rkj.zsh-theme
+++ b/themes/rkj.zsh-theme
@@ -2,7 +2,8 @@
 # on two lines for easier vgrepping
 # entry in a nice long thread on the Arch Linux forums: http://bbs.archlinux.org/viewtopic.php?pid=521888#p521888
 
+function retcode() {}
+
 PROMPT=$'%{\e[0;34m%}%B┌─[%b%{\e[0m%}%{\e[1;32m%}%n%{\e[1;30m%}@%{\e[0m%}%{\e[0;36m%}%m%{\e[0;34m%}%B]%b%{\e[0m%} - %b%{\e[0;34m%}%B[%b%{\e[1;37m%}%~%{\e[0;34m%}%B]%b%{\e[0m%} - %{\e[0;34m%}%B[%b%{\e[0;33m%}'%D{"%Y-%m-%d %I:%M:%S"}%b$'%{\e[0;34m%}%B]%b%{\e[0m%}
-%{\e[0;34m%}%B└─%B[%{\e[1;35m%}$%{\e[0;34m%}%B]%{\e[0m%}%b '
-
+%{\e[0;34m%}%B└─%B[%{\e[1;35m%}%?$(retcode)%{\e[0;34m%}%B]%{\e[0m%}%b '
 
diff --git a/themes/superjarin.zsh-theme b/themes/superjarin.zsh-theme
index 0be816de0..2920d17a2 100644
--- a/themes/superjarin.zsh-theme
+++ b/themes/superjarin.zsh-theme
@@ -1,5 +1,5 @@
 # Grab the current version of ruby in use (via RVM): [ruby-1.8.7]
-if which rvm-prompt &> /dev/null; then
+if [ -e ~/.rvm/bin/rvm-prompt ]; then
   JARIN_CURRENT_RUBY_="%{$fg[white]%}[%{$fg[red]%}\$(~/.rvm/bin/rvm-prompt i v)%{$fg[white]%}]%{$reset_color%}"
 else
   if which rbenv &> /dev/null; then
@@ -11,13 +11,13 @@ fi
 # Append the current git branch, if in a git repository
 JARIN_CURRENT_LOCA_="%{$fg_bold[cyan]%}%~\$(git_prompt_info)%{$reset_color%}"
 ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[white]%} <%{$fg[magenta]%}"
-ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg[white]%}"
 
 # Do nothing if the branch is clean (no changes).
-ZSH_THEME_GIT_PROMPT_CLEAN="%{$reset_color%}>"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[white]%}>"
 
 # Add a yellow ✗ if the branch is dirty
-ZSH_THEME_GIT_PROMPT_DIRTY="%{$reset_color%}> %{$fg[yellow]%}✗"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[white]%}> %{$fg[yellow]%}✗"
 
 # Put it all together!
 PROMPT="$JARIN_CURRENT_RUBY_ $JARIN_CURRENT_LOCA_ "
diff --git a/themes/zhann.zsh-theme b/themes/zhann.zsh-theme
index 574e0cec3..5c49fe79b 100644
--- a/themes/zhann.zsh-theme
+++ b/themes/zhann.zsh-theme
@@ -1,6 +1,6 @@
 PROMPT='%{$fg_bold[green]%}%p %{$fg[cyan]%}%c%{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
 
-if which rvm-prompt &> /dev/null; then
+if [ -e ~/.rvm/bin/rvm-prompt ]; then
   RPROMPT='%{$reset_color%} %{$fg[red]%}$(~/.rvm/bin/rvm-prompt i v g) %{$reset_color%}'
 else
   if which rbenv &> /dev/null; then
diff --git a/tools/upgrade.sh b/tools/upgrade.sh
index 0aeebdebf..e04fc672f 100644
--- a/tools/upgrade.sh
+++ b/tools/upgrade.sh
@@ -1,9 +1,6 @@
-current_path=`pwd`
-current_path=${current_path/ /\\ }
 printf '\033[0;34m%s\033[0m\n' "Upgrading Oh My Zsh"
 cd "$ZSH"
-
-if git pull origin master
+if git pull --rebase origin master
 then
   printf '\033[0;32m%s\033[0m\n' '         __                                     __   '
   printf '\033[0;32m%s\033[0m\n' '  ____  / /_     ____ ___  __  __   ____  _____/ /_  '
@@ -17,4 +14,3 @@ else
   printf '\033[0;31m%s\033[0m\n' 'There was an error updating. Try again later?'
 fi
 
-cd "$current_path"