Просмотр исходного кода

Add ack/ag completions, change tmuxinator completion

Switch tmuxinator completion to this one from `zsh-users`, because it is
fits into our current custom completion structure (rather than the
tmuxinator repo version, which seems like it will become a
directly-sourced script).
Weiyi Lou 9 лет назад
Родитель
Сommit
5169e72eed
4 измененных файлов с 474 добавлено и 3 удалено
  1. 7 3
      bin/dotfiles-upgrade
  2. 237 0
      shell/zsh/completions/_ack
  3. 217 0
      shell/zsh/completions/_ag
  4. 13 0
      shell/zsh/completions/_tmuxinator

+ 7 - 3
bin/dotfiles-upgrade

@@ -26,13 +26,17 @@ echo "Downloading files from external sources:"
 #curl -# https://gist.githubusercontent.com/octocat/9257657/raw/3f9569e65df83a7b328b39a091f0ce9c6efc6429/.gitignore \
   #-o ~/dotfiles/git/globalignore
 
-echo "tmuxinator completion for bash"
+echo "Completions for bash"
 curl -# https://raw.githubusercontent.com/tmuxinator/tmuxinator/master/completion/tmuxinator.bash \
   -o ~/dotfiles/shell/bash/tmuxinator.bash
 
-echo "tmuxinator completion for zsh"
-curl -# https://raw.githubusercontent.com/tmuxinator/tmuxinator/master/completion/tmuxinator.zsh \
+echo "Completions for zsh"
+curl -# https://raw.githubusercontent.com/zsh-users/zsh-completions/master/src/_tmuxinator \
   -o ~/dotfiles/shell/zsh/completions/_tmuxinator
+curl -# https://raw.githubusercontent.com/zsh-users/zsh-completions/master/src/_ack \
+  -o ~/dotfiles/shell/zsh/completions/_ack
+curl -# https://raw.githubusercontent.com/zsh-users/zsh-completions/master/src/_ag \
+  -o ~/dotfiles/shell/zsh/completions/_ag
 
 echo "tmux colours - solarized 256"
 curl -# https://raw.githubusercontent.com/seebi/tmux-colors-solarized/master/tmuxcolors-256.conf \

+ 237 - 0
shell/zsh/completions/_ack

