doing 2.0.19 → 2.0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -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 +19 -5
  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
+ }