doing 2.0.18 → 2.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/Gemfile.lock +15 -5
  4. data/README.md +1 -1
  5. data/bin/doing +2 -18
  6. data/doing.gemspec +5 -4
  7. data/doing.rdoc +2 -2
  8. data/generate_completions.sh +3 -3
  9. data/lib/doing/cli_status.rb +6 -2
  10. data/lib/doing/completion/bash_completion.rb +185 -0
  11. data/lib/doing/completion/fish_completion.rb +175 -0
  12. data/lib/doing/completion/string.rb +17 -0
  13. data/lib/doing/completion/zsh_completion.rb +140 -0
  14. data/lib/doing/completion.rb +39 -0
  15. data/lib/doing/version.rb +1 -1
  16. data/lib/doing/wwid.rb +18 -6
  17. data/lib/doing.rb +1 -1
  18. data/lib/helpers/fzf/.goreleaser.yml +119 -0
  19. data/lib/helpers/fzf/.rubocop.yml +28 -0
  20. data/lib/helpers/fzf/ADVANCED.md +565 -0
  21. data/lib/helpers/fzf/BUILD.md +49 -0
  22. data/lib/helpers/fzf/CHANGELOG.md +1193 -0
  23. data/lib/helpers/fzf/Dockerfile +11 -0
  24. data/lib/helpers/fzf/LICENSE +21 -0
  25. data/lib/helpers/fzf/Makefile +166 -0
  26. data/lib/helpers/fzf/README-VIM.md +486 -0
  27. data/lib/helpers/fzf/README.md +712 -0
  28. data/lib/helpers/fzf/bin/fzf-tmux +233 -0
  29. data/lib/helpers/fzf/doc/fzf.txt +512 -0
  30. data/lib/helpers/fzf/go.mod +17 -0
  31. data/lib/helpers/fzf/go.sum +31 -0
  32. data/lib/helpers/fzf/install +382 -0
  33. data/lib/helpers/fzf/install.ps1 +65 -0
  34. data/lib/helpers/fzf/main.go +14 -0
  35. data/lib/helpers/fzf/man/man1/fzf-tmux.1 +68 -0
  36. data/lib/helpers/fzf/man/man1/fzf.1 +1001 -0
  37. data/lib/helpers/fzf/plugin/fzf.vim +1048 -0
  38. data/lib/helpers/fzf/shell/completion.bash +381 -0
  39. data/lib/helpers/fzf/shell/completion.zsh +329 -0
  40. data/lib/helpers/fzf/shell/key-bindings.bash +96 -0
  41. data/lib/helpers/fzf/shell/key-bindings.fish +172 -0
  42. data/lib/helpers/fzf/shell/key-bindings.zsh +114 -0
  43. data/lib/helpers/fzf/src/LICENSE +21 -0
  44. data/lib/helpers/fzf/src/algo/algo.go +884 -0
  45. data/lib/helpers/fzf/src/algo/algo_test.go +197 -0
  46. data/lib/helpers/fzf/src/algo/normalize.go +492 -0
  47. data/lib/helpers/fzf/src/ansi.go +409 -0
  48. data/lib/helpers/fzf/src/ansi_test.go +427 -0
  49. data/lib/helpers/fzf/src/cache.go +81 -0
  50. data/lib/helpers/fzf/src/cache_test.go +39 -0
  51. data/lib/helpers/fzf/src/chunklist.go +89 -0
  52. data/lib/helpers/fzf/src/chunklist_test.go +80 -0
  53. data/lib/helpers/fzf/src/constants.go +85 -0
  54. data/lib/helpers/fzf/src/core.go +351 -0
  55. data/lib/helpers/fzf/src/history.go +96 -0
  56. data/lib/helpers/fzf/src/history_test.go +68 -0
  57. data/lib/helpers/fzf/src/item.go +44 -0
  58. data/lib/helpers/fzf/src/item_test.go +23 -0
  59. data/lib/helpers/fzf/src/matcher.go +235 -0
  60. data/lib/helpers/fzf/src/merger.go +120 -0
  61. data/lib/helpers/fzf/src/merger_test.go +88 -0
  62. data/lib/helpers/fzf/src/options.go +1691 -0
  63. data/lib/helpers/fzf/src/options_test.go +457 -0
  64. data/lib/helpers/fzf/src/pattern.go +425 -0
  65. data/lib/helpers/fzf/src/pattern_test.go +209 -0
  66. data/lib/helpers/fzf/src/protector/protector.go +8 -0
  67. data/lib/helpers/fzf/src/protector/protector_openbsd.go +10 -0
  68. data/lib/helpers/fzf/src/reader.go +201 -0
  69. data/lib/helpers/fzf/src/reader_test.go +63 -0
  70. data/lib/helpers/fzf/src/result.go +243 -0
  71. data/lib/helpers/fzf/src/result_others.go +16 -0
  72. data/lib/helpers/fzf/src/result_test.go +159 -0
  73. data/lib/helpers/fzf/src/result_x86.go +16 -0
  74. data/lib/helpers/fzf/src/terminal.go +2832 -0
  75. data/lib/helpers/fzf/src/terminal_test.go +638 -0
  76. data/lib/helpers/fzf/src/terminal_unix.go +26 -0
  77. data/lib/helpers/fzf/src/terminal_windows.go +45 -0
  78. data/lib/helpers/fzf/src/tokenizer.go +253 -0
  79. data/lib/helpers/fzf/src/tokenizer_test.go +112 -0
  80. data/lib/helpers/fzf/src/tui/dummy.go +46 -0
  81. data/lib/helpers/fzf/src/tui/light.go +987 -0
  82. data/lib/helpers/fzf/src/tui/light_unix.go +110 -0
  83. data/lib/helpers/fzf/src/tui/light_windows.go +145 -0
  84. data/lib/helpers/fzf/src/tui/tcell.go +721 -0
  85. data/lib/helpers/fzf/src/tui/tcell_test.go +392 -0
  86. data/lib/helpers/fzf/src/tui/ttyname_unix.go +47 -0
  87. data/lib/helpers/fzf/src/tui/ttyname_windows.go +14 -0
  88. data/lib/helpers/fzf/src/tui/tui.go +625 -0
  89. data/lib/helpers/fzf/src/tui/tui_test.go +20 -0
  90. data/lib/helpers/fzf/src/util/atomicbool.go +34 -0
  91. data/lib/helpers/fzf/src/util/atomicbool_test.go +17 -0
  92. data/lib/helpers/fzf/src/util/chars.go +198 -0
  93. data/lib/helpers/fzf/src/util/chars_test.go +46 -0
  94. data/lib/helpers/fzf/src/util/eventbox.go +96 -0
  95. data/lib/helpers/fzf/src/util/eventbox_test.go +61 -0
  96. data/lib/helpers/fzf/src/util/slab.go +12 -0
  97. data/lib/helpers/fzf/src/util/util.go +138 -0
  98. data/lib/helpers/fzf/src/util/util_test.go +40 -0
  99. data/lib/helpers/fzf/src/util/util_unix.go +47 -0
  100. data/lib/helpers/fzf/src/util/util_windows.go +83 -0
  101. data/lib/helpers/fzf/test/fzf.vader +175 -0
  102. data/lib/helpers/fzf/test/test_go.rb +2626 -0
  103. data/lib/helpers/fzf/uninstall +117 -0
  104. data/scripts/generate_bash_completions.rb +6 -12
  105. data/scripts/generate_fish_completions.rb +7 -16
  106. data/scripts/generate_zsh_completions.rb +6 -15
  107. metadata +144 -9
