summaryrefslogtreecommitdiffstats
path: root/complete/_rg
blob: 8455c80413f6b2367f6c0ae4a3975e3a9bd2e168 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#compdef rg

##
# zsh completion function for ripgrep
#
# Run ci/test_complete.sh after building to ensure that the options supported by
# this function stay in synch with the `rg` binary.
#
# @see https://github.com/zsh-users/zsh/blob/master/Etc/completion-style-guide
#
# Based on code from the zsh-users project — see copyright notice below.

_rg() {
  local state_descr ret curcontext="${curcontext:-}"
  local -a context line state
  local -A opt_args val_args
  local -a rg_args

  # Sort by long option name to match `rg --help`
  rg_args=(
    '(-A -C --after-context --context)'{-A+,--after-context=}'[specify lines to show after each match]:number of lines'
    '(-B -C --before-context --context)'{-B+,--before-context=}'[specify lines to show before each match]:number of lines'
    '(-i -s -S --ignore-case --case-sensitive --smart-case)'{-s,--case-sensitive}'[search case-sensitively]'
    '--color=[specify when to use colors in output]:when:( never auto always ansi )'
    '*--colors=[specify color settings and styles]: :->colorspec'
    '--column[show column numbers]'
    '(-A -B -C --after-context --before-context --context)'{-C+,--context=}'[specify lines to show before and after each match]:number of lines'
    '--context-separator=[specify string used to separate non-continuous context lines in output]:separator'
    '(-c --count --passthrough --passthru)'{-c,--count}'[only show count of matches for each file]'
    '--debug[show debug messages]'
    '--dfa-size-limit=[specify upper size limit of generated DFA]:DFA size'
    '(-E --encoding)'{-E+,--encoding=}'[specify text encoding of files to search]: :_rg_encodings'
    '*'{-f+,--file=}'[specify file containing patterns to search for]:file:_files'
    "(1)--files[show each file that would be searched (but don't search)]"
    '(-l --files-with-matches --files-without-match)'{-l,--files-with-matches}'[only show names of files with matches]'
    '(-l --files-with-matches --files-without-match)--files-without-match[only show names of files without matches]'
    '(-F --fixed-strings)'{-F,--fixed-strings}'[treat pattern as literal string instead of regular expression]'
    '(-L --follow)'{-L,--follow}'[follow symlinks]'
    '*'{-g+,--glob=}'[include or exclude files for searching that match the specified glob]:glob'
    '(: -)'{-h,--help}'[display help information]'
    '(-p --no-heading --pretty --vimgrep)--heading[show matches grouped by file name]'
    '--hidden[search hidden files and directories]'
    '*--iglob=[include or exclude files for searching that match the specified case-insensitive glob]:glob'
    '(-i -s -S --case-sensitive --ignore-case --smart-case)'{-i,--ignore-case}'[search case-insensitively]'
    '--ignore-file=[specify additional ignore file]:file:_files'
    '(-v --invert-match)'{-v,--invert-match}'[invert matching]'
    '(-n -N --line-number --no-line-number)'{-n,--line-number}'[show line numbers]'
    '(-N --no-line-number)--line-number-width=[specify width of displayed line number]:number of columns'
    '(-w -x --line-regexp --word-regexp)'{-x,--line-regexp}'[only show matches surrounded by line boundaries]'
    '(-M --max-columns)'{-M+,--max-columns=}'[specify max length of lines to print]:number of bytes'
    '(-m --max-count)'{-m+,--max-count=}'[specify max number of matches per file]:number of matches'
    '--max-filesize=[specify size above which files should be ignored]:file size'
    '--maxdepth=[specify max number of directories to descend]:number of directories'
    '(--mmap --no-mmap)--mmap[search using memory maps when possible]'
    '(-H --with-filename --no-filename)--no-filename[suppress all file names]'
    "(-p --heading --pretty --vimgrep)--no-heading[don't group matches by file name]"
    "(--no-ignore-parent)--no-ignore[don't respect ignore files]"
    "--no-ignore-parent[don't respect ignore files in parent directories]"
    "--no-ignore-vcs[don't respect version control ignore files]"
    '(-n -N --line-number --no-line-number)'{-N,--no-line-number}'[suppress line numbers]'
    '--no-messages[suppress all error messages]'
    "(--mmap --no-mmap)--no-mmap[don't search using memory maps]"
    '(-0 --null)'{-0,--null}'[print NUL byte after file names]'
    '(-o -r --only-matching --passthrough --passthru --replace)'{-o,--only-matching}'[show only matching part of each line]'
    '(-c -o -r --count --only-matching --passthrough --replace)--passthru[show both matching and non-matching lines]'
    '!(-c -o -r --count --only-matching --passthru --replace)--passthrough'
    '--path-separator=[specify path separator to use when printing file names]:separator'
    '(-p --heading --no-heading --pretty --vimgrep)'{-p,--pretty}'[alias for --color=always --heading -n]'
    '(-q --quiet)'{-q,--quiet}'[suppress normal output]'
    '--regex-size-limit=[specify upper size limit of compiled regex]:regex size'
    '(1 -f --file)*'{-e+,--regexp=}'[specify pattern]:pattern'
    '(-c -o -r --count --only-matching --passthrough --passthru --replace)'{-r+,--replace=}'[specify string used to replace matches]:replace string'
    '(-i -s -S --ignore-case --case-sensitive --smart-case)'{-S,--smart-case}'[search case-insensitively if the pattern is all lowercase]'
    '(-j --threads)--sort-files[sort results by file path (disables parallelism)]'
    '(-a --text)'{-a,--text}'[search binary files as if they were text]'
    '(-j --sort-files --threads)'{-j+,--threads=}'[specify approximate number of threads to use]:number of threads'
    '*'{-t+,--type=}'[only search files matching specified type]: :_rg_types'
    '*--type-add=[add new glob for file type]: :->typespec'
    '*--type-clear=[clear globs previously defined for specified file type]: :_rg_types'
    # This should actually be exclusive with everything but other type options
    '(:)--type-list[show all supported file types and their associated globs]'
    '*'{-T+,--type-not=}"[don't search files matching specified type]: :_rg_types"
    '*'{-u,--unrestricted}'[reduce level of "smart" searching]'
    '(: -)'{-V,--version}'[display version information]'
    '(-p --heading --no-heading --pretty)--vimgrep[show results in vim-compatible format]'
    '(-H --no-filename --with-filename)'{-H,--with-filename}'[display the file name for matches]'
    '(-w -x --line-regexp --word-regexp)'{-w,--word-regexp}'[only show matches surrounded by word boundaries]'
    '(-e -f --file --files --regexp --type-list)1: :_rg_pattern'
    '(--type-list)*:file:_files'
  )

  [[ ${_RG_COMPLETE_LIST_ARGS:-} == (1|t*|y*) ]] && {
    printf '%s\n' "${rg_args[@]}"
    return 0
  }

  _arguments -s -S : "${rg_args[@]}" && return 0

  while (( $#state )); do
    case "${state[1]}" in
      colorspec)
        # @todo I don't like this because it allows you to do weird things like
        # `line:line:bg:`. Also, i would like the `compadd -q` behaviour
        [[ -prefix *:none: ]] && return 1
        [[ -prefix *:*:*:* ]] && return 1

        _values -S ':' 'color/style type' \
          'column[specify coloring for column numbers]: :->attribute' \
          'line[specify coloring for line numbers]: :->attribute' \
          'match[specify coloring for match text]: :->attribute' \
          'path[specify color for file names]: :->attribute' && return 0

        [[ "${state}" == 'attribute' ]] &&
        _values -S ':' 'color/style attribute' \
          'none[clear color/style for type]' \
          'bg[specify background color]: :->color' \
          'fg[specify foreground color]: :->color' \
          'style[specify text style]: :->style' && return 0

        [[ "${state}" == 'color' ]] &&
        _values -S ':' 'color value' \
          black blue green red cyan magenta yellow white && return 0

        [[ "${state}" == 'style' ]] &&
        _values -S ':' 'style value' \
          bold nobold intense nointense && return 0
        ;;

      typespec)
        if compset -P '[^:]##:include:'; then
          _sequence -s ',' _rg_types && return 0
        # @todo This bit in particular could be better, but it's a little
        # complex, and attempting to solve it seems to run us up against a crash
        # bug — zsh # 40362
        elif compset -P '[^:]##:'; then
          _message 'glob or include directive' && return 1
        elif [[ ! -prefix *:* ]]; then
          _rg_types -qS ':' && return 0
        fi
        ;;
    esac
    shift state
  done

  return 1
}