@@ -0,0 +1,237 @@
+#compdef ack ack2 ack-grep ack-standalone
+# ------------------------------------------------------------------------------
+# Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for ack 1.96 and 2.14 (http://betterthangrep.com).
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Julien Nicoulaud <julien.nicoulaud@gmail.com> (version 1.94)
+#  * Zhao Cai <caizhaoff@gmail.com> (version 2.04)
+#
+# ------------------------------------------------------------------------------
+
+_ack_version() {
+    local version
+    version=(${(f)"$(_call_program version $words[1] --version)"})
+    version=${${(z)${version[1]}}[2]}
+    echo $version
+}
+
+_ack() {
+  local context curcontext="$curcontext" state line cmds update_policy ret=1
+  integer NORMARG
+  typeset -A opt_args
+
+  # Don't complete if command doesn't exist
+  [[ ${+commands[${words[1]}]} -eq 0 ]] && return 0
+
+  zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+  [[ -z "$update_policy" ]] && zstyle ":completion:${curcontext}:" cache-policy _ack_types_caching_policy
+
+  unset _ack_raw_types
+  if ( [[ ${+_ack_raw_types} -eq 0 ]] || _cache_invalid "ack-grep" ) && ! _retrieve_cache "ack-grep"; then
+    _ack_raw_types=(${(S)${(S)${(f)${${"$(_call_program types $words[1] --help=types)"}#*--\[no\]}}%; first line matches \/*\/}#*no\]})
+    [[ $#_ack_raw_types -gt 0 ]] && _store_cache "ack-grep" _ack_raw_types
+  fi
+
+  ack_20_options=(
+    '--ackrc[specify an ackrc file to use]:files:_files'
+    '(- 1 *)--bar[consult Admiral Ackbar]'
+    '(--nobreak --break)'{--nobreak,--break}'[print a break between results from different files, default on]'
+    '(- 1 *)--cathy[chocolate chocolate chocolate]'
+    '(- 1 *)--create-ackrc[create custom ackrc files based on the default settings loaded by ackrc]'
+    '(- 1 *)--dump[writes the list of options loaded and where they came from to standard output]'
+    '(--files-from -x)--files-from=[read the list of files to search from FILE]:files:_files'
+    '(--filter --nofilter)--filter[force ack to treat input as pipe]'
+    '(--filter --nofilter)--nofilter[force ack to treat input as tty]'
+    '(--noheading --heading)'{--noheading,--heading}'[print a filename heading above results, default on]'
+    '(- 1 *)--help-types[display all known types]'
+    '--ignore-ack-defaults[ignore default definitions included with ack]'
+    '*--ignore-file=[ignore file]:ignore file filter: _describe "ignore file filter" ignore_filter_opts'
+    '(-k --known-types)'{-k,--known-types}'[include only files of types that ack recognizes]'
+    '--lines=[only print line(s) NUM of each file]:number'
+    '--nopager[do not send output through a pager, overrides ackrc, ACK_PAGER & ACK_PAGER_COLOR]'
+    '-s[suppress error messages about nonexistent or unreadable files]'
+    '(- 1 *)--thpppt[bill the cat]'
+    '*--type-del[remove all filters associated with TYPE]' \
+    '(-x --files-from)-x[read the list of files to search from STDIN]'
+  )
+
+  ack_19_options=(
+    '(-a --all -u --unrestricted)'{-a,--all}'[operate on all files, regardless of type (but still skip directories like blib, CVS, etc.)]'
+    '-G+[only paths matching the given regex are included in the search]:regex'
+    '--invert-file-match[print/search handle files that do not match -g/-G]'
+    '--line=[only print given line of each file]:number' \
+    '(-u --unrestricted -a --all)'{-u,--unrestricted}'[all files and directories (including blib/, core.*, ...) are searched, nothing is skipped]'
+  )
+
+  if (( $(_ack_version) > 2.0 )); then
+    ack_version_options=(${ack_20_options})
+  else
+    ack_version_options=(${ack_19_options})
+  fi
+
+  _arguments -C -s -S -n \
+    '(- 1 *)--version[display version and copyright information]' \
+    '(- 1 *)--help[print a short help statement]' \
+    '(- 1 *)--man[print the manual page]' \
+    $ack_version_options \
+    '(-A --after-context -C --context)'{-A+,--after-context=}'[print N lines of trailing context after matching lines]:number' \
+    '(-B --before-context -C --context)'{-B+,--before-context=}'[print N lines of leading context before matching lines]:number' \
+    '(-C --context -A --after-context -B --before-context)'{-C-,--context=}'[print N lines (default 2) of context around matching lines]:number' \
+    '(-c --count)'{-c,--count}'[suppress normal output; instead print a count of matching lines for each input file]' \
+    '(--nocolor)--color[highlight the matching text]' \
+    '(--color --color-filename --color-match --color-lineno)--nocolor[suppress the color]' \
+    '(--nocolor --color)--color-filename[sets the color to be used for filenames]:color:->colors' \
+    '(--nocolor --color)--color-match[sets the color to be used for matches]:color:->colors' \
+    '(--nocolor --color)--color-lineno[sets the color to be used for line numbers]:color:->colors' \
+    '--column[show the column number of the first match]' \
+    '(--noenv)--env[enable environment processing]' \
+    '(--env)--noenv[disable all environment processing, no .ackrc is read and all environment variables are ignored]' \
+    '--flush[flush output immediately]' \
+    '-f[only print the files that would be searched, without actually doing any searching]' \
+    '(--nofollow)--follow[follow symlinks]' \
+    '(--follow)--nofollow[don'\''t follow symlinks]' \
+    '-g+[print files where the relative path + filename matches the given regex]:regex' \
+    '(--nogroup)--group[group matches by file name]' \
+    '(--group)--nogroup[do not group matches by file name]' \
+    '(-H --with-filename -h --no-filename)'{-H,--with-filename}'[print the filename for each match]' \
+    '(-h --no-filename -H --with-filename)'{-h,--no-filename}'[suppress the prefixing of filenames on output when multiple files are searched]' \
+    '(-i --ignore-case)'{-i,--ignore-case}'[ignore case in the search strings]' \
+    '*--ignore-dir=[ignore directory]:directory:_files' \
+    '*--noignore-dir=[ignore directory]:directory:_files' \
+    '(-l --files-with-matches -L --files-without-matches)'{-l,--files-with-matches}'[only print the filenames of matching files, instead of the matching text]' \
+    '(-L --files-without-matches -l --files-with-matches)'{-L,--files-without-matches}'[only print the filenames of files that do NOT match]' \
+    '--match=[specify the regular expression explicitly]:regex' \
+    '(-m --max-count)'{-m+,--max-count=}'[stop reading a file after N matches]:number' \
+    '(-r -R --recurse -n --no-recurse)'{-r,-R,--recurse}'[recurse into sub-directories]' \
+    '(-n --no-recurse -r -R --recurse)'{-n,--no-recurse}'[no descending into subdirectories]' \
+    '-o[show only the part of each line matching PATTERN (turns off text highlighting)]:pattern' \
+    '--output=[output the evaluation of expr for each line (turns off text highlighting)]:expression' \
+    '--pager=[direct ack'\''s output through program]:pager program:_command_names' \
+    '--passthru[prints all lines, whether or not they match the expression]' \
+    '--print0[the filenames are output separated with a null byte instead of the usual newline]' \
+    '(-Q --literal)'{-Q,--literal}'[quote all metacharacters in the pattern, it is treated as a literal]' \
+    '(--no-smart-case)--smart-case[ignore case in the search strings if pattern contains no uppercase characters]' \
+    '(--smart-case)--no-smart-case[disable --smart-case option]' \
+    '--sort-files[sorts the found files lexically]' \
+    '--show-types[outputs the filetypes that ack associates with each file]' \
+    '--thpppt[display the all-important Bill The Cat logo]' \
+    '*--type=[specify the types of files to include or exclude from a search]:type:->types' \
+    '*--type-add[files with the given extensions are recognized as being of the given type]:type-def:->type-defs' \
+    '*--type-set[files with the given extensions are recognized as being of the given type]:type-def:->type-defs' \
+    '(-v --invert-match)'{-v,--invert-match}'[invert match: select non-matching lines]' \
+    '(-w --word-regexp)'{-w,--word-regexp}'[force the given pattern to match only whole words]' \
+    '-1[stops after reporting first match of any kind]' \
+    {'--','--no'}${_ack_raw_types/ ##/\[}']' \
+    '*: :->args' \
+  && ret=0
+
+  case $state in
+    args)
+      if [[ CURRENT -eq NORMARG && ${+opt_args[--match]} -eq 0 ]]; then
+        # If the current argument is the first non-option argument
+        # and --match isn't present then a pattern is expected
+        _message -e patterns 'pattern' && ret=0
+      else
+        _files
+      fi
+      ;;
+    colors)
+      local colors; colors=(
+        'black'      'on_black'
+        'red'        'on_red'
+        'green'      'on_green'
+        'yellow'     'on_yellow'
+        'blue'       'on_blue'
+        'magenta'    'on_magenta'
+        'cyan'       'on_cyan'
+        'white'      'on_white'
+        'clear'
+        'reset'
+        'dark'
+        'bold'
+        'underline'
+        'underscore'
+        'blink'
+        'reverse'
+        'concealed'
+      )
+      _describe -t 'colors' 'color' colors && ret=0
+      ;;
+    type-defs)
+      if compset -P '*='; then
+        local extensions; extensions=(*.*(:e))
+        _values -s ',' 'file extension' '.'$extensions && ret=0
+      else
+        _message -e type-name 'type name' && ret=0
+      fi
+      ;;
+    types)
+      local types; types=({'','no'}${_ack_raw_types/ ##/:})
+      _describe -t 'types' 'type' types
+      ;;
+  esac
+
+  return ret
+}
+
+ignore_filter_opts=(
+  'is\::FILENAME'
+  'ext\::[EXTENSION,EXTENSION2,...]'
+  'match\::PATTERN'
+  'firstlinematch\::PATTERN'
+)
+
+_ack_types_caching_policy() {
+
+  # Rebuild if ackrc more recent than cache.
+  [[ -f ${ACKRC:-$HOME/.ackrc} && ${ACKRC:-$HOME/.ackrc} -nt "$1" ]] && return 0
+
+  # Rebuild if cache is older than one week.
+  local -a oldp
+  oldp=( "$1"(Nmw+1) )
+  (( $#oldp )) && return 0
+
+  return 1
+}
+
+_ack "$@"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
+

+ 217 - 0
shell/zsh/completions/_ag

@@ -0,0 +1,217 @@
+#compdef ag
+# ------------------------------------------------------------------------------
+# Copyright (c) 2015 Github zsh-users - http://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for ag (https://github.com/ggreer/the_silver_searcher)
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Akira Maeda <https://github.com/glidenote>
+#
+# ------------------------------------------------------------------------------
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+# vim: ft=zsh sw=2 ts=2 et
+# ------------------------------------------------------------------------------
+_ag_version() {
+  local version
+  version=( $($words[1] --version) )
+  version=${version[@]:2:1}
+  version=( "${(@s/./)version}" )
+  echo "${version[2]}"
+}
+
+# Dynamically build the file type completion
+# Modifies the global $AG_OPTS array
+_ag_add_file_types() {
+  local typ exts
+  for i in $($words[1] --list-file-types); do
+    if [[ "${i:0:2}" = '--' ]]; then
+      if [[ "${typ}x" != "x" ]]; then
+        AG_OPTS+="${typ}[${exts}]"
+      fi
+      typ=$i
+      exts=
+    else
+      exts+=$i
+    fi
+  done
+  AG_OPTS+="${typ}[${exts}]"
+}
+
+# Add version appropriate options above base
+# Modifies the global $AG_OPTS array
+_ag_add_version_opts() {
+  local minor=$(_ag_version)
+
+  if [[ $minor -gt 21 ]];then
+    _ag_add_file_types
+    AG_OPTS+=(
+      '(- 1 *)--list-file-types[list supported filetypes to search]'
+      '--silent[suppress all log messages, including errors]'
+    )
+  fi
+
+  if [[ $minor -gt 22 ]];then
+    AG_OPTS+=(
+      '(-z --search-zip)'{-z,--search-zip}'[search contents of compressed files]'
+    )
+  fi
+
+  if [[ $minor -le 24 ]];then
+    AG_OPTS+=(
+      '(-s --case-sensitive)'{-s,--case-sensitive}'[match case sensitively]'
+      '(--noheading --heading)'{--noheading,--heading}'[print file names above matching contents]'
+    )
+  fi
+  if [[ $minor -gt 24 ]];then
+    AG_OPTS+=(
+      '(-s --case-sensitive)'{-s,--case-sensitive}'[Match case sensitively. Default on.]'
+      '(-H --noheading --heading)'{-H,--noheading,--heading}'[print file names above matching contents]'
+      '--vimgrep[output results like vim''s, :vimgrep /pattern/g would (report every match on the line)]'
+    )
+  fi
+
+  if [[ $minor -gt 26 ]];then
+    AG_OPTS+=(
+      '(-0 --null --print0)'{-0,--null,--print0}'[separate the filenames with \\0, rather than \\n]'
+    )
+  fi
+
+  if [[ $minor -le 27 ]];then
+    AG_OPTS+=(
+      '--depth[Search up to NUM directories deep. Default is 25.]:number'
+    )
+  fi
+  if [[ $minor -gt 27 ]];then
+    AG_OPTS+=(
+      '(-c --count)'{-c,--count}'[only print the number of matches in each file]'
+      '--depth[Search up to NUM directories deep, -1 for unlimited. Default is 25.]:number'
+      '(-F --fixed-strings)'{-F,--fixed-strings}'[alias for --literal for compatibility with grep]'
+    )
+  fi
+
+  if [[ $minor -le 28 ]];then
+    AG_OPTS+=(
+      '(--no-numbers)--no-numbers[don´t show line numbers]'
+    )
+  fi
+  if [[ $minor -gt 28 ]];then
+    AG_OPTS+=(
+      '(--nofilename --filename)'{--nofilename,--filename}'[Print file names. Default on, except when searching a single file.]'
+      '(--nonumbers --numbers)'{--nonumbers,--numbers}'[Print line numbers. Default is to omit line numbers when searching streams]'
+      '(-o --only-matching)'{-o,--only-matching}'[print only the matching part of the lines]'
+    )
+  fi
+}
+
+_ag() {
+  local curcontext="$curcontext" state line cmds update_policy ret=1
+
+  zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+  [[ -z "$update_policy" ]] && zstyle ":completion:${curcontext}:" cache-policy _ag_types_caching_policy
+
+  # Don't complete if command doesn't exist
+  [[ ${+commands[${words[1]}]} -eq 0 ]] && return 0
+
+  if ( [[ ${+AG_OPTS} -eq 0 ]] || _cache_invalid "_AG_OPTS" ) && ! _retrieve_cache "_AG_OPTS"; then
+    # Base opts starts at ag version 0.20
+    AG_OPTS=(
+      '(- 1 *)--help[print a short help statement]'
+      '(- 1 *)--man[print the manual page]'
+      '(- 1 *)--version[display version and copyright information]'
+      '--ackmate[output results in a format parseable by AckMate]'
+      '(-A --after)'{-A,--after}'[Print NUM lines before match. Default is 2]:number'
+      '(-t --all-text -a --all-types -u --unrestricted)'{-t,--all-text}"[search all text files, excluding hidden ones]"
+      '(-a --all-types -t --all-text -u --unrestricted)'{-a,--all-types}"[search all text files, excluding hidden ones and not obeying ignore files (.agignore, .gitignore...)]"
+      '(-B --before)'{-B,--before}'[Print NUM lines after match. Defaults is 2]:number'
+      '(--nobreak --break)'{--nobreak,--break}'[Print a newline between matches in different files. Default on.]'
+      '(--color --nocolor)--color[Print color codes in results. Default on.]'
+      '(--nocolor --color --color-line-number --color-match --color-path)--nocolor[Do not print color codes in results. Default on.]'
+      '(--nocolor)--color-line-number[Color codes for line numbers. Default is 1;33.]'
+      '(--nocolor)--color-match[Color codes for result match numbers. Default is 30;43.]'
+      '(--nocolor)--color-path[Color codes for path names. Default is 1;32.]'
+      '--column[print column numbers in results]'
+      '(-C --context)'{-C,--context}'[Print NUM lines before and after matches. Default is 2.]:number'
+      '(-D --debug)'{-D,--debug}'[enable debug logging]'
+      '(-G --file-search-regex)'{-G,--file-search-regex}'[only search file names matching PATTERN]:pattern'
+      '(-l --files-with-matches)'{-l,--files-with-matches}'[only print filenames containing matches, not matching lines]'
+      '(-L --files-without-matches)'{-L,--files-without-matches}"[only print filenames that don't contain matches]"
+      '(-f --follow)'{-f,--follow}'[follow symlinks]'
+      '(-g)-g[print filenames that match PATTERN]:pattern'
+      '(--nogroup --group)'{--nogroup,--group}'[same as --\[no\]break --\[no\]heading]'
+      '--hidden[search hidden files, still obeys ignore files.]'
+      '*--ignore[Ignore files/directories matching this pattern. Literal file and directory names are also allowed.]:files:_files'
+      '(-i --ignore-case)'{-i,--ignore-case}'[match case insensitively]:pattern'
+      '*--ignore-dir[alias for --ignore for compatibility with ack]:files:_files'
+      '(-v --invert-match)'{-v,--invert-match}'[invert match]'
+      '(-Q --literal)'{-Q,--literal}'[match PATTERN literally, no regular expression]'
+      '(-m --max-count)'{-m,--max-count}'[Skip the rest of a file after NUM matches. Default is 10,000.]:number'
+      '(--pager --nopager)'{--pager,--nopager}'[Display results with PAGER. Disabled by default.]:pager program:_command_names'
+      '(--passthrough)--passthrough[when searching a stream, print all lines even if they don''t match]'
+      '(-p --path-to-agignore)'{-p,--path-to-agignore}'[provide a path to a specific .agignore file]:files:_files'
+      '--print-long-lines[print matches on very long lines, > 2k characters by default]'
+      '--search-binary[search binary files]'
+      '(-U --skip-vcs-ignores)'{-U,--skip-vcs-ignores}'[ignore VCS ignore files (.gitigore, .hgignore, svn:ignore), but still use .agignore]'
+      '(-S --smart-case)'{-S,--smart-case}'[match case sensitively if PATTERN contains any uppercase letters, else match case insensitively]'
+      '--stats[print stats (files scanned, time taken, etc)]'
+      '(-u --unrestricted -t --all-text -a --all-types)'{-u,--unrestricted}'[search ALL files, includes: hidden, binary & ignored files (.agignore, .gitignore...)]'
+      '(-w --word-regexp)'{-w,--word-regexp}'[only match whole words]'
+    )
+    _ag_add_version_opts
+    AG_OPTS+=(
+      '*: :_files'
+    )
+    [[ $#AG_OPTS -gt 0 ]] && _store_cache '_AG_OPTS' AG_OPTS
+  fi
+
+  _arguments -C -s -S ${AG_OPTS} && ret=0
+  unset AG_OPTS
+
+  case $state in
+    # placeholder
+  esac
+
+  return ret
+}
+
+_ag_types_caching_policy() {
+  # Rebuild if .agignore more recent than cache.
+  [[ -f $HOME/.agignore && $$HOME/.agignore -nt "$1" ]] && return 0
+
+  # Rebuild if cache is older than one week.
+  local -a oldp
+  oldp=( "$1"(Nmw+1) )
+  (( $#oldp )) && return 0
+
+  return 1
+}
+
+_ag "$@"

+ 13 - 0
shell/zsh/completions/_tmuxinator

@@ -1,4 +1,17 @@
 #compdef tmuxinator mux
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for tmuxinator (https://github.com/tmuxinator/tmuxinator)
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Christopher Chow (https://github.com/Soliah)
+#
+# ------------------------------------------------------------------------------
 
 _tmuxinator() {
   local commands projects