e6ccd37b0563b4e7b34c41034766b9789e43ee5c

Author
Chris McCuller <cmcculler@salesforce.com>
Committer
Chris McCuller <cmcculler@salesforce.com>
Date

Message

Merge master (rebase being super annoying). Fix conflicts

Diff

This diff is truncated to protect this page.

   1diff --git a/README.markdown b/README.markdown
   2index 3805d1eb41f68cc40b400aa9b4e4c1c36c8b38d7..a29df81ab5d6aff44df86ce96e10448483474744 100644
   3--- a/README.markdown
   4+++ b/README.markdown
   5@@ -3,9 +3,9 @@
   6 
   7 Oh My Zsh is an open source, community-driven framework for managing your [zsh](http://www.zsh.org/) configuration. That sounds boring. Let's try this again.
   8 
   9diff --git a/lib/compfix.zsh b/lib/compfix.zsh
  10new file mode 100644
  11index 0000000000000000000000000000000000000000..208aaadb1ebad0e25ebdef29192da815be8136bd
  12--- /dev/null
  13+++ b/lib/compfix.zsh
  14@@ -0,0 +1,60 @@
  15+# Handle completions insecurities (i.e., completion-dependent directories with
  16+# insecure ownership or permissions) by:
  17+#
  18+# * Human-readably notifying the user of these insecurities.
  19+# * Moving away all existing completion caches to a temporary directory. Since
  20+#   any of these caches may have been generated from insecure directories, they
  21+#   are all suspect now. Failing to do so typically causes subsequent compinit()
  22+#   calls to fail with "command not found: compdef" errors. (That's bad.)
  23+function handle_completion_insecurities() {
  24+  # List of the absolute paths of all unique insecure directories, split on
  25+  # newline from compaudit()'s output resembling:
  26+  #
  27+  #     There are insecure directories:
  28+  #     /usr/share/zsh/site-functions
  29+  #     /usr/share/zsh/5.0.6/functions
  30+  #     /usr/share/zsh
  31+  #     /usr/share/zsh/5.0.6
  32+  #
  33+  # Since the ignorable first line is printed to stderr and thus not captured,
  34+  # stderr is squelched to prevent this output from leaking to the user. 
  35+  local -aU insecure_dirs
  36+  insecure_dirs=( ${(f@):-"$(compaudit 2>/dev/null)"} )
  37+
  38+  # If no such directories exist, get us out of here.
  39+  if (( ! ${#insecure_dirs} )); then
  40+      print "[oh-my-zsh] No insecure completion-dependent directories detected."
  41+      return
  42+  fi
  43+
  44+  # List ownership and permissions of all insecure directories.
  45+  print "[oh-my-zsh] Insecure completion-dependent directories detected:"
  46+  ls -ld "${(@)insecure_dirs}"
  47+  print "[oh-my-zsh] For safety, completions will be disabled until you manually fix all"
  48+  print "[oh-my-zsh] insecure directory permissions and ownership and restart oh-my-zsh."
  49+  print "[oh-my-zsh] See the above list for directories with group or other writability.\n"
  50+
  51+  # Locally enable the "NULL_GLOB" option, thus removing unmatched filename
  52+  # globs from argument lists *AND* printing no warning when doing so. Failing
  53+  # to do so prints an unreadable warning if no completion caches exist below.
  54+  setopt local_options null_glob
  55+
  56+  # List of the absolute paths of all unique existing completion caches.
  57+  local -aU zcompdump_files
  58+  zcompdump_files=( "${ZSH_COMPDUMP}"(.) "${ZDOTDIR:-${HOME}}"/.zcompdump* )
  59+
  60+  # Move such caches to a temporary directory.
  61+  if (( ${#zcompdump_files} )); then
  62+    # Absolute path of the directory to which such files will be moved.
  63+    local ZSH_ZCOMPDUMP_BAD_DIR="${ZSH_CACHE_DIR}/zcompdump-bad"
  64+
  65+    # List such files first.
  66+    print "[oh-my-zsh] Insecure completion caches also detected:"
  67+    ls -l "${(@)zcompdump_files}"
  68+
  69+    # For safety, move rather than permanently remove such files.
  70+    print "[oh-my-zsh] Moving to \"${ZSH_ZCOMPDUMP_BAD_DIR}/\"...\n"
  71+    mkdir -p "${ZSH_ZCOMPDUMP_BAD_DIR}"
  72+    mv "${(@)zcompdump_files}" "${ZSH_ZCOMPDUMP_BAD_DIR}/"
  73+  fi
  74+}
  75diff --git a/lib/completion.zsh b/lib/completion.zsh
  76index 452c0dfe765539dd6cf0a83f85037c7ac5f571a9..f5b29247127543f4aec6ffec6bdb4b29bcdd9de1 100644
  77--- a/lib/completion.zsh
  78+++ b/lib/completion.zsh
  79@@ -58,9 +58,13 @@ zstyle ':completion:*:*:*:users' ignored-patterns \
  80 # ... unless we really want to.
  81 zstyle '*' single-ignored show
  82 
  83-if [ "x$COMPLETION_WAITING_DOTS" = "xtrue" ]; then
  84+if [[ $COMPLETION_WAITING_DOTS = true ]]; then
  85   expand-or-complete-with-dots() {
  86-    echo -n "\e[31m......\e[0m"
  87+    # toggle line-wrapping off and back on again
  88+    [[ -n "$terminfo[rmam]" && -n "$terminfo[smam]" ]] && echoti rmam
  89+    print -Pn "%{%F{red}......%f%}"
  90+    [[ -n "$terminfo[rmam]" && -n "$terminfo[smam]" ]] && echoti smam
  91+
  92     zle expand-or-complete
  93     zle redisplay
  94   }
  95diff --git a/lib/diagnostics.zsh b/lib/diagnostics.zsh
  96new file mode 100644
  97index 0000000000000000000000000000000000000000..afc33829b01c0a09dc0633a21fbfee906c5d3116
  98--- /dev/null
  99+++ b/lib/diagnostics.zsh
 100@@ -0,0 +1,335 @@
 101+# diagnostics.zsh
 102+#
 103+# Diagnostic and debugging support for oh-my-zsh
 104+
 105+# omz_diagnostic_dump()
 106+#
 107+# Author: Andrew Janke <andrew@apjanke.net>
 108+#
 109+# Usage:
 110+#
 111+# omz_diagnostic_dump [-v] [-V] [file]
 112+#
 113+# NOTE: This is a work in progress. Its interface and behavior are going to change,
 114+# and probably in non-back-compatible ways.
 115+#
 116+# Outputs a bunch of information about the state and configuration of
 117+# oh-my-zsh, zsh, and the user's system. This is intended to provide a
 118+# bunch of context for diagnosing your own or a third party's problems, and to
 119+# be suitable for posting to public bug reports.
 120+#
 121+# The output is human-readable and its format may change over time. It is not
 122+# suitable for parsing. All the output is in one single file so it can be posted
 123+# as a gist or bug comment on GitHub. GitHub doesn't support attaching tarballs
 124+# or other files to bugs; otherwise, this would probably have an option to produce
 125+# tarballs that contain copies of the config and customization files instead of
 126+# catting them all in to one file.
 127+#
 128+# This is intended to be widely portable, and run anywhere that oh-my-zsh does.
 129+# Feel free to report any portability issues as bugs.
 130+#
 131+# This is written in a defensive style so it still works (and can detect) cases when
 132+# basic functionality like echo and which have been redefined. In particular, almost
 133+# everything is invoked with "builtin" or "command", to work in the face of user 
 134+# redefinitions.
 135+#
 136+# OPTIONS
 137+#
 138+# [file]   Specifies the output file. If not given, a file in the current directory
 139+#        is selected automatically.
 140+#
 141+# -v    Increase the verbosity of the dump output. May be specified multiple times.
 142+#       Verbosity levels:
 143+#        0 - Basic info, shell state, omz configuration, git state
 144+#        1 - (default) Adds key binding info and configuration file contents
 145+#        2 - Adds zcompdump file contents
 146+#
 147+# -V    Reduce the verbosity of the dump output. May be specified multiple times.
 148+#
 149+# TODO:
 150+# * Multi-file capture
 151+# * Add automatic gist uploading
 152+# * Consider whether to move default output file location to TMPDIR. More robust
 153+#     but less user friendly.
 154+#
 155+function omz_diagnostic_dump() {
 156+  emulate -L zsh
 157+
 158+  builtin echo "Generating diagnostic dump; please be patient..."
 159+  
 160+  local thisfcn=omz_diagnostic_dump
 161+  local -A opts
 162+  local opt_verbose opt_noverbose opt_outfile
 163+  local timestamp=$(date +%Y%m%d-%H%M%S)
 164+  local outfile=omz_diagdump_$timestamp.txt
 165+  builtin zparseopts -A opts -D -- "v+=opt_verbose" "V+=opt_noverbose"
 166+  local verbose n_verbose=${#opt_verbose} n_noverbose=${#opt_noverbose}
 167+  (( verbose = 1 + n_verbose - n_noverbose ))
 168+
 169+  if [[ ${#*} > 0 ]]; then
 170+    opt_outfile=$1
 171+  fi
 172+  if [[ ${#*} > 1 ]]; then
 173+    builtin echo "$thisfcn: error: too many arguments" >&2
 174+    return 1
 175+  fi
 176+  if [[ -n "$opt_outfile" ]]; then
 177+    outfile="$opt_outfile"
 178+  fi
 179+
 180+  # Always write directly to a file so terminal escape sequences are
 181+  # captured cleanly
 182+  _omz_diag_dump_one_big_text &> "$outfile"
 183+  if [[ $? != 0 ]]; then
 184+    builtin echo "$thisfcn: error while creating diagnostic dump; see $outfile for details"
 185+  fi
 186+
 187+  builtin echo
 188+  builtin echo Diagnostic dump file created at: "$outfile"
 189+  builtin echo
 190+  builtin echo To share this with OMZ developers, post it as a gist on GitHub 
 191+  builtin echo at "https://gist.github.com" and share the link to the gist.
 192+  builtin echo
 193+  builtin echo "WARNING: This dump file contains all your zsh and omz configuration files,"
 194+  builtin echo "so don't share it publicly if there's sensitive information in them."
 195+  builtin echo
 196+
 197+}
 198+
 199+function _omz_diag_dump_one_big_text() {
 200diff --git a/lib/functions.zsh b/lib/functions.zsh
 201index 17f5f9cbf246ff0e6c58abfff6dff3ea227c99d8..efb73a1bd91170f1c2622635875ceb900942ee43 100644
 202--- a/lib/functions.zsh
 203+++ b/lib/functions.zsh
 204@@ -15,6 +15,22 @@ function take() {
 205   cd $1
 206 }
 207 
 208+function open_command() {
 209+  local open_cmd
 210+
 211+  # define the open command
 212+  case "$OSTYPE" in
 213+    darwin*)  open_cmd="open" ;;
 214+    cygwin*)  open_cmd="cygstart" ;;
 215+    linux*)   open_cmd="xdg-open" ;;
 216+    *)        echo "Platform $OSTYPE not supported"
 217+              return 1
 218+              ;;
 219+  esac
 220+
 221+  nohup $open_cmd "$@" &>/dev/null
 222+}
 223+
 224 #
 225 # Get the value of an alias.
 226 #
 227@@ -73,3 +89,135 @@ function env_default() {
 228     env | grep -q "^$1=" && return 0 
 229     export "$1=$2"       && return 3
 230 }
 231+
 232+
 233+# Required for $langinfo
 234+zmodload zsh/langinfo
 235+
 236+# URL-encode a string
 237+#
 238+# Encodes a string using RFC 2396 URL-encoding (%-escaped).
 239+# See: https://www.ietf.org/rfc/rfc2396.txt
 240+#
 241+# By default, reserved characters and unreserved "mark" characters are
 242+# not escaped by this function. This allows the common usage of passing
 243+# an entire URL in, and encoding just special characters in it, with 
 244+# the expectation that reserved and mark characters are used appropriately.
 245+# The -r and -m options turn on escaping of the reserved and mark characters,
 246+# respectively, which allows arbitrary strings to be fully escaped for
 247+# embedding inside URLs, where reserved characters might be misinterpreted.
 248+#
 249+# Prints the encoded string on stdout.
 250+# Returns nonzero if encoding failed.
 251+#
 252+# Usage:
 253+#  omz_urlencode [-r] [-m] <string>
 254+#  
 255+#    -r causes reserved characters (;/?:@&=+$,) to be escaped
 256+#
 257+#    -m causes "mark" characters (_.!~*''()-) to be escaped
 258+#
 259+#    -P causes spaces to be encoded as '%20' instead of '+'
 260+function omz_urlencode() {
 261+  emulate -L zsh
 262+  zparseopts -D -E -a opts r m P
 263+
 264+  local in_str=$1
 265+  local url_str=""
 266+  local spaces_as_plus
 267+  if [[ -z $opts[(r)-P] ]]; then spaces_as_plus=1; fi
 268+  local str="$in_str"
 269+
 270+  # URLs must use UTF-8 encoding; convert str to UTF-8 if required
 271+  local encoding=$langinfo[CODESET]
 272+  local safe_encodings
 273+  safe_encodings=(UTF-8 utf8 US-ASCII)
 274+  if [[ -z ${safe_encodings[(r)$encoding]} ]]; then
 275+    str=$(echo -E "$str" | iconv -f $encoding -t UTF-8)
 276+    if [[ $? != 0 ]]; then
 277+      echo "Error converting string from $encoding to UTF-8" >&2
 278+      return 1
 279+    fi
 280+  fi
 281+
 282+  # Use LC_CTYPE=C to process text byte-by-byte
 283+  local i byte ord LC_ALL=C
 284+  export LC_ALL
 285+  local reserved=';/?:@&=+$,'
 286+  local mark='_.!~*''()-'
 287+  local dont_escape="[A-Za-z0-9"
 288+  if [[ -z $opts[(r)-r] ]]; then
 289+    dont_escape+=$reserved
 290+  fi
 291+  # $mark must be last because of the "-"
 292+  if [[ -z $opts[(r)-m] ]]; then
 293+    dont_escape+=$mark
 294+  fi
 295+  dont_escape+="]"
 296+
 297+  # Implemented to use a single printf call and avoid subshells in the loop,
 298+  # for performance (primarily on Windows).
 299+  local url_str=""
 300+  for (( i = 1; i <= ${#str}; ++i )); do
 301+    byte="$str[i]"
 302+    if [[ "$byte" =~ "$dont_escape" ]]; then
 303+      url_str+="$byte"
 304diff --git a/lib/git.zsh b/lib/git.zsh
 305index caa7e632913251f9694b3a3b7cb357e2879e02cf..baf86371724d01ae842bbfe6d4f8e39530caf208 100644
 306--- a/lib/git.zsh
 307+++ b/lib/git.zsh
 308@@ -36,7 +36,10 @@ git_remote_status() {
 309         ahead=$(command git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l)
 310         behind=$(command git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l)
 311 
 312-        if [ $ahead -gt 0 ] && [ $behind -eq 0 ]
 313+        if [ $ahead -eq 0 ] && [ $behind -eq 0 ]
 314+        then
 315+          echo "$ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE"
 316+        elif [ $ahead -gt 0 ] && [ $behind -eq 0 ]
 317         then
 318             git_remote_status="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE"
 319             git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}"
 320diff --git a/lib/termsupport.zsh b/lib/termsupport.zsh
 321index e1c2e2f93a3b376a02180d21cdddf01f0bcdcb29..5f61fe8ef2d4e3cd34fe441dde04779f709f9fa7 100644
 322--- a/lib/termsupport.zsh
 323+++ b/lib/termsupport.zsh
 324@@ -7,6 +7,9 @@
 325 # (In screen, only short_tab_title is used)
 326 # Limited support for Apple Terminal (Terminal can't set window and tab separately)
 327 function title {
 328+  emulate -L zsh
 329+  setopt prompt_subst
 330+  
 331   [[ "$EMACS" == *term* ]] && return
 332 
 333   # if $2 is unset use $1 as default
 334@@ -23,9 +26,14 @@ function title {
 335 
 336 ZSH_THEME_TERM_TAB_TITLE_IDLE="%15<..<%~%<<" #15 char left truncated PWD
 337 ZSH_THEME_TERM_TITLE_IDLE="%n@%m: %~"
 338+# Avoid duplication of directory in terminals with independent dir display
 339+if [[ $TERM_PROGRAM == Apple_Terminal ]]; then
 340+  ZSH_THEME_TERM_TITLE_IDLE="%n@%m"
 341+fi
 342 
 343 # Runs before showing the prompt
 344 function omz_termsupport_precmd {
 345+  emulate -L zsh
 346   if [[ $DISABLE_AUTO_TITLE == true ]]; then
 347     return
 348   fi
 349@@ -35,15 +43,15 @@ function omz_termsupport_precmd {
 350 
 351 # Runs before executing the command
 352 function omz_termsupport_preexec {
 353+  emulate -L zsh
 354   if [[ $DISABLE_AUTO_TITLE == true ]]; then
 355     return
 356   fi
 357 
 358-  emulate -L zsh
 359   setopt extended_glob
 360 
 361   # cmd name only, or if this is sudo or ssh, the next cmd
 362-  local CMD=${1[(wr)^(*=*|sudo|ssh|rake|-*)]:gs/%/%%}
 363+  local CMD=${1[(wr)^(*=*|sudo|ssh|mosh|rake|-*)]:gs/%/%%}
 364   local LINE="${2:gs/%/%%}"
 365 
 366   title '$CMD' '%100>...>$LINE%<<'
 367@@ -53,14 +61,28 @@ precmd_functions+=(omz_termsupport_precmd)
 368 preexec_functions+=(omz_termsupport_preexec)
 369 
 370 
 371-# Runs before showing the prompt, to update the current directory in Terminal.app
 372-function omz_termsupport_cwd {
 373-  # Notify Terminal.app of current directory using undocumented OSC sequence
 374-  # found in OS X 10.9 and 10.10's /etc/bashrc
 375-  if [[ $TERM_PROGRAM == Apple_Terminal ]] && [[ -z $INSIDE_EMACS ]]; then
 376-    local PWD_URL="file://$HOSTNAME${PWD// /%20}"
 377-    printf '\e]7;%s\a' "$PWD_URL"
 378-  fi
 379-}
 380+# Keep Apple Terminal.app's current working directory updated
 381+# Based on this answer: http://superuser.com/a/315029
 382+# With extra fixes to handle multibyte chars and non-UTF-8 locales
 383+
 384+if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then
 385+
 386+  # Emits the control sequence to notify Terminal.app of the cwd
 387+  function update_terminalapp_cwd() {
 388+    emulate -L zsh
 389+    # Identify the directory using a "file:" scheme URL, including
 390+    # the host name to disambiguate local vs. remote paths.
 391+
 392+    # Percent-encode the pathname.
 393+    local URL_PATH=$(omz_urlencode -P $PWD)
 394+    [[ $? != 0 ]] && return 1
 395+    local PWD_URL="file://$HOST$URL_PATH"
 396+    # Undocumented Terminal.app-specific control sequence
 397+    printf '\e]7;%s\a' $PWD_URL
 398+  }
 399 
 400-precmd_functions+=(omz_termsupport_cwd)
 401+  # Use a precmd hook instead of a chpwd hook to avoid contaminating output
 402+  precmd_functions+=(update_terminalapp_cwd)
 403+  # Run once to get initial cwd set
 404+  update_terminalapp_cwd
 405+fi
 406diff --git a/lib/theme-and-appearance.zsh b/lib/theme-and-appearance.zsh
 407index 926303ca4509cd89bbc30187fd99879c1fbeb771..ebb11fb3185cef97ef29c8b6f11174c7669986ac 100644
 408--- a/lib/theme-and-appearance.zsh
 409+++ b/lib/theme-and-appearance.zsh
 410@@ -11,8 +11,11 @@ then
 411     # otherwise, leave ls as is, because NetBSD's ls doesn't support -G
 412     gls --color -d . &>/dev/null 2>&1 && alias ls='gls --color=tty'
 413   elif [[ "$(uname -s)" == "OpenBSD" ]]; then
 414-    # On OpenBSD, test if "colorls" is installed (this one supports colors);
 415-    # otherwise, leave ls as is, because OpenBSD's ls doesn't support -G
 416+    # On OpenBSD, "gls" (ls from GNU coreutils) and "colorls" (ls from base, 
 417+    # with color and multibyte support) are available from ports.  "colorls"  
 418+    # will be installed on purpose and can't be pulled in by installing 
 419+    # coreutils, so prefer it to "gls".
 420+    gls --color -d . &>/dev/null 2>&1 && alias ls='gls --color=tty'
 421     colorls -G -d . &>/dev/null 2>&1 && alias ls='colorls -G'
 422   else
 423     ls --color -d . &>/dev/null 2>&1 && alias ls='ls --color=tty' || alias ls='ls -G'
 424diff --git a/oh-my-zsh.sh b/oh-my-zsh.sh
 425index ec64c240f0203b64b1d32fe6da2ae657e93329f1..8e31ddd0ff62c43d187cd6f6fd2bf97a72a0bc11 100644
 426--- a/oh-my-zsh.sh
 427+++ b/oh-my-zsh.sh
 428@@ -8,6 +8,9 @@ fi
 429 # add a function path
 430 fpath=($ZSH/functions $ZSH/completions $fpath)
 431 
 432+# Load all stock functions (from $fpath files) called below.
 433+autoload -U compaudit compinit
 434+
 435 # Set ZSH_CUSTOM to the path where your custom config files
 436 # and plugins exists, or else we will use the default custom/
 437 if [[ -z "$ZSH_CUSTOM" ]]; then
 438@@ -29,11 +32,6 @@ for config_file ($ZSH/lib/*.zsh); do
 439   source $config_file
 440 done
 441 
 442-# Load all of your custom configurations from custom/
 443-for config_file ($ZSH_CUSTOM/*.zsh(N)); do
 444-  source $config_file
 445-done
 446-unset config_file
 447 
 448 is_plugin() {
 449   local base_dir=$1
 450@@ -64,9 +62,14 @@ if [ -z "$ZSH_COMPDUMP" ]; then
 451   ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
 452 fi
 453 
 454-# Load and run compinit
 455-autoload -U compinit
 456-compinit -i -d "${ZSH_COMPDUMP}"
 457+# If completion insecurities exist, warn the user without enabling completions.
 458+if ! compaudit &>/dev/null; then
 459+  # This function resides in the "lib/compfix.zsh" script sourced above.
 460+  handle_completion_insecurities
 461+# Else, enable and cache completions to the desired file.
 462+else
 463+  compinit -d "${ZSH_COMPDUMP}"
 464+fi
 465 
 466 # Load all of the plugins that were defined in ~/.zshrc
 467 for plugin ($plugins); do
 468@@ -77,6 +80,12 @@ for plugin ($plugins); do
 469   fi
 470 done
 471 
 472+# Load all of your custom configurations from custom/
 473+for config_file ($ZSH_CUSTOM/*.zsh(N)); do
 474+  source $config_file
 475+done
 476+unset config_file
 477+
 478 # Load the theme
 479 if [ "$ZSH_THEME" = "random" ]; then
 480   themes=($ZSH/themes/*zsh-theme)
 481diff --git a/plugins/atom/README.md b/plugins/atom/README.md
 482index 75d77a0ac1c3732be4dbab1b4062e4f8e1d315fc..6350c647b029ef0ca2416c6dcfe976a63e1d1534 100644
 483--- a/plugins/atom/README.md
 484+++ b/plugins/atom/README.md
 485@@ -1,6 +1,8 @@
 486 ## atom
 487 
 488-Plugin for Atom, a cross platform text and code editor, available for Linux, Mac OS X, and Windows.
 489+This plugin makes "at" a useful function for invoking the Atom Editor.
 490+
 491+Originally by Github user [aforty](https://github.com/aforty) for OSX, modified to alias 'at' to 'atom' for Linux, since atom already works on the terminal for Linux, and calling 'at' in a non-OSX environment should still work.
 492 
 493 ### Requirements
 494 
 495@@ -10,8 +12,12 @@ Plugin for Atom, a cross platform text and code editor, available for Linux, Mac
 496 
 497  * If `at` command is called without an argument, launch Atom
 498 
 499- * If `at` is passed a directory, `cd` to it and open it in Atom
 500+ * If `at` is passed a directory, open it in Atom
 501 
 502  * If `at` is passed a file, open it in Atom
 503 
 504- * if `att` command is called, it is equivalent to `at .`, opening the current folder in Atom
 505+### Examples
 506+
 507+ * Open the current dir in atom: `at .`
 508+ * Open another dir in atom: `at path/to/folder`
 509+ * Open a file: `at filename.extension`
 510diff --git a/plugins/atom/atom.plugin.zsh b/plugins/atom/atom.plugin.zsh
 511index 9adb9031a0e9c61c113a0e210531f5f3fdc5f4e2..ec1a114edeb67221e0f203646fb0daf30fabbe07 100644
 512--- a/plugins/atom/atom.plugin.zsh
 513+++ b/plugins/atom/atom.plugin.zsh
 514@@ -1,14 +1,22 @@
 515-local _atom_paths > /dev/null 2>&1
 516-_atom_paths=(
 517-    "$HOME/Applications/Atom.app"
 518-    "/Applications/Atom.app"
 519-)
 520+# Gets OS Type
 521+unamestr=$(uname -s)
 522 
 523-for _atom_path in $_atom_paths; do
 524-    if [[ -a $_atom_path ]]; then
 525-        alias at="open -a '$_atom_path'"
 526-        break
 527-    fi
 528-done
 529+# If OSX
 530+if [[ "$unamestr" == 'Darwin' ]]; then
 531+    local _atom_paths > /dev/null 2>&1
 532+    _atom_paths=(
 533+        "$HOME/Applications/Atom.app"
 534+        "/Applications/Atom.app"
 535+    )
 536 
 537-alias att='at .'
 538+    for _atom_path in $_atom_paths; do
 539+        if [[ -a $_atom_path ]]; then
 540+            alias at="open -a '$_atom_path'"
 541+            break
 542+        fi
 543+    done
 544+# If Linux
 545+elif [[ "$unamestr" == 'Linux' ]]; then
 546+    # Alerts the user if 'atom' is not a found command.
 547+    type atom >/dev/null 2>&1 && alias at="atom" || { echo >&2 "You have enabled the atom oh-my-zsh plugin on Linux, but atom is not a recognized command. Please make sure you have it installed before using this plugin."; }
 548+fi
 549diff --git a/plugins/autojump/autojump.plugin.zsh b/plugins/autojump/autojump.plugin.zsh
 550index 4cf0364013b2655dac01bf250d063ff2d7b2d1b5..c05c699e106b56ec04278d4cd84d7a4176fd9c35 100644
 551--- a/plugins/autojump/autojump.plugin.zsh
 552+++ b/plugins/autojump/autojump.plugin.zsh
 553@@ -15,7 +15,7 @@ if [ $commands[autojump] ]; then # check if autojump is installed
 554     . /usr/local/share/autojump/autojump.zsh
 555   elif [ -f /opt/local/etc/profile.d/autojump.zsh ]; then # mac os x with ports
 556     . /opt/local/etc/profile.d/autojump.zsh
 557-  elif [ $commands[brew] -a -f `brew --prefix`/etc/autojump.zsh ]; then # mac os x with brew
 558-    . `brew --prefix`/etc/autojump.zsh
 559+  elif [ $commands[brew] -a -f `brew --prefix`/etc/autojump.sh ]; then # mac os x with brew
 560+    . `brew --prefix`/etc/autojump.sh
 561   fi
 562 fi
 563diff --git a/plugins/aws/aws.plugin.zsh b/plugins/aws/aws.plugin.zsh
 564index 7246db9f0e10252a2c9bee1cff624e0b76ebc6c9..d31052f8300082f0d7ed5a47e59a2cf1454288d0 100644
 565--- a/plugins/aws/aws.plugin.zsh
 566+++ b/plugins/aws/aws.plugin.zsh
 567@@ -11,11 +11,16 @@ export AWS_HOME=~/.aws
 568 function agp {
 569   echo $AWS_DEFAULT_PROFILE
 570 }
 571+
 572 function asp {
 573+  local rprompt=${RPROMPT/<aws:$(agp)>/}
 574+
 575   export AWS_DEFAULT_PROFILE=$1
 576   export AWS_PROFILE=$1
 577-  export RPROMPT="<aws:$AWS_DEFAULT_PROFILE>$RPROMPT"
 578+
 579+  export RPROMPT="<aws:$AWS_DEFAULT_PROFILE>$rprompt"
 580 }
 581+
 582 function aws_profiles {
 583   reply=($(grep profile $AWS_HOME/config|sed -e 's/.*profile \([a-zA-Z0-9_-]*\).*/\1/'))
 584 }
 585diff --git a/plugins/bgnotify/bgnotify.plugin.zsh b/plugins/bgnotify/bgnotify.plugin.zsh
 586index b70b42f984540b2d58e9a6720e57234ec5ae21d6..459f5214e62c07d62d65dbd98901ea2c4dc82bcc 100755
 587--- a/plugins/bgnotify/bgnotify.plugin.zsh
 588+++ b/plugins/bgnotify/bgnotify.plugin.zsh
 589@@ -11,31 +11,38 @@ autoload -Uz add-zsh-hook || { print "can't add zsh hook!"; return }
 590 
 591 ## definitions ##
 592 
 593-if ! (type bgnotify_formatted | grep -q 'function'); then
 594-  function bgnotify_formatted {
 595-    ## exit_status, command, elapsed_time
 596-    [ $1 -eq 0 ] && title="#win (took $3 s)" || title="#fail (took $3 s)"
 597-    bgnotify "$title" "$2"
 598+if ! (type bgnotify_formatted | grep -q 'function'); then ## allow custom function override
 599+  function bgnotify_formatted { ## args: (exit_status, command, elapsed_seconds)
 600+    elapsed="$(( $3 % 60 ))s"
 601+    (( $3 >= 60 )) && elapsed="$((( $3 % 3600) / 60 ))m $elapsed"
 602+    (( $3 >= 3600 )) && elapsed="$(( $3 / 3600 ))h $elapsed"
 603+    [ $1 -eq 0 ] && bgnotify "#win (took $elapsed)" "$2" || bgnotify "#fail (took $elapsed)" "$2"
 604   }
 605 fi
 606 
 607 currentWindowId () {
 608   if hash osascript 2>/dev/null; then #osx
 609     osascript -e 'tell application (path to frontmost application as text) to id of front window' 2&> /dev/null || echo "0"
 610-  elif hash notify-send 2>/dev/null; then #ubuntu!
 611-    xprop -root | awk '/NET_ACTIVE_WINDOW/ { print $5; exit }'
 612+  elif (hash notify-send 2>/dev/null || hash kdialog 2>/dev/null); then #ubuntu!
 613+    xprop -root 2> /dev/null | awk '/NET_ACTIVE_WINDOW/{print $5;exit} END{exit !$5}' || echo "0"
 614   else
 615     echo $EPOCHSECONDS #fallback for windows
 616   fi
 617 }
 618 
 619-bgnotify () {
 620+bgnotify () { ## args: (title, subtitle)
 621   if hash terminal-notifier 2>/dev/null; then #osx
 622-    terminal-notifier -message "$2" -title "$1"
 623+    [[ "$TERM_PROGRAM" == 'iTerm.app' ]] && term_id='com.googlecode.iterm2';
 624+    [[ "$TERM_PROGRAM" == 'Apple_Terminal' ]] && term_id='com.apple.terminal';
 625+    ## now call terminal-notifier, (hopefully with $term_id!)
 626+    [ -z "$term_id" ] && terminal-notifier -message "$2" -title "$1" >/dev/null ||
 627+    terminal-notifier -message "$2" -title "$1" -activate "$term_id" -sender "$term_id" >/dev/null
 628   elif hash growlnotify 2>/dev/null; then #osx growl
 629     growlnotify -m "$1" "$2"
 630-  elif hash notify-send 2>/dev/null; then #ubuntu!
 631+  elif hash notify-send 2>/dev/null; then #ubuntu gnome!
 632     notify-send "$1" "$2"
 633+  elif hash kdialog 2>/dev/null; then #ubuntu kde!
 634+    kdialog  -title "$1" --passivepopup  "$2" 5
 635   elif hash notifu 2>/dev/null; then #cygwyn support!
 636     notifu /m "$2" /p "$1"
 637   fi
 638@@ -46,7 +53,7 @@ bgnotify () {
 639 
 640 bgnotify_begin() {
 641   bgnotify_timestamp=$EPOCHSECONDS
 642-  bgnotify_lastcmd=$1
 643+  bgnotify_lastcmd="$1"
 644   bgnotify_windowid=$(currentWindowId)
 645 }
 646 
 647@@ -63,5 +70,8 @@ bgnotify_end() {
 648   bgnotify_timestamp=0 #reset it to 0!
 649 }
 650 
 651-add-zsh-hook preexec bgnotify_begin
 652-add-zsh-hook precmd bgnotify_end
 653+## only enable if a local (non-ssh) connection
 654+if [ -z "$SSH_CLIENT" ] && [ -z "$SSH_TTY" ]; then
 655+  add-zsh-hook preexec bgnotify_begin
 656+  add-zsh-hook precmd bgnotify_end
 657+fi
 658diff --git a/plugins/capistrano/_capistrano b/plugins/capistrano/_capistrano
 659index 3cadf3d54be8aabaacaf509d5ca75ab14eb97910..e6e71ffcc80d121d3adba7bde7f461bafcaa26b3 100644
 660--- a/plugins/capistrano/_capistrano
 661+++ b/plugins/capistrano/_capistrano
 662@@ -1,10 +1,49 @@
 663-#compdef cap
 664+#compdef shipit
 665 #autoload
 666 
 667-if [[ -f config/deploy.rb || -f Capfile ]]; then
 668-  if [[ ! -f .cap_tasks~ || config/deploy.rb -nt .cap_tasks~ ]]; then
 669-    echo "\nGenerating .cap_tasks~..." > /dev/stderr
 670-    cap -v --tasks | grep '#' | cut -d " " -f 2 > .cap_tasks~
 671+# Added `shipit` because `cap` is a reserved word. `cap` completion doesn't work.
 672+# http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcap-Module
 673+
 674+local curcontext="$curcontext" state line ret=1
 675+local -a _configs
 676+
 677+_arguments -C \
 678+  '1: :->cmds' \
 679+  '2:: :->args' && ret=0
 680+
 681+_cap_tasks() {
 682+  if [[ -f config/deploy.rb || -f Capfile ]]; then
 683+    if [[ ! -f .cap_tasks~ ]]; then
 684+      shipit -v --tasks | sed 's/\(\[\)\(.*\)\(\]\)/\2:/' | awk '{command=$2; $1=$2=$3=""; gsub(/^[ \t\r\n]+/, "", $0); gsub(":", "\\:", command); print command"["$0"]"}' > .cap_tasks~
 685+    fi
 686+
 687+    OLD_IFS=$IFS
 688+    IFS=$'\n'
 689+    _values 'cap commands' $(< .cap_tasks~)
 690+    IFS=$OLD_IFS
 691+    # zmodload zsh/mapfile
 692+    # _values ${(f)mapfile[.cap_tasks~]}
 693   fi
 694-  compadd `cat .cap_tasks~`
 695-fi
 696+}
 697+
 698+_cap_stages() {
 699+  compadd $(find config/deploy -name \*.rb | cut -d/ -f3 | sed s:.rb::g)
 700+}
 701+
 702+case $state in
 703+  cmds)
 704+    # check if it uses multistage
 705+    if [[ -d config/deploy ]]; then
 706+      _cap_stages
 707+    else
 708+      _cap_tasks
 709+    fi
 710+    ret=0
 711+    ;;
 712+  args)
 713+    _cap_tasks
 714+    ret=0
 715+    ;;
 716+esac
 717+
 718+return ret
 719diff --git a/plugins/capistrano/capistrano.plugin.zsh b/plugins/capistrano/capistrano.plugin.zsh
 720new file mode 100644
 721index 0000000000000000000000000000000000000000..c85eb474ca8a9cd85f8f3cc4446e54ce5a5a0c85
 722--- /dev/null
 723+++ b/plugins/capistrano/capistrano.plugin.zsh
 724@@ -0,0 +1,11 @@
 725+# Added `shipit` because `cap` is a reserved word. `cap` completion doesn't work.
 726+# http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcap-Module
 727+
 728+func shipit() {
 729+  if [ -f Gemfile ]
 730+  then
 731+    bundle exec cap $*
 732+  else
 733+    cap $*
 734+  fi
 735+}
 736diff --git a/plugins/chruby/chruby.plugin.zsh b/plugins/chruby/chruby.plugin.zsh
 737index b461b0c9be7d5b39a27ebc7d646e93434e57e15a..5be6528b0edbcf818ca8ccd52d6cc7a619de7079 100644
 738--- a/plugins/chruby/chruby.plugin.zsh
 739+++ b/plugins/chruby/chruby.plugin.zsh
 740@@ -45,11 +45,11 @@ _source_from_omz_settings() {
 741     zstyle -s :omz:plugins:chruby path _chruby_path
 742     zstyle -s :omz:plugins:chruby auto _chruby_auto
 743 
 744-    if ${_chruby_path} && [[ -r ${_chruby_path} ]]; then
 745+    if [[ -r ${_chruby_path} ]]; then
 746         source ${_chruby_path}
 747     fi
 748 
 749-    if ${_chruby_auto} && [[ -r ${_chruby_auto} ]]; then
 750+    if [[ -r ${_chruby_auto} ]]; then
 751         source ${_chruby_auto}
 752     fi
 753 }
 754diff --git a/plugins/codeclimate/_codeclimate b/plugins/codeclimate/_codeclimate
 755new file mode 100644
 756index 0000000000000000000000000000000000000000..fd2536a340d632108c3f04bdd130052445c8d02d
 757--- /dev/null
 758+++ b/plugins/codeclimate/_codeclimate
 759@@ -0,0 +1,82 @@
 760+#compdef codeclimate
 761+
 762+_codeclimate_all_engines() {
 763+  engines_all=(`codeclimate engines:list | tail -n +2 | gawk '{ print $2 }' | gawk -F: '{ print $1 }'`)
 764+}
 765+
 766+_codeclimate_installed_engines() {
 767+  _codeclimate_all_engines
 768+
 769+  engines_installed=()
 770+
 771+  if [ -e .codeclimate.yml ]
 772+  then
 773+    for engine in $engines_all
 774+    do
 775+      if grep -q $engine ".codeclimate.yml"
 776+      then
 777+        engines_installed+=$engine
 778+      fi
 779+    done
 780+  fi
 781+}
 782+
 783+_codeclimate_not_installed_engines() {
 784+  _codeclimate_all_engines
 785+
 786+  engines_not_installed=()
 787+
 788+  if [ -e .codeclimate.yml ]
 789+  then
 790+    for engine in $engines_all
 791+    do
 792+      if ! grep -q $engine ".codeclimate.yml"
 793+      then
 794+        engines_not_installed+=$engine
 795+      fi
 796+    done
 797+  fi
 798+}
 799+
 800+local curcontext="$curcontext" state line ret=1
 801+local expl
 802+local -a engines_all engines_installed engines_not_installed
 803+
 804+_arguments \
 805+  '1: :->cmds' \
 806+  '*:: :->args' && ret=0
 807+
 808+case $state in
 809+  cmds)
 810+    _values "bundle command" \
 811+      "analyze[Analyze all relevant files in the current working directory]" \
 812+      "console[Start an interactive session providing access to the classes within the CLI]" \
 813+      "engines\:disable[Prevents the engine from being used in this project]" \
 814+      "engines\:enable[This engine will be run the next time your project is analyzed]" \
 815+      "engines\:install[Compares the list of engines in your .codeclimate.yml file to those that are currently installed, then installs any missing engines]" \
 816+      "engines\:list[Lists all available engines in the Code Climate Docker Hub]" \
 817+      "engines\:remove[Removes an engine from your .codeclimate.yml file]" \
 818+      "help[Displays a list of commands that can be passed to the Code Climate CLI]" \
 819+      "init[Generates a new .codeclimate.yml file in the current working directory]" \
 820+      "validate-config[Validates the .codeclimate.yml file in the current working directory]" \
 821+      "version[Displays the current version of the Code Climate CLI]"
 822+    ret=0
 823+    ;;
 824+  args)
 825+    case $line[1] in
 826+      engines:enable)
 827+        _codeclimate_not_installed_engines
 828+        _wanted engines_not_installed expl 'not installed engines' compadd -a engines_not_installed ;;
 829+      engines:disable|engines:remove)
 830+        _codeclimate_installed_engines
 831+        _wanted engines_installed expl 'installed engines' compadd -a engines_installed ;;
 832+      analyze)
 833+        _arguments \
 834+          '-f:Output Format:(text json)'
 835+        ret=0
 836+        ;;
 837+    esac
 838+    ;;
 839+esac
 840+
 841+return ret
 842diff --git a/plugins/coffee/coffee.plugin.zsh b/plugins/coffee/coffee.plugin.zsh
 843index 1a7bedd87fe9426f18c00e9f99bbc269a194406d..4e98e022869ea8b968ab4f3598f904bb51ff27d8 100644
 844--- a/plugins/coffee/coffee.plugin.zsh
 845+++ b/plugins/coffee/coffee.plugin.zsh
 846@@ -2,11 +2,11 @@
 847 
 848 # compile a string of coffeescript and print to output
 849 cf () {
 850-  coffee -peb $1
 851+  coffee -peb "$1"
 852 }
 853 # compile & copy to clipboard
 854 cfc () {
 855-  cf $1 | pbcopy
 856+  cf "$1" | pbcopy
 857 }
 858 
 859 # compile from pasteboard & print
 860diff --git a/plugins/dirhistory/dirhistory.plugin.zsh b/plugins/dirhistory/dirhistory.plugin.zsh
 861index d101cfcae6a435ac0d78398f23cb1aac809a0efc..0209981e31f463a30cc6d65f0b58c5d19c280c34 100644
 862--- a/plugins/dirhistory/dirhistory.plugin.zsh
 863+++ b/plugins/dirhistory/dirhistory.plugin.zsh
 864@@ -49,7 +49,8 @@ function push_future() {
 865 }
 866 
 867 # Called by zsh when directory changes
 868-function chpwd() {
 869+chpwd_functions+=(chpwd_dirhistory)
 870+function chpwd_dirhistory() {
 871   push_past $PWD
 872   # If DIRHISTORY_CD is not set...
 873   if [[ -z "${DIRHISTORY_CD+x}" ]]; then
 874diff --git a/plugins/dirpersist/dirpersist.plugin.zsh b/plugins/dirpersist/dirpersist.plugin.zsh
 875index 88d1129d4ac9a21a0a08f1a61f6531b84f320c34..616e2c3c658710d47073cfdd88aa43aea3782675 100644
 876--- a/plugins/dirpersist/dirpersist.plugin.zsh
 877+++ b/plugins/dirpersist/dirpersist.plugin.zsh
 878@@ -11,7 +11,8 @@ if [[ -f ${dirstack_file} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
 879   [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD
 880 fi
 881 
 882-chpwd() {
 883+chpwd_functions+=(chpwd_dirpersist)
 884+chpwd_dirpersist() {
 885   if (( $DIRSTACKSIZE <= 0 )) || [[ -z $dirstack_file ]]; then return; fi
 886   local -ax my_stack
 887   my_stack=( ${PWD} ${dirstack} )
 888diff --git a/plugins/docker-compose/README.md b/plugins/docker-compose/README.md
 889index 77b98f30df1ff85b1bebf4ed213548408f26fddb..567b821487af846fa41948fea666f7de6280954f 100644
 890--- a/plugins/docker-compose/README.md
 891+++ b/plugins/docker-compose/README.md
 892@@ -1 +1,5 @@
 893 # Docker-compose plugin for oh my zsh
 894+
 895+A copy of the completion script from the [docker-compose](1) git repo.
 896+
 897+[1]:[https://github.com/docker/compose/blob/master/contrib/completion/zsh/_docker-compose]
 898diff --git a/plugins/docker-compose/_docker-compose b/plugins/docker-compose/_docker-compose
 899new file mode 100644
 900index 0000000000000000000000000000000000000000..19c06675ad5057dd09b3398e476744ac8fdd8b10
 901--- /dev/null
 902+++ b/plugins/docker-compose/_docker-compose
 903@@ -0,0 +1,308 @@
 904+#compdef docker-compose
 905+
 906+# Description
 907+# -----------
 908+#  zsh completion for docker-compose
 909+#  https://github.com/sdurrheimer/docker-compose-zsh-completion
 910+# -------------------------------------------------------------------------
 911+# Version
 912+# -------
 913+#  0.1.0
 914+# -------------------------------------------------------------------------
 915+# Authors
 916+# -------
 917+#  * Steve Durrheimer <s.durrheimer@gmail.com>
 918+# -------------------------------------------------------------------------
 919+# Inspiration
 920+# -----------
 921+#  * @albers docker-compose bash completion script
 922+#  * @felixr docker zsh completion script : https://github.com/felixr/docker-zsh-completion
 923+# -------------------------------------------------------------------------
 924+
 925+# For compatibility reasons, Compose and therefore its completion supports several
 926+# stack compositon files as listed here, in descending priority.
 927+# Support for these filenames might be dropped in some future version.
 928+__docker-compose_compose_file() {
 929+    local file
 930+    for file in docker-compose.y{,a}ml fig.y{,a}ml ; do
 931+        [ -e $file ] && {
 932+            echo $file
 933+            return
 934+        }
 935+    done
 936+    echo docker-compose.yml
 937+}
 938+
 939+# Extracts all service names from docker-compose.yml.
 940+___docker-compose_all_services_in_compose_file() {
 941+    local already_selected
 942+    local -a services
 943+    already_selected=$(echo ${words[@]} | tr " " "|")
 944+    awk -F: '/^[a-zA-Z0-9]/{print $1}' "${compose_file:-$(__docker-compose_compose_file)}" 2>/dev/null | grep -Ev "$already_selected"
 945+}
 946+
 947+# All services, even those without an existing container
 948+__docker-compose_services_all() {
 949+    services=$(___docker-compose_all_services_in_compose_file)
 950+    _alternative "args:services:($services)"
 951+}
 952+
 953+# All services that have an entry with the given key in their docker-compose.yml section
 954+___docker-compose_services_with_key() {
 955+    local already_selected
 956+    local -a buildable
 957+    already_selected=$(echo ${words[@]} | tr " " "|")
 958+    # flatten sections to one line, then filter lines containing the key and return section name.
 959+    awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' "${compose_file:-$(__docker-compose_compose_file)}" 2>/dev/null | awk -F: -v key=": +$1:" '$0 ~ key {print $1}' 2>/dev/null | grep -Ev "$already_selected"
 960+}
 961+
 962+# All services that are defined by a Dockerfile reference
 963+__docker-compose_services_from_build() {
 964+    buildable=$(___docker-compose_services_with_key build)
 965+    _alternative "args:buildable services:($buildable)"
 966+}
 967+
 968+# All services that are defined by an image
 969+__docker-compose_services_from_image() {
 970+    pullable=$(___docker-compose_services_with_key image)
 971+    _alternative "args:pullable services:($pullable)"
 972+}
 973+
 974+__docker-compose_get_services() {
 975+    local kind expl
 976+    declare -a running stopped lines args services
 977+
 978+    docker_status=$(docker ps > /dev/null 2>&1)
 979+    if [ $? -ne 0 ]; then
 980+        _message "Error! Docker is not running."
 981+        return 1
 982+    fi
 983+
 984+    kind=$1
 985+    shift
 986+    [[ $kind = (stopped|all) ]] && args=($args -a)
 987+
 988+    lines=(${(f)"$(_call_program commands docker ps ${args})"})
 989+    services=(${(f)"$(_call_program commands docker-compose 2>/dev/null ${compose_file:+-f $compose_file} ${compose_project:+-p $compose_project} ps -q)"})
 990+
 991+    # Parse header line to find columns
 992+    local i=1 j=1 k header=${lines[1]}
 993+    declare -A begin end
 994+    while (( $j < ${#header} - 1 )) {
 995+        i=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 1))
 996+        j=$(( $i + ${${header[$i,-1]}[(i)  ]} - 1))
 997+        k=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 2))
 998+        begin[${header[$i,$(($j-1))]}]=$i
 999+        end[${header[$i,$(($j-1))]}]=$k
1000+    }
1001+    lines=(${lines[2,-1]})
1002+
1003diff --git a/plugins/docker-compose/docker-compose.plugin.zsh b/plugins/docker-compose/docker-compose.plugin.zsh
1004deleted file mode 100644
1005index 08500408d7a309a116bd8064c829f8fbaea59722..0000000000000000000000000000000000000000
1006--- a/plugins/docker-compose/docker-compose.plugin.zsh
1007+++ /dev/null
1008@@ -1,14 +0,0 @@
1009-# Authors:
1010-# https://github.com/tristola
1011-#
1012-# Docker-compose related zsh aliases
1013-
1014-# Aliases ###################################################################
1015-
1016-alias dcup='docker-compose up'
1017-alias dcb='docker-compose build'
1018-alias dcrm='docker-compose rm'
1019-alias dcps='docker-compose ps'
1020-alias dcstop='docker-compose stop'
1021-alias dcrestart='docker-compose restart'
1022-
1023diff --git a/plugins/docker/_docker b/plugins/docker/_docker
1024index 25f55beca384ecdd3d4b9c970a322676e9e4599c..a82a31ad3441f78d1b79aca8220728b01fe86ff1 100644
1025--- a/plugins/docker/_docker
1026+++ b/plugins/docker/_docker
1027@@ -27,7 +27,7 @@ __docker_all_containers() {
1028 # output a selectable list of all docker images
1029 __docker_images() {
1030     declare -a img_cmd
1031-    img_cmd=($(docker images | awk 'NR>1{print $1}'))
1032+    img_cmd=($(docker images | awk 'NR>1{print $1}'| sed 's/:/\\:/g'))
1033     _describe 'images' img_cmd
1034 }
1035 
1036diff --git a/plugins/ember-cli/README.md b/plugins/ember-cli/README.md
1037index f5eca1ad08c910e801bd8568d220716c81d5b4c4..1f92bba32cfd7fd1915c3455e7b1a79467cb5d6d 100644
1038--- a/plugins/ember-cli/README.md
1039+++ b/plugins/ember-cli/README.md
1040@@ -1,8 +1,8 @@
1041-# Ember-cli
1042+# Ember CLI
1043 
1044-**Maintainer:**[BilalBudhani](http://www.github.com/BilalBudhani)
1045+**Maintainers:** [BilalBudhani](http://www.github.com/BilalBudhani), [eubenesa](http://www.github.com/eubenesa)
1046 
1047-Ember-cli (http://www.ember-cli.com/)
1048+Ember CLI (http://www.ember-cli.com/)
1049 
1050 ### List of Aliases
1051 
1052@@ -15,9 +15,6 @@ Alias | Ember-CLI command
1053 **eg** | *ember generate*
1054 **eh** | *ember help*
1055 **ein** | *ember init*
1056-**eia** | *ember install:addon*
1057-**eib** | *ember install:bower*
1058-**ein** | *ember install:npm*
1059 **ei** | *ember install*
1060 **et** | *ember test*
1061 **eu** | *ember update*
1062diff --git a/plugins/ember-cli/ember-cli.plugin.zsh b/plugins/ember-cli/ember-cli.plugin.zsh
1063index 044a2c0438896a51e05d8dc4015e72db555442f0..a0f3468299e8587435bef1d63ff13ba02d33423e 100644
1064--- a/plugins/ember-cli/ember-cli.plugin.zsh
1065+++ b/plugins/ember-cli/ember-cli.plugin.zsh
1066@@ -1,5 +1,5 @@
1067-# Ember ClI 
1068-# visit http://www.ember-cli.com/ to view user guid 
1069+# Ember CLI
1070+# Visit http://www.ember-cli.com/ to view user guide
1071 
1072 alias es='ember serve'
1073 alias ea='ember addon'
1074@@ -8,9 +8,6 @@ alias ed='ember destroy'
1075 alias eg='ember generate'
1076 alias eh='ember help'
1077 alias ein='ember init'
1078-alias eia='ember install:addon'
1079-alias eib='ember install:bower'
1080-alias ein='ember install:npm'
1081 alias ei='ember install'
1082 alias et='ember test'
1083 alias eu='ember update'
1084diff --git a/plugins/emoji/README.md b/plugins/emoji/README.md
1085new file mode 100644
1086index 0000000000000000000000000000000000000000..889e567e6ce8e3689fa57a517fd74ab8bc8732e6
1087--- /dev/null
1088+++ b/plugins/emoji/README.md
1089@@ -0,0 +1,135 @@
1090+# emoji plugin
1091+
1092+Support for conveniently working with Unicode emoji in Zsh.
1093+
1094+## Features
1095+
1096diff --git a/plugins/emoji/emoji-char-definitions.zsh b/plugins/emoji/emoji-char-definitions.zsh
1097new file mode 100644
1098index 0000000000000000000000000000000000000000..04693da0593b98620161e2d52aaeba3115d953c9
1099--- /dev/null
1100+++ b/plugins/emoji/emoji-char-definitions.zsh
1101@@ -0,0 +1,1303 @@
1102+
1103+# emoji-char-definitions.zsh - Emoji character definitions for oh-my-zsh emoji plugin
1104+#
1105+# This file is auto-generated by update_emoji.pl. Do not edit it manually.
1106+#
1107+# This contains the definition for:
1108+#   $emoji         - which maps character names to Unicode characters
1109+#   $emoji_flags   - maps country names to Unicode flag characters using region indicators 
1110+
1111+# Main emoji
1112+typeset -gAH emoji
1113+# National flags
1114+typeset -gAH emoji_flags
1115+# Combining modifiers
1116+typeset -gAH emoji_mod
1117+
1118+emoji[copyright_sign]=$'\U00A9'
1119+emoji[registered_sign]=$'\U00AE'
1120+emoji[double_exclamation_mark]=$'\U203C'
1121+emoji[exclamation_question_mark]=$'\U2049'
1122+emoji[trade_mark_sign]=$'\U2122'
1123+emoji[information_source]=$'\U2139'
1124+emoji[left_right_arrow]=$'\U2194'
1125+emoji[up_down_arrow]=$'\U2195'
1126+emoji[north_west_arrow]=$'\U2196'
1127+emoji[north_east_arrow]=$'\U2197'
1128+emoji[south_east_arrow]=$'\U2198'
1129+emoji[south_west_arrow]=$'\U2199'
1130+emoji[leftwards_arrow_with_hook]=$'\U21A9'
1131+emoji[rightwards_arrow_with_hook]=$'\U21AA'
1132+emoji[watch]=$'\U231A'
1133+emoji[hourglass]=$'\U231B'
1134+emoji[keyboard]=$'\U2328'
1135+emoji[eject_symbol]=$'\U23CF'
1136+emoji[black_right_pointing_double_triangle]=$'\U23E9'
1137+emoji[black_left_pointing_double_triangle]=$'\U23EA'
1138+emoji[black_up_pointing_double_triangle]=$'\U23EB'
1139+emoji[black_down_pointing_double_triangle]=$'\U23EC'
1140+emoji[black_right_pointing_double_triangle_with_vertical_bar]=$'\U23ED'
1141+emoji[black_left_pointing_double_triangle_with_vertical_bar]=$'\U23EE'
1142+emoji[black_right_pointing_triangle_with_double_vertical_bar]=$'\U23EF'
1143+emoji[alarm_clock]=$'\U23F0'
1144+emoji[stopwatch]=$'\U23F1'
1145+emoji[timer_clock]=$'\U23F2'
1146+emoji[hourglass_with_flowing_sand]=$'\U23F3'
1147+emoji[double_vertical_bar]=$'\U23F8'
1148+emoji[black_square_for_stop]=$'\U23F9'
1149+emoji[black_circle_for_record]=$'\U23FA'
1150+emoji[circled_latin_capital_letter_m]=$'\U24C2'
1151+emoji[black_small_square]=$'\U25AA'
1152+emoji[white_small_square]=$'\U25AB'
1153+emoji[black_right_pointing_triangle]=$'\U25B6'
1154+emoji[black_left_pointing_triangle]=$'\U25C0'
1155+emoji[white_medium_square]=$'\U25FB'
1156+emoji[black_medium_square]=$'\U25FC'
1157+emoji[white_medium_small_square]=$'\U25FD'
1158+emoji[black_medium_small_square]=$'\U25FE'
1159+emoji[black_sun_with_rays]=$'\U2600'
1160+emoji[cloud]=$'\U2601'
1161+emoji[umbrella]=$'\U2602'
1162+emoji[snowman]=$'\U2603'
1163+emoji[comet]=$'\U2604'
1164+emoji[black_telephone]=$'\U260E'
1165+emoji[ballot_box_with_check]=$'\U2611'
1166+emoji[umbrella_with_rain_drops]=$'\U2614'
1167+emoji[hot_beverage]=$'\U2615'
1168+emoji[shamrock]=$'\U2618'
1169+emoji[white_up_pointing_index]=$'\U261D'
1170+emoji[skull_and_crossbones]=$'\U2620'
1171+emoji[radioactive_sign]=$'\U2622'
1172+emoji[biohazard_sign]=$'\U2623'
1173+emoji[orthodox_cross]=$'\U2626'
1174+emoji[star_and_crescent]=$'\U262A'
1175+emoji[peace_symbol]=$'\U262E'
1176+emoji[yin_yang]=$'\U262F'
1177+emoji[wheel_of_dharma]=$'\U2638'
1178+emoji[white_frowning_face]=$'\U2639'
1179+emoji[white_smiling_face]=$'\U263A'
1180+emoji[aries]=$'\U2648'
1181+emoji[taurus]=$'\U2649'
1182+emoji[gemini]=$'\U264A'
1183+emoji[cancer]=$'\U264B'
1184+emoji[leo]=$'\U264C'
1185+emoji[virgo]=$'\U264D'
1186+emoji[libra]=$'\U264E'
1187+emoji[scorpius]=$'\U264F'
1188+emoji[sagittarius]=$'\U2650'
1189+emoji[capricorn]=$'\U2651'
1190+emoji[aquarius]=$'\U2652'
1191+emoji[pisces]=$'\U2653'
1192+emoji[black_spade_suit]=$'\U2660'
1193+emoji[black_club_suit]=$'\U2663'
1194+emoji[black_heart_suit]=$'\U2665'
1195+emoji[black_diamond_suit]=$'\U2666'
1196+emoji[hot_springs]=$'\U2668'
1197+emoji[black_universal_recycling_symbol]=$'\U267B'
1198+emoji[wheelchair_symbol]=$'\U267F'
1199+emoji[hammer_and_pick]=$'\U2692'
1200+emoji[anchor]=$'\U2693'
1201diff --git a/plugins/emoji/emoji-data.txt b/plugins/emoji/emoji-data.txt
1202new file mode 100644
1203index 0000000000000000000000000000000000000000..7b4c015f7afb8ccd82f9b027da43df8c7a8e1ba7
1204--- /dev/null
1205+++ b/plugins/emoji/emoji-data.txt
1206@@ -0,0 +1,1308 @@
1207+# DRAFT emoji-data.txt
1208+# For details about the format and other information, see /../../../reports/tr51/index.html#Data_Files.
1209+#
1210+# Format: Code ; Default_Emoji_Style ; Emoji_Level ; Emoji_Modifier_Status ; Emoji_Sources # Comment
1211+#
1212+#   Field 1 — Default_Emoji_Style:
1213+#             text:      default text presentation
1214+#             emoji:     default emoji presentation
1215+#   Field 2 — Emoji_Level:
1216+#             L1:        level 1 emoji
1217+#             L2:        level 2 emoji
1218+#             NA:        not applicable
1219+#   Field 3 — Emoji_Modifier_Status:
1220+#             modifier:  an emoji modifier
1221+#             primary:   a primary emoji modifier base
1222+#             secondary: a secondary emoji modifier base
1223+#             none:      not applicable
1224+#   Field 4 — Emoji_Sources:
1225+#             one or more values from {z, a, j, w, x}
1226+#             see the key in http://www.unicode.org/draft/reports/tr51/tr51.html#Major_Sources
1227+#             NA:        not applicable
1228+#   Comment — currently contains the version where the character was first encoded,
1229+#             followed by:
1230+#             - a character name in uppercase (for a single character),
1231+#             - a keycap name,
1232+#             - an associated flag, where is associated with value unicode region code
1233+#
1234+00A9 ;	text ;	L1 ;	none ;	j	# V1.1 (©) COPYRIGHT SIGN
1235+00AE ;	text ;	L1 ;	none ;	j	# V1.1 (®) REGISTERED SIGN
1236+203C ;	text ;	L1 ;	none ;	a j	# V1.1 (‼) DOUBLE EXCLAMATION MARK
1237+2049 ;	text ;	L1 ;	none ;	a j	# V3.0 (⁉) EXCLAMATION QUESTION MARK
1238+2122 ;	text ;	L1 ;	none ;	j	# V1.1 (™) TRADE MARK SIGN
1239+2139 ;	text ;	L1 ;	none ;	j	# V3.0 (ℹ) INFORMATION SOURCE
1240+2194 ;	text ;	L1 ;	none ;	z j	# V1.1 (↔) LEFT RIGHT ARROW
1241+2195 ;	text ;	L1 ;	none ;	z j	# V1.1 (↕) UP DOWN ARROW
1242+2196 ;	text ;	L1 ;	none ;	j	# V1.1 (↖) NORTH WEST ARROW
1243+2197 ;	text ;	L1 ;	none ;	j	# V1.1 (↗) NORTH EAST ARROW
1244+2198 ;	text ;	L1 ;	none ;	j	# V1.1 (↘) SOUTH EAST ARROW
1245+2199 ;	text ;	L1 ;	none ;	j	# V1.1 (↙) SOUTH WEST ARROW
1246+21A9 ;	text ;	L1 ;	none ;	j	# V1.1 (↩) LEFTWARDS ARROW WITH HOOK
1247+21AA ;	text ;	L1 ;	none ;	j	# V1.1 (↪) RIGHTWARDS ARROW WITH HOOK
1248+231A ;	emoji ;	L1 ;	none ;	j	# V1.1 (⌚) WATCH
1249+231B ;	emoji ;	L1 ;	none ;	j	# V1.1 (⌛) HOURGLASS
1250+2328 ;	text ;	L2 ;	none ;	x	# V1.1 (⌨) KEYBOARD
1251+23CF ;	text ;	L2 ;	none ;	x	# V4.0 (⏏) EJECT SYMBOL
1252+23E9 ;	emoji ;	L1 ;	none ;	j w	# V6.0 (⏩) BLACK RIGHT-POINTING DOUBLE TRIANGLE
1253+23EA ;	emoji ;	L1 ;	none ;	j w	# V6.0 (⏪) BLACK LEFT-POINTING DOUBLE TRIANGLE
1254+23EB ;	emoji ;	L1 ;	none ;	j	# V6.0 (⏫) BLACK UP-POINTING DOUBLE TRIANGLE
1255+23EC ;	emoji ;	L1 ;	none ;	j	# V6.0 (⏬) BLACK DOWN-POINTING DOUBLE TRIANGLE
1256+23ED ;	text ;	L2 ;	none ;	w	# V6.0 (⏭) BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR
1257+23EE ;	text ;	L2 ;	none ;	w	# V6.0 (⏮) BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR
1258+23EF ;	text ;	L2 ;	none ;	x	# V6.0 (⏯) BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR
1259+23F0 ;	emoji ;	L1 ;	none ;	j	# V6.0 (⏰) ALARM CLOCK
1260+23F1 ;	text ;	L2 ;	none ;	x	# V6.0 (⏱) STOPWATCH
1261+23F2 ;	text ;	L2 ;	none ;	x	# V6.0 (⏲) TIMER CLOCK
1262+23F3 ;	emoji ;	L1 ;	none ;	j w	# V6.0 (⏳) HOURGLASS WITH FLOWING SAND
1263+23F8 ;	text ;	L2 ;	none ;	w	# V7.0 (⏸) DOUBLE VERTICAL BAR
1264+23F9 ;	text ;	L2 ;	none ;	w	# V7.0 (⏹) BLACK SQUARE FOR STOP
1265+23FA ;	text ;	L2 ;	none ;	w	# V7.0 (⏺) BLACK CIRCLE FOR RECORD
1266+24C2 ;	text ;	L1 ;	none ;	j	# V1.1 (Ⓜ) CIRCLED LATIN CAPITAL LETTER M
1267+25AA ;	text ;	L1 ;	none ;	j w	# V1.1 (▪) BLACK SMALL SQUARE
1268+25AB ;	text ;	L1 ;	none ;	j	# V1.1 (▫) WHITE SMALL SQUARE
1269+25B6 ;	text ;	L1 ;	none ;	a j w	# V1.1 (▶) BLACK RIGHT-POINTING TRIANGLE
1270+25C0 ;	text ;	L1 ;	none ;	a j w	# V1.1 (◀) BLACK LEFT-POINTING TRIANGLE
1271+25FB ;	text ;	L1 ;	none ;	j	# V3.2 (◻) WHITE MEDIUM SQUARE
1272+25FC ;	text ;	L1 ;	none ;	j w	# V3.2 (◼) BLACK MEDIUM SQUARE
1273+25FD ;	emoji ;	L1 ;	none ;	j	# V3.2 (◽) WHITE MEDIUM SMALL SQUARE
1274+25FE ;	emoji ;	L1 ;	none ;	j w	# V3.2 (◾) BLACK MEDIUM SMALL SQUARE
1275+2600 ;	text ;	L1 ;	none ;	a j	# V1.1 (☀) BLACK SUN WITH RAYS
1276+2601 ;	text ;	L1 ;	none ;	a j w	# V1.1 (☁) CLOUD
1277+2602 ;	text ;	L2 ;	none ;	a	# V1.1 (☂) UMBRELLA
1278+2603 ;	text ;	L2 ;	none ;	a	# V1.1 (☃) SNOWMAN
1279+2604 ;	text ;	L2 ;	none ;	x	# V1.1 (☄) COMET
1280+260E ;	text ;	L1 ;	none ;	z a j	# V1.1 (☎) BLACK TELEPHONE
1281+2611 ;	text ;	L1 ;	none ;	j w	# V1.1 (☑) BALLOT BOX WITH CHECK
1282+2614 ;	emoji ;	L1 ;	none ;	a j	# V4.0 (☔) UMBRELLA WITH RAIN DROPS
1283+2615 ;	emoji ;	L1 ;	none ;	j	# V4.0 (☕) HOT BEVERAGE
1284+2618 ;	text ;	L2 ;	none ;	x	# V4.1 (☘) SHAMROCK
1285+261D ;	text ;	L1 ;	secondary ;	j w	# V1.1 (☝) WHITE UP POINTING INDEX
1286+2620 ;	text ;	L2 ;	none ;	x	# V1.1 (☠) SKULL AND CROSSBONES
1287+2622 ;	text ;	L2 ;	none ;	x	# V1.1 (☢) RADIOACTIVE SIGN
1288+2623 ;	text ;	L2 ;	none ;	x	# V1.1 (☣) BIOHAZARD SIGN
1289+2626 ;	text ;	L2 ;	none ;	x	# V1.1 (☦) ORTHODOX CROSS
1290+262A ;	text ;	L2 ;	none ;	w	# V1.1 (☪) STAR AND CRESCENT
1291+262E ;	text ;	L2 ;	none ;	x	# V1.1 (☮) PEACE SYMBOL
1292+262F ;	text ;	L2 ;	none ;	w	# V1.1 (☯) YIN YANG
1293+2638 ;	text ;	L2 ;	none ;	w	# V1.1 (☸) WHEEL OF DHARMA
1294+2639 ;	text ;	L2 ;	secondary ;	w	# V1.1 (☹) WHITE FROWNING FACE
1295+263A ;	text ;	L1 ;	secondary ;	j w	# V1.1 (☺) WHITE SMILING FACE
1296+2648 ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♈) ARIES
1297+2649 ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♉) TAURUS
1298+264A ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♊) GEMINI
1299+264B ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♋) CANCER
1300+264C ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♌) LEO
1301+264D ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♍) VIRGO
1302+264E ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♎) LIBRA
1303+264F ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♏) SCORPIUS
1304+2650 ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♐) SAGITTARIUS
1305+2651 ;	emoji ;	L1 ;	none ;	j w	# V1.1 (♑) CAPRICORN
1306diff --git a/plugins/emoji/emoji.plugin.zsh b/plugins/emoji/emoji.plugin.zsh
1307new file mode 100644
1308index 0000000000000000000000000000000000000000..7876f1c89e5580d8b57bd1fd2d3ae756bba36c80
1309--- /dev/null
1310+++ b/plugins/emoji/emoji.plugin.zsh
1311@@ -0,0 +1,288 @@
1312+# emoji plugin
1313+#
1314+# Makes emoji support available within ZSH
1315+#
1316+# See the README for documentation.
1317+
1318+_omz_emoji_plugin_dir="${0:h}"
1319+
1320+() {
1321+
1322+local LC_ALL=en_US.UTF-8
1323+
1324+typeset -gAH emoji_groups
1325+typeset -gAH emoji_con
1326+typeset -gAH emoji2
1327+typeset -gAH emoji_skintone
1328+
1329+source "$_omz_emoji_plugin_dir/emoji-char-definitions.zsh"
1330+unset _omz_emoji_plugin_dir
1331+
1332+# These additional emoji are not in the definition file, but are useful in conjunction with it
1333+
1334+# This is a combinin character that can be placed after any other character to surround
1335+# it in a "keycap" symbol.
1336+# The digits 0-9 are already in the emoji table as keycap_digit_<N>, keycap_ten, etc. 
1337+# It's unclear whether this should be in the $emoji array, because those characters are all ones
1338+# which can be displayed on their own.
1339+#emoji[combining_enclosing_keycap]="\U20E3"
1340+
1341+emoji[regional_indicator_symbol_letter_d_regional_indicator_symbol_letter_e]=$'\xF0\x9F\x87\xA9\xF0\x9F\x87\xAA'
1342+emoji[regional_indicator_symbol_letter_g_regional_indicator_symbol_letter_b]=$'\xF0\x9F\x87\xAC\xF0\x9F\x87\xA7'
1343+emoji[regional_indicator_symbol_letter_c_regional_indicator_symbol_letter_n]=$'\xF0\x9F\x87\xA8\xF0\x9F\x87\xB3'
1344+emoji[regional_indicator_symbol_letter_j_regional_indicator_symbol_letter_p]=$'\xF0\x9F\x87\xAF\xF0\x9F\x87\xB5'
1345+emoji[regional_indicator_symbol_letter_k_regional_indicator_symbol_letter_r]=$'\xF0\x9F\x87\xB0\xF0\x9F\x87\xB7'
1346+emoji[regional_indicator_symbol_letter_f_regional_indicator_symbol_letter_r]=$'\xF0\x9F\x87\xAB\xF0\x9F\x87\xB7'
1347+emoji[regional_indicator_symbol_letter_e_regional_indicator_symbol_letter_s]=$'\xF0\x9F\x87\xAA\xF0\x9F\x87\xB8'
1348+emoji[regional_indicator_symbol_letter_i_regional_indicator_symbol_letter_t]=$'\xF0\x9F\x87\xAE\xF0\x9F\x87\xB9'
1349+emoji[regional_indicator_symbol_letter_u_regional_indicator_symbol_letter_s]=$'\xF0\x9F\x87\xBA\xF0\x9F\x87\xB8'
1350+emoji[regional_indicator_symbol_letter_r_regional_indicator_symbol_letter_u]=$'\xF0\x9F\x87\xB7\xF0\x9F\x87\xBA'
1351+
1352+# Nonstandard alias names
1353+emoji[vulcan_salute]=$'\U1F596'
1354+
1355+
1356+# Emoji combining and auxiliary characters
1357+
1358+# "Variation Selectors" for controlling text vs emoji style presentation
1359+# These apply to the immediately preceding character
1360+emoji2[text_style]=$'\UFE0E'
1361+emoji2[emoji_style]=$'\UFE0F'
1362+# Joiner that indicates a single combined-form glyph (ligature) should be used
1363+emoji2[zero_width_joiner]=$'\U200D'
1364+# Skin tone modifiers
1365+emoji2[emoji_modifier_fitzpatrick_type_1_2]=$'\U1F3FB'
1366+emoji2[emoji_modifier_fitzpatrick_type_3]=$'\U1F3FC'
1367+emoji2[emoji_modifier_fitzpatrick_type_4]=$'\U1F3FD'
1368+emoji2[emoji_modifier_fitzpatrick_type_5]=$'\U1F3FE'
1369+emoji2[emoji_modifier_fitzpatrick_type_6]=$'\U1F3FF'
1370+# Various other combining characters. (Incomplete list; I selected ones that sound useful)
1371+emoji2[combining_enclosing_circle]=$'\U20DD'
1372+emoji2[combining_enclosing_square]=$'\U20DE'
1373+emoji2[combining_enclosing_diamond]=$'\U20DF'
1374+emoji2[combining_enclosing_circle_backslash]=$'\U20E0'
1375+emoji2[combining_enclosing_screen]=$'\U20E2'
1376+emoji2[combining_enclosing_keycap]=$'\U20E3'
1377+emoji2[combining_enclosing_upward_pointing_triangle]=$'\U20E4'
1378+
1379+# Easier access to skin tone modifiers
1380+emoji_skintone[1_2]=$'\U1F3FB'
1381+emoji_skintone[3]=$'\U1F3FC'
1382+emoji_skintone[4]=$'\U1F3FD'
1383+emoji_skintone[5]=$'\U1F3FE'
1384+emoji_skintone[6]=$'\U1F3FF'
1385+
1386+# Emoji groups
1387+# These are stored in a single associative array, $emoji_groups, to avoid cluttering up the global
1388+# namespace, and to allow adding additional group definitions at run time.
1389+# The keys are the group names, and the values are whitespace-separated lists of emoji character names.
1390+
1391+emoji_groups[fruits]="
1392+  tomato
1393+  aubergine
1394+  grapes
1395+  melon
1396+  watermelon
1397+  tangerine
1398+  banana
1399+  pineapple
1400+  red_apple
1401+  green_apple
1402+  peach
1403+  cherries
1404+  strawberry
1405+  lemon
1406+  pear
1407+"
1408+
1409+emoji_groups[vehicles]="
1410+  airplane
1411diff --git a/plugins/emoji/update_emoji.pl b/plugins/emoji/update_emoji.pl
1412new file mode 100644
1413index 0000000000000000000000000000000000000000..04f3ce8e77f2e3f18ca6ded37e0a95b2b5520b04
1414--- /dev/null
1415+++ b/plugins/emoji/update_emoji.pl
1416@@ -0,0 +1,113 @@
1417+#!/usr/bin/perl -w
1418+#
1419+# update_emoji.pl
1420+#
1421+# This script generates the emoji.plugin.zsh emoji definitions from the Unicode
1422+# character data for the emoji characters.
1423+#
1424+# The data file can be found at http://unicode.org/Public/emoji/latest/emoji-data.txt
1425+# as referenced in Unicode TR51 (http://www.unicode.org/reports/tr51/index.html).
1426+#
1427+# This is known to work with the data file from version 1.0. It may not work with later
1428+# versions if the format changes. In particular, this reads line comments to get the
1429+# emoji character name and unicode version.
1430+#
1431+# Country names have punctuation and other non-letter characters removed from their name,
1432+# to avoid possible complications with having to escape the strings when using them as 
1433+# array subscripts. The definition file seems to use some combining characters like accents
1434+# that get stripped during this process.
1435+
1436+use strict;
1437+use warnings;
1438+use 5.010;
1439+use autodie;
1440+
1441+use Path::Class;
1442+use File::Copy;
1443+
1444+# Parse definitions out of the data file and convert
1445+sub process_emoji_data_file {
1446+	my ( $infile, $outfilename ) = @_;
1447+	my $file = file($infile);
1448+	my $outfile = file($outfilename);
1449+	my $outfilebase = $outfile->basename();
1450+	my $tempfilename = "$outfilename.tmp";
1451+	my $tempfile = file($tempfilename);
1452+	my $outfh = $tempfile->openw();
1453+	$outfh->print("
1454+# $outfilebase - Emoji character definitions for oh-my-zsh emoji plugin
1455+#
1456+# This file is auto-generated by update_emoji.pl. Do not edit it manually.
1457+#
1458+# This contains the definition for:
1459+#   \$emoji         - which maps character names to Unicode characters
1460+#   \$emoji_flags   - maps country names to Unicode flag characters using region indicators 
1461+
1462+# Main emoji
1463+typeset -gAH emoji
1464+# National flags
1465+typeset -gAH emoji_flags
1466+# Combining modifiers
1467+typeset -gAH emoji_mod
1468+
1469+");
1470+
1471+	my $fh = $file->openr();
1472+	my $line_num = 0;
1473+	while ( my $line = $fh->getline() ) {
1474+		$line_num++;
1475+		$_ = $line;
1476+		# Skip all-comment lines (from the header) and blank lines
1477+		# (But don't strip comments on normal lines; we need to parse those for
1478+		# the emoji names.)
1479+		next if /^\s*#/ or /^\s*$/;
1480+
1481+		if (/^(\S.*?\S)\s*;\s*(\w+)\s*;\s*(\w+)\s*;\s*(\w+)\s*;\s*(\w.*?)\s*#\s*V(\S+)\s\(.*?\)\s*(\w.*\S)\s*$/) {
1482+			my ($code, $style, $level, $modifier_status, $sources, $version, $keycap_name) 
1483+				= ($1, $2, $3, $4, $5, $6, $7);
1484+			#print "code=$code style=$style level=$level modifier_status=$modifier_status sources=$sources version=$version name=$keycap_name\n";
1485+			my @code_points = split /\s+/, $code;
1486+			my @sources = split /\s+/, $sources;
1487+
1488+			my $flag_country = "";
1489+			if ( $keycap_name =~ /^flag for (\S.*?)\s*$/) {
1490+				$flag_country = $1;
1491+			}
1492+
1493+			my $zsh_code = join '', map { "\\U$_" } @code_points;
1494+			# Convert keycap names to valid associative array names that do not require any
1495+			# quoting. Works fine for most stuff, but is clumsy for flags.
1496+			my $omz_name = lc($keycap_name);
1497+			$omz_name =~ s/[^A-Za-z0-9]/_/g;
1498+			my $zsh_flag_country = $flag_country;
1499+			$zsh_flag_country =~ s/[^\p{Letter}]/_/g;
1500+			if ($flag_country) {
1501+				$outfh->print("emoji_flags[$zsh_flag_country]=\$'$zsh_code'\n");
1502+			} else {
1503+				$outfh->print("emoji[$omz_name]=\$'$zsh_code'\n");				
1504+			}
1505+			# Modifiers are included in both the main set and their separate map,
1506+			# because they have a standalone representation as a color swatch.
1507+			if ( $modifier_status eq "modifier" ) {
1508+				$outfh->print("emoji_mod[$omz_name]=\$'$zsh_code'\n");
1509+			}
1510+		} else {
1511+			die "Failed parsing line $line_num: '$_'";
1512+		}
1513+	}
1514+	$fh->close();
1515+	$outfh->print("\n");
1516diff --git a/plugins/emotty/emotty.plugin.zsh b/plugins/emotty/emotty.plugin.zsh
1517new file mode 100644
1518index 0000000000000000000000000000000000000000..b32dd1a4c52b0a76ec21b6b7a5485db6f6a5af5a
1519--- /dev/null
1520+++ b/plugins/emotty/emotty.plugin.zsh
1521@@ -0,0 +1,43 @@
1522+# ------------------------------------------------------------------------------
1523+#          FILE: emotty.plugin.zsh
1524+#   DESCRIPTION: Return an emoji for the current $TTY number.
1525+#        AUTHOR: Alexis Hildebrandt (afh[at]surryhill.net)
1526+#       VERSION: 1.0.0
1527+#       DEPENDS: emoji plugin
1528+#       
1529+# There are different sets of emoji characters available, to choose a different
1530+# set export emotty_set to the name of the set you would like to use, e.g.:
1531+# % export emotty_set=nature
1532+# ------------------------------------------------------------------------------
1533+
1534+typeset -gAH _emotty_sets
1535+local _emotty_plugin_dir="${0:h}"
1536+source "$_emotty_plugin_dir/emotty_stellar_set.zsh"
1537+source "$_emotty_plugin_dir/emotty_floral_set.zsh"
1538+source "$_emotty_plugin_dir/emotty_zodiac_set.zsh"
1539+source "$_emotty_plugin_dir/emotty_nature_set.zsh"
1540+source "$_emotty_plugin_dir/emotty_emoji_set.zsh"
1541+source "$_emotty_plugin_dir/emotty_love_set.zsh"
1542+unset _emotty_plugin_dir
1543+
1544+emotty_default_set=emoji
1545+
1546+function emotty() {
1547+  # Use emotty set defined by user, fallback to default
1548+  local emotty=${_emotty_sets[${emotty_set:-$emotty_default_set}]}
1549+  # Parse $TTY number, normalizing it to an emotty set index
1550+  (( tty = (${TTY##/dev/ttys} % ${#${=emotty}}) + 1 ))
1551+  local character_name=${${=emotty}[tty]}
1552+  echo "${emoji[${character_name}]}${emoji2[emoji_style]}"
1553+}
1554+
1555+function display_emotty() {
1556+  local name=$1
1557+  for i in ${=_emotty_sets[$name]}; do
1558+    printf "${emoji[$i]}${emoji2[emoji_style]}  "
1559+  done
1560+  print
1561+  for i in ${=_emotty_sets[$name]}; do
1562+    print "${emoji[$i]}${emoji2[emoji_style]}  = $i"
1563+  done
1564+}
1565diff --git a/plugins/emotty/emotty_emoji_set.zsh b/plugins/emotty/emotty_emoji_set.zsh
1566new file mode 100644
1567index 0000000000000000000000000000000000000000..00e3171312aa7da12ba138f19904d2184e58b0e7
1568--- /dev/null
1569+++ b/plugins/emotty/emotty_emoji_set.zsh
1570@@ -0,0 +1,24 @@
1571+#!/usr/bin/env zsh
1572+# vim:ft=zsh ts=2 sw=2 sts=2
1573+
1574+_emotty_sets[emoji]="
1575+  crystal_ball
1576+  ghost
1577+  jack_o_lantern
1578+  see_no_evil_monkey
1579+  hear_no_evil_monkey
1580+  speak_no_evil_monkey
1581+  smiling_cat_face_with_open_mouth
1582+  extraterrestrial_alien
1583+  rocket
1584+  billiards
1585+  bomb
1586+  pill
1587+  japanese_symbol_for_beginner
1588+  direct_hit
1589+  cyclone
1590+  diamond_shape_with_a_dot_inside
1591+  sparkle
1592+  eight_spoked_asterisk
1593+  eight_pointed_black_star
1594+  "
1595diff --git a/plugins/emotty/emotty_floral_set.zsh b/plugins/emotty/emotty_floral_set.zsh
1596new file mode 100644
1597index 0000000000000000000000000000000000000000..f761feae6de186cf83e68f8398d535472dc1fd82
1598--- /dev/null
1599+++ b/plugins/emotty/emotty_floral_set.zsh
1600@@ -0,0 +1,18 @@
1601+#!/usr/bin/env zsh
1602+# vim:ft=zsh ts=2 sw=2 sts=2
1603+
1604+_emotty_sets[floral]="
1605+  hibiscus
1606+  cherry_blossom
1607+  blossom
1608+  sunflower
1609+  bouquet
1610+  tulip
1611+  rose
1612+  four_leaf_clover
1613+  seedling
1614+  herb
1615+  palm_tree
1616+  evergreen_tree
1617+  deciduous_tree
1618+  "
1619diff --git a/plugins/emotty/emotty_love_set.zsh b/plugins/emotty/emotty_love_set.zsh
1620new file mode 100644
1621index 0000000000000000000000000000000000000000..8f19e6902e2e5842eba4ed2dfb53e36ef619b391
1622--- /dev/null
1623+++ b/plugins/emotty/emotty_love_set.zsh
1624@@ -0,0 +1,34 @@
1625+#!/usr/bin/env zsh
1626+# vim:ft=zsh ts=2 sw=2 sts=2
1627+
1628+# Note: The heavy_black_heart emoji requires $emoji2[emoji_style]
1629+# to be rendered as the emoji red heart.
1630+_emotty_sets[love]="
1631+  green_heart
1632+  blue_heart
1633+  purple_heart
1634+  yellow_heart
1635+  heavy_black_heart
1636+  broken_heart
1637+  heart_with_arrow
1638+  heart_with_ribbon
1639+  sparkling_heart
1640+  two_hearts
1641+  revolving_hearts
1642+  growing_heart
1643+  beating_heart
1644+  heart_decoration
1645+  couple_with_heart
1646+  kiss
1647+  man_and_woman_holding_hands
1648+  two_women_holding_hands
1649+  two_men_holding_hands
1650+  kiss_mark
1651+  smiling_face_with_heart_shaped_eyes
1652+  kissing_face
1653+  face_throwing_a_kiss
1654+  kissing_face_with_smiling_eyes
1655+  kissing_face_with_closed_eyes
1656+  smiling_cat_face_with_heart_shaped_eyes
1657+  kissing_cat_face_with_closed_eyes
1658+  "
1659diff --git a/plugins/emotty/emotty_nature_set.zsh b/plugins/emotty/emotty_nature_set.zsh
1660new file mode 100644
1661index 0000000000000000000000000000000000000000..8dab4c1ba2eee2ad59bb8335dea79aabb007dadd
1662--- /dev/null
1663+++ b/plugins/emotty/emotty_nature_set.zsh
1664@@ -0,0 +1,58 @@
1665+#!/usr/bin/env zsh
1666+# vim:ft=zsh ts=2 sw=2 sts=2
1667+
1668+_emotty_sets[nature]="
1669+  mouse_face
1670+  hamster_face
1671+  rabbit_face
1672+  dog_face
1673+  cat_face
1674+  tiger_face
1675+  bear_face
1676+  monkey_face
1677+  koala
1678+  panda_face
1679+  chicken
1680+  baby_chick
1681+  bird
1682+  penguin
1683+  cow_face
1684+  pig_face
1685+  frog_face
1686+  boar
1687+  wolf_face
1688+  horse_face
1689+  snail
1690+  bug
1691+  ant
1692+  honeybee
1693+  lady_beetle
1694+  spouting_whale
1695+  dolphin
1696+  octopus
1697+  fish
1698+  tropical_fish
1699+  snake
1700+  turtle
1701+  lemon
1702+  tangerine
1703+  peach
1704+  mushroom
1705+  tomato
1706+  strawberry
1707+  red_apple
1708+  cherries
1709+  grapes
1710+  aubergine
1711+  watermelon
1712+  banana
1713+  pineapple
1714+  melon
1715+  pear
1716+  green_apple
1717+  ear_of_maize
1718+  sunflower
1719+  seedling
1720+  herb
1721+  four_leaf_clover
1722+  "
1723diff --git a/plugins/emotty/emotty_stellar_set.zsh b/plugins/emotty/emotty_stellar_set.zsh
1724new file mode 100644
1725index 0000000000000000000000000000000000000000..8e7e61068a523461cd1dbd4b5d0e8e023a35ce6c
1726--- /dev/null
1727+++ b/plugins/emotty/emotty_stellar_set.zsh
1728@@ -0,0 +1,25 @@
1729+#!/usr/bin/env zsh
1730+# vim:ft=zsh ts=2 sw=2 sts=2
1731+
1732+# NOTE: The following emoji show as $'character' in the title
1733+#  white_medium_star
1734+#  sparkles
1735+#  dizzy_symbol
1736+
1737+_emotty_sets[stellar]="
1738+  full_moon_symbol
1739+  waning_gibbous_moon_symbol
1740+  waning_crescent_moon_symbol
1741+  last_quarter_moon_symbol
1742+  new_moon_symbol
1743+  new_moon_with_face
1744+  waxing_crescent_moon_symbol
1745+  first_quarter_moon_symbol
1746+  waxing_gibbous_moon_symbol
1747+  full_moon_with_face
1748+  sun_with_face
1749+  glowing_star
1750+  crescent_moon
1751+  first_quarter_moon_with_face
1752+  last_quarter_moon_with_face
1753+  "
1754diff --git a/plugins/emotty/emotty_zodiac_set.zsh b/plugins/emotty/emotty_zodiac_set.zsh
1755new file mode 100644
1756index 0000000000000000000000000000000000000000..bde6e3d2e764477ce3ed0e3a0186d02a09ed6bff
1757--- /dev/null
1758+++ b/plugins/emotty/emotty_zodiac_set.zsh
1759@@ -0,0 +1,29 @@
1760+#!/usr/bin/env zsh
1761+# vim:ft=zsh ts=2 sw=2 sts=2
1762+
1763+_emotty_sets[zodiac]="
1764+  aries
1765+  taurus
1766+  gemini
1767+  cancer
1768+  leo
1769+  virgo
1770+  libra
1771+  scorpius
1772+  sagittarius
1773+  capricorn
1774+  aquarius
1775+  pisces
1776+  rat
1777+  ox
1778+  tiger
1779+  rabbit
1780+  dragon
1781+  snake
1782+  horse
1783+  goat
1784+  monkey
1785+  rooster
1786+  dog
1787+  pig
1788+  "
1789diff --git a/plugins/fancy-ctrl-z/README.md b/plugins/fancy-ctrl-z/README.md
1790new file mode 100644
1791index 0000000000000000000000000000000000000000..a7670fa2c2d9a21ea1c5aeeeb06ed07c6ece2988
1792--- /dev/null
1793+++ b/plugins/fancy-ctrl-z/README.md
1794@@ -0,0 +1,14 @@
1795+# Use Ctrl-Z to switch back to Vim
1796+
1797+I frequently need to execute random command in my shell. To achieve it I pause 
1798+Vim by pressing Ctrl-z, type command and press fg<Enter> to switch back to Vim.
1799+The fg part really hurt sme. I just wanted to hit Ctrl-z once again to get back 
1800+to Vim. I could not find a solution, so I developed one on my own that 
1801+works wonderfully with ZSH
1802+
1803+Source: http://sheerun.net/2014/03/21/how-to-boost-your-vim-productivity/
1804+
1805+Credits: 
1806+- original idea by @sheerun
1807+- added to OMZ by @mbologna
1808+
1809diff --git a/plugins/fancy-ctrl-z/fancy-ctrl-z.plugin.zsh b/plugins/fancy-ctrl-z/fancy-ctrl-z.plugin.zsh
1810new file mode 100644
1811index 0000000000000000000000000000000000000000..8ab2979133efda46a4ce1990f4d159da69d603e6
1812--- /dev/null
1813+++ b/plugins/fancy-ctrl-z/fancy-ctrl-z.plugin.zsh
1814@@ -0,0 +1,12 @@
1815+fancy-ctrl-z () {
1816+  if [[ $#BUFFER -eq 0 ]]; then
1817+    BUFFER="fg"
1818+    zle accept-line
1819+  else
1820+    zle push-input
1821+    zle clear-screen
1822+  fi
1823+}
1824+zle -N fancy-ctrl-z
1825+bindkey '^Z' fancy-ctrl-z
1826+
1827diff --git a/plugins/fasd/fasd.plugin.zsh b/plugins/fasd/fasd.plugin.zsh
1828index 472ab2b0f6b630d3c68c0de835ff4695f6306a75..b11f0b511f68ea343dcf6e090db26c9975b8fd0e 100644
1829--- a/plugins/fasd/fasd.plugin.zsh
1830+++ b/plugins/fasd/fasd.plugin.zsh
1831@@ -5,7 +5,7 @@ if [ $commands[fasd] ]; then # check if fasd is installed
1832   fi
1833   source "$fasd_cache"
1834   unset fasd_cache
1835+
1836   alias v='f -e vim'
1837-  alias o='a -e open'
1838+  alias o='a -e open_command'
1839 fi
1840-
1841diff --git a/plugins/fbterm/fbterm.plugin.zsh b/plugins/fbterm/fbterm.plugin.zsh
1842index 4f0456016f1bfa70f8a8b9efa5ea3089b5f806c2..bc253209201cca8c4a1ea4c4d30b21a621c40b07 100644
1843--- a/plugins/fbterm/fbterm.plugin.zsh
1844+++ b/plugins/fbterm/fbterm.plugin.zsh
1845@@ -1,6 +1,7 @@
1846 # start fbterm automatically in /dev/tty*
1847 
1848-if [[ $(tty|grep -o '/dev/tty') = /dev/tty ]] ; then
1849-	fbterm
1850-	exit
1851+if (( ${+commands[fbterm]} )); then
1852+	if [[ "$TTY" = /dev/tty* ]] ; then
1853+		fbterm && exit
1854+	fi
1855 fi
1856diff --git a/plugins/frontend-search/README.md b/plugins/frontend-search/README.md
1857index 801d450f300db76af79370ce96f2ac9ef65ba024..d0bc5589f742e2dd3081242f2811b69d0571bff4 100644
1858--- a/plugins/frontend-search/README.md
1859+++ b/plugins/frontend-search/README.md
1860@@ -1,74 +1,60 @@
1861-## Rationale ##
1862+## Introduction ##
1863 
1864-> Searches for your Frontend contents more easier
1865+> Searches for your frontend web development made easier
1866 
1867 
1868-## Instalation ##
1869+## Installation ##
1870 
1871+Open your `~/.zshrc` file and enable the `frontend-search` plugin:
1872 
1873-Open your `.zshrc` file and load `frontend-search` plugin
1874+```zsh
1875+
1876+plugins=( ... frontend-search)
1877 
1878-```bash
1879-...
1880-plugins=( <your-plugins-list>... frontend-search)
1881-...
1882 ```
1883 
1884 
1885-## Commands ##
1886-
1887-All command searches are accept only in format
1888-
1889-* `frontend <search-content> <search-term>`
1890-
1891-The search content are
1892-
1893-* `jquery <api.jquery.com>`
1894-* `mdn <developer.mozilla.org>`
1895-* `compass <compass-style.org>`
1896-* `html5please <html5please.com>`
1897-* `caniuse <caniuse.com>`
1898-* `aurajs <aurajs.com>`
1899-* `dartlang <api.dartlang.org/apidocs/channels/stable/dartdoc-viewer>`
1900-* `lodash <search>`
1901-* `qunit <api.qunitjs.com>`
1902-* `fontello <fontello.com>`
1903-* `bootsnipp <bootsnipp.com>`
1904-* `cssflow <cssflow.com>`
1905-* `codepen <codepen.io>`
1906-* `unheap <www.unheap.com>`
1907-* `bem <google.com/search?as_q=<search-term>&as_sitesearch=bem.info>`
1908-* `smacss <google.com/search?as_q=<search-term>&as_sitesearch=smacss.com>`
1909-* `angularjs <google.com/search?as_q=<search-term>&as_sitesearch=angularjs.org>`
1910-* `reactjs <google.com/search?as_q=<search-term>&as_sitesearch=facebook.github.io/react>`
1911-* `emberjs <emberjs.com>`
1912-* `stackoverflow <stackoverflow.com>`
1913-
1914-
1915-## Aliases ##
1916-
1917-There are a few aliases presented as well:
1918-
1919-* `jquery` A shorthand for `frontend jquery`
1920-* `mdn` A shorthand for `frontend mdn`
1921-* `compass` A shorthand for `frontend compass`
1922-* `html5please` A shorthand for `frontend html5please`
1923-* `caniuse` A shorthand for `frontend caniuse`
1924-* `aurajs` A shorthand for `frontend aurajs`
1925-* `dartlang` A shorthand for `frontend dartlang`
1926-* `lodash` A shorthand for `frontend lodash`
1927-* `qunit` A shorthand for `frontend qunit`
1928-* `fontello` A shorthand for `frontend fontello`
1929-* `bootsnipp` A shorthand for `frontend bootsnipp`
1930-* `cssflow` A shorthand for `frontend cssflow`
1931-* `codepen` A shorthand for `frontend codepen`
1932-* `unheap` A shorthand for `frontend unheap`
1933-* `bem` A shorthand for `frontend bem`
1934-* `smacss` A shorthand for `frontend smacss`
1935-* `angularjs` A shorthand for `frontend angularjs`
1936-* `reactjs` A shorthand for `frontend reactjs`
1937-* `emberjs` A shorthand for `frontend emberjs`
1938-* `stackoverflow` A shorthand for `frontend stackoverflow`
1939+## Usage ##
1940+
1941+You can use the frontend-search plugin in these two forms:
1942+
1943+* `frontend <context> <term> [more terms if you want]`
1944+* `<context> <term> [more terms if you want]`
1945+
1946+For example, these two are equivalent:
1947+
1948+```zsh
1949+$ frontend angularjs dependency injection
1950+$ angularjs dependency injection
1951+```
1952+
1953+Available search contexts are:
1954+
1955+| context       | URL                                                                      |
1956+|---------------|--------------------------------------------------------------------------|
1957+| angularjs     | `https://google.com/search?as_sitesearch=angularjs.org&as_q=`            |
1958+| aurajs        | `http://aurajs.com/api/#stq=`                                            |
1959+| bem           | `https://google.com/search?as_sitesearch=bem.info&as_q=`                 |
1960diff --git a/plugins/frontend-search/_frontend-search.sh b/plugins/frontend-search/_frontend-search.sh
1961index 252f215707240ce8c11236d919b601c51791be62..b12f829a1c58e52388c7a613b9569ec7406ce3cf 100644
1962--- a/plugins/frontend-search/_frontend-search.sh
1963+++ b/plugins/frontend-search/_frontend-search.sh
1964@@ -37,6 +37,7 @@ function _frontend() {
1965     'reactjs: Search in React website'
1966     'emberjs: Search in Ember website'
1967     'stackoverflow: Search in StackOverflow website'
1968+    'npmjs: Search in NPMJS website'
1969   )
1970 
1971   _arguments -C \
1972@@ -110,6 +111,9 @@ function _frontend() {
1973         stackoverflow)
1974           _describe -t points "Warp points" frontend_points && ret=0
1975           ;;
1976+        npmjs)
1977+          _describe -t points "Warp points" frontend_points && ret=0
1978+          ;;
1979       esac
1980       ;;
1981   esac
1982diff --git a/plugins/frontend-search/frontend-search.plugin.zsh b/plugins/frontend-search/frontend-search.plugin.zsh
1983index b9fb8634c66f15619247713d82febeeb28fbfeeb..2fd5416b3c032aaab73f1ea780aa717881ddb680 100644
1984--- a/plugins/frontend-search/frontend-search.plugin.zsh
1985+++ b/plugins/frontend-search/frontend-search.plugin.zsh
1986@@ -1,158 +1,91 @@
1987-# frontend from terminal
1988+alias angularjs='frontend angularjs'
1989+alias aurajs='frontend aurajs'
1990+alias bem='frontend bem'
1991+alias bootsnipp='frontend bootsnipp'
1992+alias caniuse='frontend caniuse'
1993+alias codepen='frontend codepen'
1994+alias compass='frontend compass'
1995+alias cssflow='frontend cssflow'
1996+alias dartlang='frontend dartlang'
1997+alias emberjs='frontend emberjs'
1998+alias fontello='frontend fontello'
1999+alias html5please='frontend html5please'
2000+alias jquery='frontend jquery'
2001+alias lodash='frontend lodash'
2002+alias mdn='frontend mdn'
2003+alias npmjs='frontend npmjs'
2004+alias qunit='frontend qunit'
2005+alias reactjs='frontend reactjs'
2006+alias smacss='frontend smacss'
2007+alias stackoverflow='frontend stackoverflow'
2008+alias unheap='frontend unheap'
2009 
2010 function frontend() {
2011-
2012-  # get the open command
2013-  local open_cmd
2014-  if [[ $(uname -s) == 'Darwin' ]]; then
2015-    open_cmd='open'
2016-  else
2017-    open_cmd='xdg-open'
2018-  fi
2019-
2020-  # no keyword provided, simply show how call methods
2021-  if [[ $# -le 1 ]]; then
2022-    echo "Please provide a search-content and a search-term for app.\nEx:\nfrontend <search-content> <search-term>\n"
2023-    return 1
2024+  emulate -L zsh
2025+
2026+  # define search context URLS
2027+  typeset -A urls
2028+  urls=(
2029+    angularjs      'https://google.com/search?as_sitesearch=angularjs.org&as_q='
2030+    aurajs         'http://aurajs.com/api/#stq='
2031+    bem            'https://google.com/search?as_sitesearch=bem.info&as_q='
2032+    bootsnipp      'http://bootsnipp.com/search?q='
2033+    caniuse        'http://caniuse.com/#search='
2034+    codepen        'http://codepen.io/search?q='
2035+    compass        'http://compass-style.org/search?q='
2036+    cssflow        'http://www.cssflow.com/search?q='
2037+    dartlang       'https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:'
2038+    emberjs        'http://emberjs.com/api/#stp=1&stq='
2039+    fontello       'http://fontello.com/#search='
2040+    html5please    'http://html5please.com/#'
2041+    jquery         'https://api.jquery.com/?s='
2042+    lodash         'https://devdocs.io/lodash/index#'
2043+    mdn            'https://developer.mozilla.org/search?q='
2044+    npmjs          'https://www.npmjs.com/search?q='
2045+    qunit          'https://api.qunitjs.com/?s='
2046+    reactjs        'https://google.com/search?as_sitesearch=facebook.github.io/react&as_q='
2047+    smacss         'https://google.com/search?as_sitesearch=smacss.com&as_q='
2048+    stackoverflow  'http://stackoverflow.com/search?q='
2049+    unheap         'http://www.unheap.com/?s='
2050+  )
2051+
2052+  # show help for command list
2053+  if [[ $# -lt 2 ]]
2054+  then
2055+      print -P "Usage: frontend %Ucontext%u %Uterm%u [...%Umore%u] (or just: %Ucontext%u %Uterm%u [...%Umore%u])"
2056+      print -P ""
2057+      print -P "%Uterm%u and what follows is what will be searched for in the %Ucontext%u website,"
2058+      print -P "and %Ucontext%u is one of the following:"
2059+      print -P ""
2060+      print -P "  angularjs, aurajs, bem, bootsnipp, caniuse, codepen, compass, cssflow,"
2061+      print -P "  dartlang, emberjs, fontello, html5please, jquery, lodash, mdn, npmjs,"
2062+      print -P "  qunit, reactjs, smacss, stackoverflow, unheap"
2063+      print -P ""
2064+      print -P "For example: frontend npmjs mocha (or just: npmjs mocha)."
2065+      print -P ""
2066+      return 1
2067   fi
2068 
2069-  # check whether the search engine is supported
2070-  if [[ ! $1 =~ '(jquery|mdn|compass|html5please|caniuse|aurajs|dartlang|qunit|fontello|bootsnipp|cssflow|codepen|unheap|bem|smacss|angularjs|reactjs|emberjs|stackoverflow)' ]];
2071+  # check whether the search context is supported
2072+  if [[ -z "$urls[$1]" ]]
2073   then
2074-    echo "Search valid search content $1 not supported."
2075-    echo "Valid contents: (formats 'frontend <search-content>' or '<search-content>')"
2076-    echo "* jquery"
2077-    echo "* mdn"
2078-    echo "* compass"
2079-    echo "* html5please"
2080-    echo "* caniuse"
2081-    echo "* aurajs"
2082-    echo "* dartlang"
2083-    echo "* lodash"
2084-    echo "* qunit"
2085-    echo "* fontello"
2086diff --git a/plugins/git-extras/git-extras.plugin.zsh b/plugins/git-extras/git-extras.plugin.zsh
2087index 8419166abc10b7f05a30fe02d39aa34d3c33cddb..d91c1af81c6391c17249449e8cd5bc554201a73a 100644
2088--- a/plugins/git-extras/git-extras.plugin.zsh
2089+++ b/plugins/git-extras/git-extras.plugin.zsh
2090@@ -3,19 +3,20 @@
2091 # Description
2092 # -----------
2093 #
2094-#  Completion script for git-extras (http://github.com/visionmedia/git-extras).
2095+#  Completion script for git-extras (http://github.com/tj/git-extras).
2096 #
2097 # ------------------------------------------------------------------------------
2098 # Authors
2099 # -------
2100 #
2101 #  * Alexis GRIMALDI (https://github.com/agrimaldi)
2102+#  * spacewander (https://github.com/spacewander)
2103 #
2104 # ------------------------------------------------------------------------------
2105 # Inspirations
2106 # -----------
2107 #
2108-#  * git-extras (http://github.com/visionmedia/git-extras)
2109+#  * git-extras (http://github.com/tj/git-extras)
2110 #  * git-flow-completion (http://github.com/bobthecow/git-flow-completion)
2111 #
2112 # ------------------------------------------------------------------------------
2113@@ -30,10 +31,21 @@ __git_command_successful () {
2114 }
2115 
2116 
2117+__git_commits() {
2118+    declare -A commits
2119+    git log --oneline -15 | sed 's/\([[:alnum:]]\{7\}\) /\1:/' | while read commit
2120+    do
2121+        hash=$(echo $commit | cut -d':' -f1)
2122+        commits[$hash]="$commit"
2123+    done
2124+    local ret=1
2125+    _describe -t commits commit commits && ret=0
2126+}
2127+
2128 __git_tag_names() {
2129     local expl
2130     declare -a tag_names
2131-    tag_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/})
2132+    tag_names=(${${(f)"$(_call_program tags git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/})
2133     __git_command_successful || return
2134     _wanted tag-names expl tag-name compadd $* - $tag_names
2135 }
2136@@ -47,31 +59,27 @@ __git_branch_names() {
2137     _wanted branch-names expl branch-name compadd $* - $branch_names
2138 }
2139 
2140-
2141-__git_feature_branch_names() {
2142+__git_specific_branch_names() {
2143     local expl
2144     declare -a branch_names
2145-    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/feature 2>/dev/null)"}#refs/heads/feature/})
2146+    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/"$1" 2>/dev/null)"}#refs/heads/$1/})
2147     __git_command_successful || return
2148     _wanted branch-names expl branch-name compadd $* - $branch_names
2149 }
2150 
2151 
2152+__git_feature_branch_names() {
2153+    __git_specific_branch_names 'feature'
2154+}
2155+
2156+
2157 __git_refactor_branch_names() {
2158-    local expl
2159-    declare -a branch_names
2160-    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/refactor 2>/dev/null)"}#refs/heads/refactor/})
2161-    __git_command_successful || return
2162-    _wanted branch-names expl branch-name compadd $* - $branch_names
2163+    __git_specific_branch_names 'refactor'
2164 }
2165 
2166 
2167 __git_bug_branch_names() {
2168-    local expl
2169-    declare -a branch_names
2170-    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/bug 2>/dev/null)"}#refs/heads/bug/})
2171-    __git_command_successful || return
2172-    _wanted branch-names expl branch-name compadd $* - $branch_names
2173+    __git_specific_branch_names 'bug'
2174 }
2175 
2176 
2177@@ -92,19 +100,43 @@ __git_author_names() {
2178     _wanted author-names expl author-name compadd $* - $author_names
2179 }
2180 
2181+# subcommands
2182 
2183-_git-changelog() {
2184-    _arguments \
2185-        '(-l --list)'{-l,--list}'[list commits]' \
2186+_git-bug() {
2187+    local curcontext=$curcontext state line ret=1
2188+    declare -A opt_args
2189+
2190diff --git a/plugins/git-flow/git-flow.plugin.zsh b/plugins/git-flow/git-flow.plugin.zsh
2191index 4357c08957e6f7373df0dbcd465db2d59719f6f9..444440bcb8afeff1a3f699e694d834210d793087 100644
2192--- a/plugins/git-flow/git-flow.plugin.zsh
2193+++ b/plugins/git-flow/git-flow.plugin.zsh
2194@@ -21,7 +21,7 @@
2195 #
2196 
2197 #Alias
2198-alias gf='git flow'
2199+alias gfl='git flow'
2200 alias gcd='git checkout develop'
2201 alias gch='git checkout hotfix'
2202 alias gcr='git checkout release'
2203diff --git a/plugins/git-prompt/git-prompt.plugin.zsh b/plugins/git-prompt/git-prompt.plugin.zsh
2204index d868a5fe1d1bf6b6117db674b093d1a632f5d0d7..5175bf70f91d0fafddebfd72a74eea5435131213 100644
2205--- a/plugins/git-prompt/git-prompt.plugin.zsh
2206+++ b/plugins/git-prompt/git-prompt.plugin.zsh
2207@@ -1,57 +1,92 @@
2208 # ZSH Git Prompt Plugin from:
2209 # http://github.com/olivierverdier/zsh-git-prompt
2210-#
2211-export __GIT_PROMPT_DIR=$ZSH/plugins/git-prompt
2212 
2213-# Allow for functions in the prompt.
2214-setopt PROMPT_SUBST
2215+__GIT_PROMPT_DIR="${0:A:h}"
2216 
2217-## Enable auto-execution of functions.
2218-typeset -ga preexec_functions
2219-typeset -ga precmd_functions
2220-typeset -ga chpwd_functions
2221-
2222-# Append git functions needed for prompt.
2223-preexec_functions+='preexec_update_git_vars'
2224-precmd_functions+='precmd_update_git_vars'
2225-chpwd_functions+='chpwd_update_git_vars'
2226+## Hook function definitions
2227+function chpwd_update_git_vars() {
2228+    update_current_git_vars
2229+}
2230 
2231-## Function definitions
2232 function preexec_update_git_vars() {
2233     case "$2" in
2234-        git*)
2235+        git*|hub*|gh*|stg*)
2236         __EXECUTED_GIT_COMMAND=1
2237         ;;
2238     esac
2239 }
2240 
2241 function precmd_update_git_vars() {
2242-    if [ -n "$__EXECUTED_GIT_COMMAND" ]; then
2243+    if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then
2244         update_current_git_vars
2245         unset __EXECUTED_GIT_COMMAND
2246     fi
2247 }
2248 
2249-function chpwd_update_git_vars() {
2250-    update_current_git_vars
2251-}
2252+chpwd_functions+=(chpwd_update_git_vars)
2253+precmd_functions+=(precmd_update_git_vars)
2254+preexec_functions+=(preexec_update_git_vars)
2255+
2256 
2257+## Function definitions
2258 function update_current_git_vars() {
2259     unset __CURRENT_GIT_STATUS
2260 
2261     local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py"
2262-    _GIT_STATUS=`python ${gitstatus}`
2263-    __CURRENT_GIT_STATUS=("${(f)_GIT_STATUS}")
2264+    _GIT_STATUS=$(python ${gitstatus} 2>/dev/null)
2265+     __CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}")
2266+    GIT_BRANCH=$__CURRENT_GIT_STATUS[1]
2267+    GIT_AHEAD=$__CURRENT_GIT_STATUS[2]
2268+    GIT_BEHIND=$__CURRENT_GIT_STATUS[3]
2269+    GIT_STAGED=$__CURRENT_GIT_STATUS[4]
2270+    GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5]
2271+    GIT_CHANGED=$__CURRENT_GIT_STATUS[6]
2272+    GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7]
2273 }
2274 
2275-function prompt_git_info() {
2276+git_super_status() {
2277+    precmd_update_git_vars
2278     if [ -n "$__CURRENT_GIT_STATUS" ]; then
2279-        echo "(%{${fg[red]}%}$__CURRENT_GIT_STATUS[1]%{${fg[default]}%}$__CURRENT_GIT_STATUS[2]%{${fg[magenta]}%}$__CURRENT_GIT_STATUS[3]%{${fg[default]}%})"
2280+      STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}"
2281+      if [ "$GIT_BEHIND" -ne "0" ]; then
2282+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}"
2283+      fi
2284+      if [ "$GIT_AHEAD" -ne "0" ]; then
2285+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD%{${reset_color}%}"
2286+      fi
2287+      STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR"
2288+      if [ "$GIT_STAGED" -ne "0" ]; then
2289+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED%{${reset_color}%}"
2290+      fi
2291+      if [ "$GIT_CONFLICTS" -ne "0" ]; then
2292+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS%{${reset_color}%}"
2293+      fi
2294+      if [ "$GIT_CHANGED" -ne "0" ]; then
2295+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}"
2296+      fi
2297+      if [ "$GIT_UNTRACKED" -ne "0" ]; then
2298+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}"
2299+      fi
2300+      if [ "$GIT_CHANGED" -eq "0" ] && [ "$GIT_CONFLICTS" -eq "0" ] && [ "$GIT_STAGED" -eq "0" ] && [ "$GIT_UNTRACKED" -eq "0" ]; then
2301+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN"
2302+      fi
2303+      STATUS="$STATUS%{${reset_color}%}$ZSH_THEME_GIT_PROMPT_SUFFIX"
2304+      echo "$STATUS"
2305     fi
2306 }
2307diff --git a/plugins/git-prompt/gitstatus.py b/plugins/git-prompt/gitstatus.py
2308index 2568414320a79140ab387ad4fe788d8cd78367fd..a8eb8284b7ad8ed601890d84f0ffbfe92f6c00a1 100644
2309--- a/plugins/git-prompt/gitstatus.py
2310+++ b/plugins/git-prompt/gitstatus.py
2311@@ -1,82 +1,84 @@
2312 #!/usr/bin/env python
2313-# -*- coding: UTF-8 -*-
2314-from subprocess import Popen, PIPE
2315-import re
2316+from __future__ import print_function
2317 
2318-# change those symbols to whatever you prefer
2319-symbols = {
2320-    'ahead of': '↑',
2321-    'behind': '↓',
2322-    'staged': '♦',
2323-    'changed': '‣',
2324-    'untracked': '…',
2325-    'clean': '⚡',
2326-    'unmerged': '≠',
2327-    'sha1': ':'
2328-}
2329+import sys
2330+import re
2331+import shlex
2332+from subprocess import Popen, PIPE, check_output
2333 
2334-output, error = Popen(
2335-    ['git', 'status'], stdout=PIPE, stderr=PIPE, universal_newlines=True).communicate()
2336 
2337-if error:
2338-    import sys
2339-    sys.exit(0)
2340-lines = output.splitlines()
2341+def get_tagname_or_hash():
2342+    """return tagname if exists else hash"""
2343+    cmd = 'git log -1 --format="%h%d"'
2344+    output = check_output(shlex.split(cmd)).decode('utf-8').strip()
2345+    hash_, tagname = None, None
2346+    # get hash
2347+    m = re.search('\(.*\)$', output)
2348+    if m:
2349+        hash_ = output[:m.start()-1]
2350+    # get tagname
2351+    m = re.search('tag: .*[,\)]', output)
2352+    if m:
2353+        tagname = 'tags/' + output[m.start()+len('tag: '): m.end()-1]
2354 
2355-behead_re = re.compile(
2356-    r"^# Your branch is (ahead of|behind) '(.*)' by (\d+) commit")
2357-diverge_re = re.compile(r"^# and have (\d+) and (\d+) different")
2358+    if tagname:
2359+        return tagname
2360+    elif hash_:
2361+        return hash_
2362+    return None
2363 
2364-status = ''
2365-staged = re.compile(r'^# Changes to be committed:$', re.MULTILINE)
2366-changed = re.compile(r'^# Changed but not updated:$', re.MULTILINE)
2367-untracked = re.compile(r'^# Untracked files:$', re.MULTILINE)
2368-unmerged = re.compile(r'^# Unmerged paths:$', re.MULTILINE)
2369 
2370+# `git status --porcelain --branch` can collect all information
2371+# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
2372+po = Popen(['git', 'status', '--porcelain', '--branch'], stdout=PIPE, stderr=PIPE)
2373+stdout, sterr = po.communicate()
2374+if po.returncode != 0:
2375+    sys.exit(0)  # Not a git repository
2376 
2377-def execute(*command):
2378-    out, err = Popen(stdout=PIPE, stderr=PIPE, *command).communicate()
2379-    if not err:
2380-        nb = len(out.splitlines())
2381+# collect git status information
2382+untracked, staged, changed, conflicts = [], [], [], []
2383+ahead, behind = 0, 0
2384+status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()]
2385+for st in status:
2386+    if st[0] == '#' and st[1] == '#':
2387+        if re.search('Initial commit on', st[2]):
2388+            branch = st[2].split(' ')[-1]
2389+        elif re.search('no branch', st[2]):  # detached status
2390+            branch = get_tagname_or_hash()
2391+        elif len(st[2].strip().split('...')) == 1:
2392+            branch = st[2].strip()
2393+        else:
2394+            # current and remote branch info
2395+            branch, rest = st[2].strip().split('...')
2396+            if len(rest.split(' ')) == 1:
2397+                # remote_branch = rest.split(' ')[0]
2398+                pass
2399+            else:
2400+                # ahead or behind
2401+                divergence = ' '.join(rest.split(' ')[1:])
2402+                divergence = divergence.lstrip('[').rstrip(']')
2403+                for div in divergence.split(', '):
2404+                    if 'ahead' in div:
2405+                        ahead = int(div[len('ahead '):].strip())
2406+                    elif 'behind' in div:
2407+                        behind = int(div[len('behind '):].strip())
2408+    elif st[0] == '?' and st[1] == '?':
2409+        untracked.append(st)
2410     else: