My personal dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

_ag 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #compdef ag
  2. # ------------------------------------------------------------------------------
  3. # Copyright (c) 2015 Github zsh-users - http://github.com/zsh-users
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are met:
  8. # * Redistributions of source code must retain the above copyright
  9. # notice, this list of conditions and the following disclaimer.
  10. # * Redistributions in binary form must reproduce the above copyright
  11. # notice, this list of conditions and the following disclaimer in the
  12. # documentation and/or other materials provided with the distribution.
  13. # * Neither the name of the zsh-users nor the
  14. # names of its contributors may be used to endorse or promote products
  15. # derived from this software without specific prior written permission.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. # DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
  21. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. # ------------------------------------------------------------------------------
  28. # Description
  29. # -----------
  30. #
  31. # Completion script for ag (https://github.com/ggreer/the_silver_searcher)
  32. #
  33. # ------------------------------------------------------------------------------
  34. # Authors
  35. # -------
  36. #
  37. # * Akira Maeda <https://github.com/glidenote>
  38. #
  39. # ------------------------------------------------------------------------------
  40. # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
  41. # vim: ft=zsh sw=2 ts=2 et
  42. # ------------------------------------------------------------------------------
  43. _ag_version() {
  44. local version
  45. version=( $($words[1] --version) )
  46. version=${version[@]:2:1}
  47. version=( "${(@s/./)version}" )
  48. echo "${version[2]}"
  49. }
  50. # Dynamically build the file type completion
  51. # Modifies the global $AG_OPTS array
  52. _ag_add_file_types() {
  53. local typ exts
  54. for i in $($words[1] --list-file-types); do
  55. if [[ "${i:0:2}" = '--' ]]; then
  56. if [[ "${typ}x" != "x" ]]; then
  57. AG_OPTS+="${typ}[${exts}]"
  58. fi
  59. typ=$i
  60. exts=
  61. else
  62. exts+=$i
  63. fi
  64. done
  65. AG_OPTS+="${typ}[${exts}]"
  66. }
  67. # Add version appropriate options above base
  68. # Modifies the global $AG_OPTS array
  69. _ag_add_version_opts() {
  70. local minor=$(_ag_version)
  71. if [[ $minor -gt 21 ]];then
  72. _ag_add_file_types
  73. AG_OPTS+=(
  74. '(- 1 *)--list-file-types[list supported filetypes to search]'
  75. '--silent[suppress all log messages, including errors]'
  76. )
  77. fi
  78. if [[ $minor -gt 22 ]];then
  79. AG_OPTS+=(
  80. '(-z --search-zip)'{-z,--search-zip}'[search contents of compressed files]'
  81. )
  82. fi
  83. if [[ $minor -le 24 ]];then
  84. AG_OPTS+=(
  85. '(-s --case-sensitive)'{-s,--case-sensitive}'[match case sensitively]'
  86. '(--noheading --heading)'{--noheading,--heading}'[print file names above matching contents]'
  87. )
  88. fi
  89. if [[ $minor -gt 24 ]];then
  90. AG_OPTS+=(
  91. '(-s --case-sensitive)'{-s,--case-sensitive}'[Match case sensitively. Default on.]'
  92. '(-H --noheading --heading)'{-H,--noheading,--heading}'[print file names above matching contents]'
  93. '--vimgrep[output results like vim''s, :vimgrep /pattern/g would (report every match on the line)]'
  94. )
  95. fi
  96. if [[ $minor -gt 26 ]];then
  97. AG_OPTS+=(
  98. '(-0 --null --print0)'{-0,--null,--print0}'[separate the filenames with \\0, rather than \\n]'
  99. )
  100. fi
  101. if [[ $minor -le 27 ]];then
  102. AG_OPTS+=(
  103. '--depth[Search up to NUM directories deep. Default is 25.]:number'
  104. )
  105. fi
  106. if [[ $minor -gt 27 ]];then
  107. AG_OPTS+=(
  108. '(-c --count)'{-c,--count}'[only print the number of matches in each file]'
  109. '--depth[Search up to NUM directories deep, -1 for unlimited. Default is 25.]:number'
  110. '(-F --fixed-strings)'{-F,--fixed-strings}'[alias for --literal for compatibility with grep]'
  111. )
  112. fi
  113. if [[ $minor -le 28 ]];then
  114. AG_OPTS+=(
  115. '(--no-numbers)--no-numbers[don´t show line numbers]'
  116. )
  117. fi
  118. if [[ $minor -gt 28 ]];then
  119. AG_OPTS+=(
  120. '(--nofilename --filename)'{--nofilename,--filename}'[Print file names. Default on, except when searching a single file.]'
  121. '(--nonumbers --numbers)'{--nonumbers,--numbers}'[Print line numbers. Default is to omit line numbers when searching streams]'
  122. '(-o --only-matching)'{-o,--only-matching}'[print only the matching part of the lines]'
  123. )
  124. fi
  125. }
  126. _ag() {
  127. local curcontext="$curcontext" state line cmds update_policy ret=1
  128. zstyle -s ":completion:${curcontext}:" cache-policy update_policy
  129. [[ -z "$update_policy" ]] && zstyle ":completion:${curcontext}:" cache-policy _ag_types_caching_policy
  130. # Don't complete if command doesn't exist
  131. [[ ${+commands[${words[1]}]} -eq 0 ]] && return 0
  132. if ( [[ ${+AG_OPTS} -eq 0 ]] || _cache_invalid "_AG_OPTS" ) && ! _retrieve_cache "_AG_OPTS"; then
  133. # Base opts starts at ag version 0.20
  134. AG_OPTS=(
  135. '(- 1 *)--help[print a short help statement]'
  136. '(- 1 *)--man[print the manual page]'
  137. '(- 1 *)--version[display version and copyright information]'
  138. '--ackmate[output results in a format parseable by AckMate]'
  139. '(-A --after)'{-A,--after}'[Print NUM lines before match. Default is 2]:number'
  140. '(-t --all-text -a --all-types -u --unrestricted)'{-t,--all-text}"[search all text files, excluding hidden ones]"
  141. '(-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...)]"
  142. '(-B --before)'{-B,--before}'[Print NUM lines after match. Defaults is 2]:number'
  143. '(--nobreak --break)'{--nobreak,--break}'[Print a newline between matches in different files. Default on.]'
  144. '(--color --nocolor)--color[Print color codes in results. Default on.]'
  145. '(--nocolor --color --color-line-number --color-match --color-path)--nocolor[Do not print color codes in results. Default on.]'
  146. '(--nocolor)--color-line-number[Color codes for line numbers. Default is 1;33.]'
  147. '(--nocolor)--color-match[Color codes for result match numbers. Default is 30;43.]'
  148. '(--nocolor)--color-path[Color codes for path names. Default is 1;32.]'
  149. '--column[print column numbers in results]'
  150. '(-C --context)'{-C,--context}'[Print NUM lines before and after matches. Default is 2.]:number'
  151. '(-D --debug)'{-D,--debug}'[enable debug logging]'
  152. '(-G --file-search-regex)'{-G,--file-search-regex}'[only search file names matching PATTERN]:pattern'
  153. '(-l --files-with-matches)'{-l,--files-with-matches}'[only print filenames containing matches, not matching lines]'
  154. '(-L --files-without-matches)'{-L,--files-without-matches}"[only print filenames that don't contain matches]"
  155. '(-f --follow)'{-f,--follow}'[follow symlinks]'
  156. '(-g)-g[print filenames that match PATTERN]:pattern'
  157. '(--nogroup --group)'{--nogroup,--group}'[same as --\[no\]break --\[no\]heading]'
  158. '--hidden[search hidden files, still obeys ignore files.]'
  159. '*--ignore[Ignore files/directories matching this pattern. Literal file and directory names are also allowed.]:files:_files'
  160. '(-i --ignore-case)'{-i,--ignore-case}'[match case insensitively]:pattern'
  161. '*--ignore-dir[alias for --ignore for compatibility with ack]:files:_files'
  162. '(-v --invert-match)'{-v,--invert-match}'[invert match]'
  163. '(-Q --literal)'{-Q,--literal}'[match PATTERN literally, no regular expression]'
  164. '(-m --max-count)'{-m,--max-count}'[Skip the rest of a file after NUM matches. Default is 10,000.]:number'
  165. '(--pager --nopager)'{--pager,--nopager}'[Display results with PAGER. Disabled by default.]:pager program:_command_names'
  166. '(--passthrough)--passthrough[when searching a stream, print all lines even if they don''t match]'
  167. '(-p --path-to-agignore)'{-p,--path-to-agignore}'[provide a path to a specific .agignore file]:files:_files'
  168. '--print-long-lines[print matches on very long lines, > 2k characters by default]'
  169. '--search-binary[search binary files]'
  170. '(-U --skip-vcs-ignores)'{-U,--skip-vcs-ignores}'[ignore VCS ignore files (.gitigore, .hgignore, svn:ignore), but still use .agignore]'
  171. '(-S --smart-case)'{-S,--smart-case}'[match case sensitively if PATTERN contains any uppercase letters, else match case insensitively]'
  172. '--stats[print stats (files scanned, time taken, etc)]'
  173. '(-u --unrestricted -t --all-text -a --all-types)'{-u,--unrestricted}'[search ALL files, includes: hidden, binary & ignored files (.agignore, .gitignore...)]'
  174. '(-w --word-regexp)'{-w,--word-regexp}'[only match whole words]'
  175. )
  176. _ag_add_version_opts
  177. AG_OPTS+=(
  178. '*: :_files'
  179. )
  180. [[ $#AG_OPTS -gt 0 ]] && _store_cache '_AG_OPTS' AG_OPTS
  181. fi
  182. _arguments -C -s -S ${AG_OPTS} && ret=0
  183. unset AG_OPTS
  184. case $state in
  185. # placeholder
  186. esac
  187. return ret
  188. }
  189. _ag_types_caching_policy() {
  190. # Rebuild if .agignore more recent than cache.
  191. [[ -f $HOME/.agignore && $$HOME/.agignore -nt "$1" ]] && return 0
  192. # Rebuild if cache is older than one week.
  193. local -a oldp
  194. oldp=( "$1"(Nmw+1) )
  195. (( $#oldp )) && return 0
  196. return 1
  197. }
  198. _ag "$@"