# zsh 5.1 refuses to complete options if a 'match-less' operand like our pattern
# could be 'completed' instead. We can use _guard() to avoid this problem, but
# it introduces another one: zsh won't print the message if we try to complete
# the pattern after having passed `--`. To work around *that* problem, we can
# use this function to bypass the _guard() when `--` is on the command line.
# This is inaccurate (it'd get confused by e.g. `rg -e --`), but zsh's handling
# of `--` isn't accurate anyway
_rg_pattern() {
  if (( ${words[(I)--]} )); then
    _message 'pattern'
  else
    _guard '^-*' 'pattern'
  fi
}

# Complete encodings
_rg_encodings() {
  local -a expl
  local -aU _encodings

  # This is impossible to read, but these encodings rarely if ever change, so it
  # probably doesn't matter. They are derived from the list given here:
  # https://encoding.spec.whatwg.org/#concept-encoding-get
  _encodings=(
    {{,us-}ascii,arabic,chinese,cyrillic,greek{,8},hebrew,korean}
    logical visual mac {,cs}macintosh x-mac-{cyrillic,roman,ukrainian}
    866 ibm{819,866} csibm866
    big5{,-hkscs} {cn-,cs}big5 x-x-big5
    cp{819,866,125{0..8}} x-cp125{0..8}
    csiso2022{jp,kr} csiso8859{6,8}{e,i}
    csisolatin{{1..6},9} csisolatin{arabic,cyrillic,greek,hebrew}
    ecma-{114,118} asmo-708 elot_928 sun_eu_greek
    euc-{jp,kr} x-euc-jp cseuckr cseucpkdfmtjapanese
    {,x-}gbk csiso58gb231280 gb18030 {,cs}gb2312 gb_2312{,-80} hz-gb-2312
    iso-2022-{cn,cn-ext,jp,kr}
    iso8859{,-}{{1..11},13,14,15}
    iso-8859-{{1..11},{6,8}-{e,i},13,14,15,16} iso_8859-{{1..9},15}
    iso_8859-{1,2,6,7}:1987 iso_8859-{3,4,5,8}:1988 iso_8859-9:1989
    iso-ir-{58,100,101,109,110,126,127,138,144,148,149,157}
    koi{,8,8-r,8-ru,8-u,8_r} cskoi8r
    ks_c_5601-{1987,1989} ksc{,_}5691 csksc56011987
    latin{1..6} l{{1..6},9}
    shift{-,_}jis csshiftjis {,x-}sjis ms_kanji ms932
    utf{,-}8 utf-16{,be,le} unicode-1-1-utf-8
    windows-{31j,874,949,125{0..8}} dos-874 tis-620 ansi_x3.4-1968
    x-user-defined auto
  )

  _wanted rg-encodings expl 'encoding' compadd -a "${@}" - _encodings
}

# Complete file types
_rg_types() {
  local -a expl
  local -aU _types

  _types=( ${${(f)"$( _call_program rg-types rg --type-list )"}%%:*} )

  _wanted rg-types expl 'file type' compadd -a "${@}" - _types
}

_rg "${@}"

# ------------------------------------------------------------------------------
# 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 ripgrep
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
#  * arcizan <ghostrevery@gmail.com>
#  * MaskRay <i@maskray.me>
#
# ------------------------------------------------------------------------------

# Local Variables:
# mode: shell-script
# coding: utf-8-unix
# indent-tabs-mode: nil
# sh-indentation: 2
# sh-basic-offset: 2
# End:
# vim: ft=zsh sw=2 ts=2 et