@@ -0,0 +1,381 @@
1
+ # ____ ____
2
+ # / __/___ / __/
3
+ # / /_/_ / / /_
4
+ # / __/ / /_/ __/
5
+ # /_/ /___/_/ completion.bash
6
+ #
7
+ # - $FZF_TMUX (default: 0)
8
+ # - $FZF_TMUX_OPTS (default: empty)
9
+ # - $FZF_COMPLETION_TRIGGER (default: '**')
10
+ # - $FZF_COMPLETION_OPTS (default: empty)
11
+
12
+ if [[ $- =~ i ]]; then
13
+
14
+ # To use custom commands instead of find, override _fzf_compgen_{path,dir}
15
+ if ! declare -f _fzf_compgen_path > /dev/null; then
16
+ _fzf_compgen_path() {
17
+ echo "$1"
18
+ command find -L "$1" \
19
+ -name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
20
+ -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
21
+ }
22
+ fi
23
+
24
+ if ! declare -f _fzf_compgen_dir > /dev/null; then
25
+ _fzf_compgen_dir() {
26
+ command find -L "$1" \
27
+ -name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
28
+ -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
29
+ }
30
+ fi
31
+
32
+ ###########################################################
33
+
34
+ # To redraw line after fzf closes (printf '\e[5n')
35
+ bind '"\e[0n": redraw-current-line' 2> /dev/null
36
+
37
+ __fzf_comprun() {
38
+ if [[ "$(type -t _fzf_comprun 2>&1)" = function ]]; then
39
+ _fzf_comprun "$@"
40
+ elif [[ -n "$TMUX_PANE" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "$FZF_TMUX_OPTS" ]]; }; then
41
+ shift
42
+ fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- "$@"
43
+ else
44
+ shift
45
+ fzf "$@"
46
+ fi
47
+ }
48
+
49
+ __fzf_orig_completion() {
50
+ local l comp f cmd
51
+ while read -r l; do
52
+ if [[ "$l" =~ ^(.*\ -F)\ *([^ ]*).*\ ([^ ]*)$ ]]; then
53
+ comp="${BASH_REMATCH[1]}"
54
+ f="${BASH_REMATCH[2]}"
55
+ cmd="${BASH_REMATCH[3]}"
56
+ [[ "$f" = _fzf_* ]] && continue
57
+ printf -v "_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}" "%s" "${comp} %s ${cmd} #${f}"
58
+ if [[ "$l" = *" -o nospace "* ]] && [[ ! "$__fzf_nospace_commands" = *" $cmd "* ]]; then
59
+ __fzf_nospace_commands="$__fzf_nospace_commands $cmd "
60
+ fi
61
+ fi
62
+ done
63
+ }
64
+
65
+ _fzf_opts_completion() {
66
+ local cur prev opts
67
+ COMPREPLY=()
68
+ cur="${COMP_WORDS[COMP_CWORD]}"
69
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
70
+ opts="
71
+ -x --extended
72
+ -e --exact
73
+ --algo
74
+ -i +i
75
+ -n --nth
76
+ --with-nth
77
+ -d --delimiter
78
+ +s --no-sort
79
+ --tac
80
+ --tiebreak
81
+ -m --multi
82
+ --no-mouse
83
+ --bind
84
+ --cycle
85
+ --no-hscroll
86
+ --jump-labels
87
+ --height
88
+ --literal
89
+ --reverse
90
+ --margin
91
+ --inline-info
92
+ --prompt
93
+ --pointer
94
+ --marker
95
+ --header
96
+ --header-lines
97
+ --ansi
98
+ --tabstop
99
+ --color
100
+ --no-bold
101
+ --history
102
+ --history-size
103
+ --preview
104
+ --preview-window
105
+ -q --query
106
+ -1 --select-1
107
+ -0 --exit-0
108
+ -f --filter
109
+ --print-query
110
+ --expect
111
+ --sync"
112
+
113
+ case "${prev}" in
114
+ --tiebreak)
115
+ COMPREPLY=( $(compgen -W "length begin end index" -- "$cur") )
116
+ return 0
117
+ ;;
118
+ --color)
119
+ COMPREPLY=( $(compgen -W "dark light 16 bw" -- "$cur") )
120
+ return 0
121
+ ;;
122
+ --history)
123
+ COMPREPLY=()
124
+ return 0
125
+ ;;
126
+ esac
127
+
128
+ if [[ "$cur" =~ ^-|\+ ]]; then
129
+ COMPREPLY=( $(compgen -W "${opts}" -- "$cur") )
130
+ return 0
131
+ fi
132
+
133
+ return 0
134
+ }
135
+
136
+ _fzf_handle_dynamic_completion() {
137
+ local cmd orig_var orig ret orig_cmd orig_complete
138
+ cmd="$1"
139
+ shift
140
+ orig_cmd="$1"
141
+ orig_var="_fzf_orig_completion_$cmd"
142
+ orig="${!orig_var##*#}"
143
+ if [[ -n "$orig" ]] && type "$orig" > /dev/null 2>&1; then
144
+ $orig "$@"
145
+ elif [[ -n "$_fzf_completion_loader" ]]; then
146
+ orig_complete=$(complete -p "$orig_cmd" 2> /dev/null)
147
+ _completion_loader "$@"
148
+ ret=$?
149
+ # _completion_loader may not have updated completion for the command
150
+ if [[ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]]; then
151
+ __fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null)
152
+ if [[ "$__fzf_nospace_commands" = *" $orig_cmd "* ]]; then
153
+ eval "${orig_complete/ -F / -o nospace -F }"
154
+ else
155
+ eval "$orig_complete"
156
+ fi
157
+ fi
158
+ return $ret
159
+ fi
160
+ }
161
+
162
+ __fzf_generic_path_completion() {
163
+ local cur base dir leftover matches trigger cmd
164
+ cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
165
+ COMPREPLY=()
166
+ trigger=${FZF_COMPLETION_TRIGGER-'**'}
167
+ cur="${COMP_WORDS[COMP_CWORD]}"
168
+ if [[ "$cur" == *"$trigger" ]]; then
169
+ base=${cur:0:${#cur}-${#trigger}}
170
+ eval "base=$base"
171
+
172
+ [[ $base = *"/"* ]] && dir="$base"
173
+ while true; do
174
+ if [[ -z "$dir" ]] || [[ -d "$dir" ]]; then
175
+ leftover=${base/#"$dir"}
176
+ leftover=${leftover/#\/}
177
+ [[ -z "$dir" ]] && dir='.'
178
+ [[ "$dir" != "/" ]] && dir="${dir/%\//}"
179
+ matches=$(eval "$1 $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $2" __fzf_comprun "$4" -q "$leftover" | while read -r item; do
180
+ printf "%q$3 " "$item"
181
+ done)
182
+ matches=${matches% }
183
+ [[ -z "$3" ]] && [[ "$__fzf_nospace_commands" = *" ${COMP_WORDS[0]} "* ]] && matches="$matches "
184
+ if [[ -n "$matches" ]]; then
185
+ COMPREPLY=( "$matches" )
186
+ else
187
+ COMPREPLY=( "$cur" )
188
+ fi
189
+ printf '\e[5n'
190
+ return 0
191
+ fi
192
+ dir=$(dirname "$dir")
193
+ [[ "$dir" =~ /$ ]] || dir="$dir"/
194
+ done
195
+ else
196
+ shift
197
+ shift
198
+ shift
199
+ _fzf_handle_dynamic_completion "$cmd" "$@"
200
+ fi
201
+ }
202
+
203
+ _fzf_complete() {
204
+ # Split arguments around --
205
+ local args rest str_arg i sep
206
+ args=("$@")
207
+ sep=
208
+ for i in "${!args[@]}"; do
209
+ if [[ "${args[$i]}" = -- ]]; then
210
+ sep=$i
211
+ break
212
+ fi
213
+ done
214
+ if [[ -n "$sep" ]]; then
215
+ str_arg=
216
+ rest=("${args[@]:$((sep + 1)):${#args[@]}}")
217
+ args=("${args[@]:0:$sep}")
218
+ else
219
+ str_arg=$1
220
+ args=()
221
+ shift
222
+ rest=("$@")
223
+ fi
224
+
225
+ local cur selected trigger cmd post
226
+ post="$(caller 0 | awk '{print $2}')_post"
227
+ type -t "$post" > /dev/null 2>&1 || post=cat
228
+
229
+ cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
230
+ trigger=${FZF_COMPLETION_TRIGGER-'**'}
231
+ cur="${COMP_WORDS[COMP_CWORD]}"
232
+ if [[ "$cur" == *"$trigger" ]]; then
233
+ cur=${cur:0:${#cur}-${#trigger}}
234
+
235
+ selected=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "${rest[0]}" "${args[@]}" -q "$cur" | $post | tr '\n' ' ')
236
+ selected=${selected% } # Strip trailing space not to repeat "-o nospace"
237
+ if [[ -n "$selected" ]]; then
238
+ COMPREPLY=("$selected")
239
+ else
240
+ COMPREPLY=("$cur")
241
+ fi
242
+ printf '\e[5n'
243
+ return 0
244
+ else
245
+ _fzf_handle_dynamic_completion "$cmd" "${rest[@]}"
246
+ fi
247
+ }
248
+
249
+ _fzf_path_completion() {
250
+ __fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@"
251
+ }
252
+
253
+ # Deprecated. No file only completion.
254
+ _fzf_file_completion() {
255
+ _fzf_path_completion "$@"
256
+ }
257
+
258
+ _fzf_dir_completion() {
259
+ __fzf_generic_path_completion _fzf_compgen_dir "" "/" "$@"
260
+ }
261
+
262
+ _fzf_complete_kill() {
263
+ local trigger=${FZF_COMPLETION_TRIGGER-'**'}
264
+ local cur="${COMP_WORDS[COMP_CWORD]}"
265
+ if [[ -z "$cur" ]]; then
266
+ COMP_WORDS[$COMP_CWORD]=$trigger
267
+ elif [[ "$cur" != *"$trigger" ]]; then
268
+ return 1
269
+ fi
270
+
271
+ _fzf_proc_completion "$@"
272
+ }
273
+
274
+ _fzf_proc_completion() {
275
+ _fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap --min-height 15 -- "$@" < <(
276
+ command ps -ef | sed 1d
277
+ )
278
+ }
279
+
280
+ _fzf_proc_completion_post() {
281
+ awk '{print $2}'
282
+ }
283
+
284
+ _fzf_host_completion() {
285
+ _fzf_complete +m -- "$@" < <(
286
+ command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?]') \
287
+ <(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
288
+ <(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
289
+ awk '{if (length($2) > 0) {print $2}}' | sort -u
290
+ )
291
+ }
292
+
293
+ _fzf_var_completion() {
294
+ _fzf_complete -m -- "$@" < <(
295
+ declare -xp | sed 's/=.*//' | sed 's/.* //'
296
+ )
297
+ }
298
+
299
+ _fzf_alias_completion() {
300
+ _fzf_complete -m -- "$@" < <(
301
+ alias | sed 's/=.*//' | sed 's/.* //'
302
+ )
303
+ }
304
+
305
+ # fzf options
306
+ complete -o default -F _fzf_opts_completion fzf
307
+
308
+ d_cmds="${FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir}"
309
+ a_cmds="
310
+ awk cat diff diff3
311
+ emacs emacsclient ex file ftp g++ gcc gvim head hg java
312
+ javac ld less more mvim nvim patch perl python ruby
313
+ sed sftp sort source tail tee uniq vi view vim wc xdg-open
314
+ basename bunzip2 bzip2 chmod chown curl cp dirname du
315
+ find git grep gunzip gzip hg jar
316
+ ln ls mv open rm rsync scp
317
+ svn tar unzip zip"
318
+
319
+ # Preserve existing completion
320
+ __fzf_orig_completion < <(complete -p $d_cmds $a_cmds 2> /dev/null)
321
+
322
+ if type _completion_loader > /dev/null 2>&1; then
323
+ _fzf_completion_loader=1
324
+ fi
325
+
326
+ __fzf_defc() {
327
+ local cmd func opts orig_var orig def
328
+ cmd="$1"
329
+ func="$2"
330
+ opts="$3"
331
+ orig_var="_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}"
332
+ orig="${!orig_var}"
333
+ if [[ -n "$orig" ]]; then
334
+ printf -v def "$orig" "$func"
335
+ eval "$def"
336
+ else
337
+ complete -F "$func" $opts "$cmd"
338
+ fi
339
+ }
340
+
341
+ # Anything
342
+ for cmd in $a_cmds; do
343
+ __fzf_defc "$cmd" _fzf_path_completion "-o default -o bashdefault"
344
+ done
345
+
346
+ # Directory
347
+ for cmd in $d_cmds; do
348
+ __fzf_defc "$cmd" _fzf_dir_completion "-o nospace -o dirnames"
349
+ done
350
+
351
+ # Kill completion (supports empty completion trigger)
352
+ complete -F _fzf_complete_kill -o default -o bashdefault kill
353
+
354
+ unset cmd d_cmds a_cmds
355
+
356
+ _fzf_setup_completion() {
357
+ local kind fn cmd
358
+ kind=$1
359
+ fn=_fzf_${1}_completion
360
+ if [[ $# -lt 2 ]] || ! type -t "$fn" > /dev/null; then
361
+ echo "usage: ${FUNCNAME[0]} path|dir|var|alias|host|proc COMMANDS..."
362
+ return 1
363
+ fi
364
+ shift
365
+ __fzf_orig_completion < <(complete -p "$@" 2> /dev/null)
366
+ for cmd in "$@"; do
367
+ case "$kind" in
368
+ dir) __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
369
+ var) __fzf_defc "$cmd" "$fn" "-o default -o nospace -v" ;;
370
+ alias) __fzf_defc "$cmd" "$fn" "-a" ;;
371
+ *) __fzf_defc "$cmd" "$fn" "-o default -o bashdefault" ;;
372
+ esac
373
+ done
374
+ }
375
+
376
+ # Environment variables / Aliases / Hosts
377
+ _fzf_setup_completion 'var' export unset
378
+ _fzf_setup_completion 'alias' unalias
379
+ _fzf_setup_completion 'host' ssh telnet
380
+
381
+ fi
@@ -0,0 +1,329 @@
1
+ # ____ ____
2
+ # / __/___ / __/
3
+ # / /_/_ / / /_
4
+ # / __/ / /_/ __/
5
+ # /_/ /___/_/ completion.zsh
6
+ #
7
+ # - $FZF_TMUX (default: 0)
8
+ # - $FZF_TMUX_OPTS (default: '-d 40%')
9
+ # - $FZF_COMPLETION_TRIGGER (default: '**')
10
+ # - $FZF_COMPLETION_OPTS (default: empty)
11
+
12
+ # Both branches of the following `if` do the same thing -- define
13
+ # __fzf_completion_options such that `eval $__fzf_completion_options` sets
14
+ # all options to the same values they currently have. We'll do just that at
15
+ # the bottom of the file after changing options to what we prefer.
16
+ #
17
+ # IMPORTANT: Until we get to the `emulate` line, all words that *can* be quoted
18
+ # *must* be quoted in order to prevent alias expansion. In addition, code must
19
+ # be written in a way works with any set of zsh options. This is very tricky, so
20
+ # careful when you change it.
21
+ #
22
+ # Start by loading the builtin zsh/parameter module. It provides `options`
23
+ # associative array that stores current shell options.
24
+ if 'zmodload' 'zsh/parameter' 2>'/dev/null' && (( ${+options} )); then
25
+ # This is the fast branch and it gets taken on virtually all Zsh installations.
26
+ #
27
+ # ${(kv)options[@]} expands to array of keys (option names) and values ("on"
28
+ # or "off"). The subsequent expansion# with (j: :) flag joins all elements
29
+ # together separated by spaces. __fzf_completion_options ends up with a value
30
+ # like this: "options=(shwordsplit off aliases on ...)".
31
+ __fzf_completion_options="options=(${(j: :)${(kv)options[@]}})"
32
+ else
33
+ # This branch is much slower because it forks to get the names of all
34
+ # zsh options. It's possible to eliminate this fork but it's not worth the
35
+ # trouble because this branch gets taken only on very ancient or broken
36
+ # zsh installations.
37
+ () {
38
+ # That `()` above defines an anonymous function. This is essentially a scope
39
+ # for local parameters. We use it to avoid polluting global scope.
40
+ 'local' '__fzf_opt'
41
+ __fzf_completion_options="setopt"
42
+ # `set -o` prints one line for every zsh option. Each line contains option
43
+ # name, some spaces, and then either "on" or "off". We just want option names.
44
+ # Expansion with (@f) flag splits a string into lines. The outer expansion
45
+ # removes spaces and everything that follow them on every line. __fzf_opt
46
+ # ends up iterating over option names: shwordsplit, aliases, etc.
47
+ for __fzf_opt in "${(@)${(@f)$(set -o)}%% *}"; do
48
+ if [[ -o "$__fzf_opt" ]]; then
49
+ # Option $__fzf_opt is currently on, so remember to set it back on.
50
+ __fzf_completion_options+=" -o $__fzf_opt"
51
+ else
52
+ # Option $__fzf_opt is currently off, so remember to set it back off.
53
+ __fzf_completion_options+=" +o $__fzf_opt"
54
+ fi
55
+ done
56
+ # The value of __fzf_completion_options here looks like this:
57
+ # "setopt +o shwordsplit -o aliases ..."
58
+ }
59
+ fi
60
+
61
+ # Enable the default zsh options (those marked with <Z> in `man zshoptions`)
62
+ # but without `aliases`. Aliases in functions are expanded when functions are
63
+ # defined, so if we disable aliases here, we'll be sure to have no pesky
64
+ # aliases in any of our functions. This way we won't need prefix every
65
+ # command with `command` or to quote every word to defend against global
66
+ # aliases. Note that `aliases` is not the only option that's important to
67
+ # control. There are several others that could wreck havoc if they are set
68
+ # to values we don't expect. With the following `emulate` command we
69
+ # sidestep this issue entirely.
70
+ 'emulate' 'zsh' '-o' 'no_aliases'
71
+
72
+ # This brace is the start of try-always block. The `always` part is like
73
+ # `finally` in lesser languages. We use it to *always* restore user options.
74
+ {
75
+
76
+ # Bail out if not interactive shell.
77
+ [[ -o interactive ]] || return 0
78
+
79
+ # To use custom commands instead of find, override _fzf_compgen_{path,dir}
80
+ if ! declare -f _fzf_compgen_path > /dev/null; then
81
+ _fzf_compgen_path() {
82
+ echo "$1"
83
+ command find -L "$1" \
84
+ -name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
85
+ -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
86
+ }
87
+ fi
88
+
89
+ if ! declare -f _fzf_compgen_dir > /dev/null; then
90
+ _fzf_compgen_dir() {
91
+ command find -L "$1" \
92
+ -name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
93
+ -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
94
+ }
95
+ fi
96
+
97
+ ###########################################################
98
+
99
+ __fzf_comprun() {
100
+ if [[ "$(type _fzf_comprun 2>&1)" =~ function ]]; then
101
+ _fzf_comprun "$@"
102
+ elif [ -n "$TMUX_PANE" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "$FZF_TMUX_OPTS" ]; }; then
103
+ shift
104
+ if [ -n "$FZF_TMUX_OPTS" ]; then
105
+ fzf-tmux ${(Q)${(Z+n+)FZF_TMUX_OPTS}} -- "$@"
106
+ else
107
+ fzf-tmux -d ${FZF_TMUX_HEIGHT:-40%} -- "$@"
108
+ fi
109
+ else
110
+ shift
111
+ fzf "$@"
112
+ fi
113
+ }
114
+
115
+ # Extract the name of the command. e.g. foo=1 bar baz**<tab>
116
+ __fzf_extract_command() {
117
+ local token tokens
118
+ tokens=(${(z)1})
119
+ for token in $tokens; do
120
+ token=${(Q)token}
121
+ if [[ "$token" =~ [[:alnum:]] && ! "$token" =~ "=" ]]; then
122
+ echo "$token"
123
+ return
124
+ fi
125
+ done
126
+ echo "${tokens[1]}"
127
+ }
128
+
129
+ __fzf_generic_path_completion() {
130
+ local base lbuf cmd compgen fzf_opts suffix tail dir leftover matches
131
+ base=$1
132
+ lbuf=$2
133
+ cmd=$(__fzf_extract_command "$lbuf")
134
+ compgen=$3
135
+ fzf_opts=$4
136
+ suffix=$5
137
+ tail=$6
138
+
139
+ setopt localoptions nonomatch
140
+ eval "base=$base"
141
+ [[ $base = *"/"* ]] && dir="$base"
142
+ while [ 1 ]; do
143
+ if [[ -z "$dir" || -d ${dir} ]]; then
144
+ leftover=${base/#"$dir"}
145
+ leftover=${leftover/#\/}
146
+ [ -z "$dir" ] && dir='.'
147
+ [ "$dir" != "/" ] && dir="${dir/%\//}"
148
+ matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do
149
+ echo -n "${(q)item}$suffix "
150
+ done)
151
+ matches=${matches% }
152
+ if [ -n "$matches" ]; then
153
+ LBUFFER="$lbuf$matches$tail"
154
+ fi
155
+ zle reset-prompt
156
+ break
157
+ fi
158
+ dir=$(dirname "$dir")
159
+ dir=${dir%/}/
160
+ done
161
+ }
162
+
163
+ _fzf_path_completion() {
164
+ __fzf_generic_path_completion "$1" "$2" _fzf_compgen_path \
165
+ "-m" "" " "
166
+ }
167
+
168
+ _fzf_dir_completion() {
169
+ __fzf_generic_path_completion "$1" "$2" _fzf_compgen_dir \
170
+ "" "/" ""
171
+ }
172
+
173
+ _fzf_feed_fifo() (
174
+ command rm -f "$1"
175
+ mkfifo "$1"
176
+ cat <&0 > "$1" &
177
+ )
178
+
179
+ _fzf_complete() {
180
+ setopt localoptions ksh_arrays
181
+ # Split arguments around --
182
+ local args rest str_arg i sep
183
+ args=("$@")
184
+ sep=
185
+ for i in {0..${#args[@]}}; do
186
+ if [[ "${args[$i]}" = -- ]]; then
187
+ sep=$i
188
+ break
189
+ fi
190
+ done
191
+ if [[ -n "$sep" ]]; then
192
+ str_arg=
193
+ rest=("${args[@]:$((sep + 1)):${#args[@]}}")
194
+ args=("${args[@]:0:$sep}")
195
+ else
196
+ str_arg=$1
197
+ args=()
198
+ shift
199
+ rest=("$@")
200
+ fi
201
+
202
+ local fifo lbuf cmd matches post
203
+ fifo="${TMPDIR:-/tmp}/fzf-complete-fifo-$$"
204
+ lbuf=${rest[0]}
205
+ cmd=$(__fzf_extract_command "$lbuf")
206
+ post="${funcstack[1]}_post"
207
+ type $post > /dev/null 2>&1 || post=cat
208
+
209
+ _fzf_feed_fifo "$fifo"
210
+ matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "$cmd" "${args[@]}" -q "${(Q)prefix}" < "$fifo" | $post | tr '\n' ' ')
211
+ if [ -n "$matches" ]; then
212
+ LBUFFER="$lbuf$matches"
213
+ fi
214
+ command rm -f "$fifo"
215
+ }
216
+
217
+ _fzf_complete_telnet() {
218
+ _fzf_complete +m -- "$@" < <(
219
+ command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' |
220
+ awk '{if (length($2) > 0) {print $2}}' | sort -u
221
+ )
222
+ }
223
+
224
+ _fzf_complete_ssh() {
225
+ _fzf_complete +m -- "$@" < <(
226
+ setopt localoptions nonomatch
227
+ command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?]') \
228
+ <(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
229
+ <(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
230
+ awk '{if (length($2) > 0) {print $2}}' | sort -u
231
+ )
232
+ }
233
+
234
+ _fzf_complete_export() {
235
+ _fzf_complete -m -- "$@" < <(
236
+ declare -xp | sed 's/=.*//' | sed 's/.* //'
237
+ )
238
+ }
239
+
240
+ _fzf_complete_unset() {
241
+ _fzf_complete -m -- "$@" < <(
242
+ declare -xp | sed 's/=.*//' | sed 's/.* //'
243
+ )
244
+ }
245
+
246
+ _fzf_complete_unalias() {
247
+ _fzf_complete +m -- "$@" < <(
248
+ alias | sed 's/=.*//'
249
+ )
250
+ }
251
+
252
+ _fzf_complete_kill() {
253
+ _fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap --min-height 15 -- "$@" < <(
254
+ command ps -ef | sed 1d
255
+ )
256
+ }
257
+
258
+ _fzf_complete_kill_post() {
259
+ awk '{print $2}'
260
+ }
261
+
262
+ fzf-completion() {
263
+ local tokens cmd prefix trigger tail matches lbuf d_cmds
264
+ setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
265
+
266
+ # http://zsh.sourceforge.net/FAQ/zshfaq03.html
267
+ # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags
268
+ tokens=(${(z)LBUFFER})
269
+ if [ ${#tokens} -lt 1 ]; then
270
+ zle ${fzf_default_completion:-expand-or-complete}
271
+ return
272
+ fi
273
+
274
+ cmd=$(__fzf_extract_command "$LBUFFER")
275
+
276
+ # Explicitly allow for empty trigger.
277
+ trigger=${FZF_COMPLETION_TRIGGER-'**'}
278
+ [ -z "$trigger" -a ${LBUFFER[-1]} = ' ' ] && tokens+=("")
279
+
280
+ # When the trigger starts with ';', it becomes a separate token
281
+ if [[ ${LBUFFER} = *"${tokens[-2]}${tokens[-1]}" ]]; then
282
+ tokens[-2]="${tokens[-2]}${tokens[-1]}"
283
+ tokens=(${tokens[0,-2]})
284
+ fi
285
+
286
+ lbuf=$LBUFFER
287
+ tail=${LBUFFER:$(( ${#LBUFFER} - ${#trigger} ))}
288
+ # Kill completion (do not require trigger sequence)
289
+ if [ "$cmd" = kill -a ${LBUFFER[-1]} = ' ' ]; then
290
+ tail=$trigger
291
+ tokens+=$trigger
292
+ lbuf="$lbuf$trigger"
293
+ fi
294
+
295
+ # Trigger sequence given
296
+ if [ ${#tokens} -gt 1 -a "$tail" = "$trigger" ]; then
297
+ d_cmds=(${=FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir})
298
+
299
+ [ -z "$trigger" ] && prefix=${tokens[-1]} || prefix=${tokens[-1]:0:-${#trigger}}
300
+ [ -n "${tokens[-1]}" ] && lbuf=${lbuf:0:-${#tokens[-1]}}
301
+
302
+ if eval "type _fzf_complete_${cmd} > /dev/null"; then
303
+ prefix="$prefix" eval _fzf_complete_${cmd} ${(q)lbuf}
304
+ zle reset-prompt
305
+ elif [ ${d_cmds[(i)$cmd]} -le ${#d_cmds} ]; then
306
+ _fzf_dir_completion "$prefix" "$lbuf"
307
+ else
308
+ _fzf_path_completion "$prefix" "$lbuf"
309
+ fi
310
+ # Fall back to default completion
311
+ else
312
+ zle ${fzf_default_completion:-expand-or-complete}
313
+ fi
314
+ }
315
+
316
+ [ -z "$fzf_default_completion" ] && {
317
+ binding=$(bindkey '^I')
318
+ [[ $binding =~ 'undefined-key' ]] || fzf_default_completion=$binding[(s: :w)2]
319
+ unset binding
320
+ }
321
+
322
+ zle -N fzf-completion
323
+ bindkey '^I' fzf-completion
324
+
325
+ } always {
326
+ # Restore the original options.
327
+ eval $__fzf_completion_options
328
+ 'unset' '__fzf_completion_options'
329
+ }