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,409 @@
1
+ package fzf
2
+
3
+ import (
4
+ "strconv"
5
+ "strings"
6
+ "unicode/utf8"
7
+
8
+ "github.com/junegunn/fzf/src/tui"
9
+ )
10
+
11
+ type ansiOffset struct {
12
+ offset [2]int32
13
+ color ansiState
14
+ }
15
+
16
+ type ansiState struct {
17
+ fg tui.Color
18
+ bg tui.Color
19
+ attr tui.Attr
20
+ lbg tui.Color
21
+ }
22
+
23
+ func (s *ansiState) colored() bool {
24
+ return s.fg != -1 || s.bg != -1 || s.attr > 0 || s.lbg >= 0
25
+ }
26
+
27
+ func (s *ansiState) equals(t *ansiState) bool {
28
+ if t == nil {
29
+ return !s.colored()
30
+ }
31
+ return s.fg == t.fg && s.bg == t.bg && s.attr == t.attr && s.lbg == t.lbg
32
+ }
33
+
34
+ func (s *ansiState) ToString() string {
35
+ if !s.colored() {
36
+ return ""
37
+ }
38
+
39
+ ret := ""
40
+ if s.attr&tui.Bold > 0 {
41
+ ret += "1;"
42
+ }
43
+ if s.attr&tui.Dim > 0 {
44
+ ret += "2;"
45
+ }
46
+ if s.attr&tui.Italic > 0 {
47
+ ret += "3;"
48
+ }
49
+ if s.attr&tui.Underline > 0 {
50
+ ret += "4;"
51
+ }
52
+ if s.attr&tui.Blink > 0 {
53
+ ret += "5;"
54
+ }
55
+ if s.attr&tui.Reverse > 0 {
56
+ ret += "7;"
57
+ }
58
+ ret += toAnsiString(s.fg, 30) + toAnsiString(s.bg, 40)
59
+
60
+ return "\x1b[" + strings.TrimSuffix(ret, ";") + "m"
61
+ }
62
+
63
+ func toAnsiString(color tui.Color, offset int) string {
64
+ col := int(color)
65
+ ret := ""
66
+ if col == -1 {
67
+ ret += strconv.Itoa(offset + 9)
68
+ } else if col < 8 {
69
+ ret += strconv.Itoa(offset + col)
70
+ } else if col < 16 {
71
+ ret += strconv.Itoa(offset - 30 + 90 + col - 8)
72
+ } else if col < 256 {
73
+ ret += strconv.Itoa(offset+8) + ";5;" + strconv.Itoa(col)
74
+ } else if col >= (1 << 24) {
75
+ r := strconv.Itoa((col >> 16) & 0xff)
76
+ g := strconv.Itoa((col >> 8) & 0xff)
77
+ b := strconv.Itoa(col & 0xff)
78
+ ret += strconv.Itoa(offset+8) + ";2;" + r + ";" + g + ";" + b
79
+ }
80
+ return ret + ";"
81
+ }
82
+
83
+ func isPrint(c uint8) bool {
84
+ return '\x20' <= c && c <= '\x7e'
85
+ }
86
+
87
+ func matchOperatingSystemCommand(s string) int {
88
+ // `\x1b][0-9];[[:print:]]+(?:\x1b\\\\|\x07)`
89
+ // ^ match starting here
90
+ //
91
+ i := 5 // prefix matched in nextAnsiEscapeSequence()
92
+ for ; i < len(s) && isPrint(s[i]); i++ {
93
+ }
94
+ if i < len(s) {
95
+ if s[i] == '\x07' {
96
+ return i + 1
97
+ }
98
+ if s[i] == '\x1b' && i < len(s)-1 && s[i+1] == '\\' {
99
+ return i + 2
100
+ }
101
+ }
102
+ return -1
103
+ }
104
+
105
+ func matchControlSequence(s string) int {
106
+ // `\x1b[\\[()][0-9;?]*[a-zA-Z@]`
107
+ // ^ match starting here
108
+ //
109
+ i := 2 // prefix matched in nextAnsiEscapeSequence()
110
+ for ; i < len(s) && (isNumeric(s[i]) || s[i] == ';' || s[i] == '?'); i++ {
111
+ }
112
+ if i < len(s) {
113
+ c := s[i]
114
+ if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '@' {
115
+ return i + 1
116
+ }
117
+ }
118
+ return -1
119
+ }
120
+
121
+ func isCtrlSeqStart(c uint8) bool {
122
+ return c == '\\' || c == '[' || c == '(' || c == ')'
123
+ }
124
+
125
+ // nextAnsiEscapeSequence returns the ANSI escape sequence and is equivalent to
126
+ // calling FindStringIndex() on the below regex (which was originally used):
127
+ //
128
+ // "(?:\x1b[\\[()][0-9;?]*[a-zA-Z@]|\x1b][0-9];[[:print:]]+(?:\x1b\\\\|\x07)|\x1b.|[\x0e\x0f]|.\x08)"
129
+ //
130
+ func nextAnsiEscapeSequence(s string) (int, int) {
131
+ // fast check for ANSI escape sequences
132
+ i := 0
133
+ for ; i < len(s); i++ {
134
+ switch s[i] {
135
+ case '\x0e', '\x0f', '\x1b', '\x08':
136
+ // We ignore the fact that '\x08' cannot be the first char
137
+ // in the string and be an escape sequence for the sake of
138
+ // speed and simplicity.
139
+ goto Loop
140
+ }
141
+ }
142
+ return -1, -1
143
+
144
+ Loop:
145
+ for ; i < len(s); i++ {
146
+ switch s[i] {
147
+ case '\x08':
148
+ // backtrack to match: `.\x08`
149
+ if i > 0 && s[i-1] != '\n' {
150
+ if s[i-1] < utf8.RuneSelf {
151
+ return i - 1, i + 1
152
+ }
153
+ _, n := utf8.DecodeLastRuneInString(s[:i])
154
+ return i - n, i + 1
155
+ }
156
+ case '\x1b':
157
+ // match: `\x1b[\\[()][0-9;?]*[a-zA-Z@]`
158
+ if i+2 < len(s) && isCtrlSeqStart(s[i+1]) {
159
+ if j := matchControlSequence(s[i:]); j != -1 {
160
+ return i, i + j
161
+ }
162
+ }
163
+
164
+ // match: `\x1b][0-9];[[:print:]]+(?:\x1b\\\\|\x07)`
165
+ if i+5 < len(s) && s[i+1] == ']' && isNumeric(s[i+2]) &&
166
+ s[i+3] == ';' && isPrint(s[i+4]) {
167
+
168
+ if j := matchOperatingSystemCommand(s[i:]); j != -1 {
169
+ return i, i + j
170
+ }
171
+ }
172
+
173
+ // match: `\x1b.`
174
+ if i+1 < len(s) && s[i+1] != '\n' {
175
+ if s[i+1] < utf8.RuneSelf {
176
+ return i, i + 2
177
+ }
178
+ _, n := utf8.DecodeRuneInString(s[i+1:])
179
+ return i, i + n + 1
180
+ }
181
+ case '\x0e', '\x0f':
182
+ // match: `[\x0e\x0f]`
183
+ return i, i + 1
184
+ }
185
+ }
186
+ return -1, -1
187
+ }
188
+
189
+ func extractColor(str string, state *ansiState, proc func(string, *ansiState) bool) (string, *[]ansiOffset, *ansiState) {
190
+ // We append to a stack allocated variable that we'll
191
+ // later copy and return, to save on allocations.
192
+ offsets := make([]ansiOffset, 0, 32)
193
+
194
+ if state != nil {
195
+ offsets = append(offsets, ansiOffset{[2]int32{0, 0}, *state})
196
+ }
197
+
198
+ var (
199
+ pstate *ansiState // lazily allocated
200
+ output strings.Builder
201
+ prevIdx int
202
+ runeCount int
203
+ )
204
+ for idx := 0; idx < len(str); {
205
+ // Make sure that we found an ANSI code
206
+ start, end := nextAnsiEscapeSequence(str[idx:])
207
+ if start == -1 {
208
+ break
209
+ }
210
+ start += idx
211
+ idx += end
212
+
213
+ // Check if we should continue
214
+ prev := str[prevIdx:start]
215
+ if proc != nil && !proc(prev, state) {
216
+ return "", nil, nil
217
+ }
218
+ prevIdx = idx
219
+
220
+ if len(prev) != 0 {
221
+ runeCount += utf8.RuneCountInString(prev)
222
+ // Grow the buffer size to the maximum possible length (string length
223
+ // containing ansi codes) to avoid repetitive allocation
224
+ if output.Cap() == 0 {
225
+ output.Grow(len(str))
226
+ }
227
+ output.WriteString(prev)
228
+ }
229
+
230
+ newState := interpretCode(str[start:idx], state)
231
+ if !newState.equals(state) {
232
+ if state != nil {
233
+ // Update last offset
234
+ (&offsets[len(offsets)-1]).offset[1] = int32(runeCount)
235
+ }
236
+
237
+ if newState.colored() {
238
+ // Append new offset
239
+ if pstate == nil {
240
+ pstate = &ansiState{}
241
+ }
242
+ *pstate = newState
243
+ state = pstate
244
+ offsets = append(offsets, ansiOffset{
245
+ [2]int32{int32(runeCount), int32(runeCount)},
246
+ newState,
247
+ })
248
+ } else {
249
+ // Discard state
250
+ state = nil
251
+ }
252
+ }
253
+ }
254
+
255
+ var rest string
256
+ var trimmed string
257
+ if prevIdx == 0 {
258
+ // No ANSI code found
259
+ rest = str
260
+ trimmed = str
261
+ } else {
262
+ rest = str[prevIdx:]
263
+ output.WriteString(rest)
264
+ trimmed = output.String()
265
+ }
266
+ if proc != nil {
267
+ proc(rest, state)
268
+ }
269
+ if len(offsets) > 0 {
270
+ if len(rest) > 0 && state != nil {
271
+ // Update last offset
272
+ runeCount += utf8.RuneCountInString(rest)
273
+ (&offsets[len(offsets)-1]).offset[1] = int32(runeCount)
274
+ }
275
+ // Return a copy of the offsets slice
276
+ a := make([]ansiOffset, len(offsets))
277
+ copy(a, offsets)
278
+ return trimmed, &a, state
279
+ }
280
+ return trimmed, nil, state
281
+ }
282
+
283
+ func parseAnsiCode(s string) (int, string) {
284
+ var remaining string
285
+ if i := strings.IndexByte(s, ';'); i >= 0 {
286
+ remaining = s[i+1:]
287
+ s = s[:i]
288
+ }
289
+
290
+ if len(s) > 0 {
291
+ // Inlined version of strconv.Atoi() that only handles positive
292
+ // integers and does not allocate on error.
293
+ code := 0
294
+ for _, ch := range []byte(s) {
295
+ ch -= '0'
296
+ if ch > 9 {
297
+ return -1, remaining
298
+ }
299
+ code = code*10 + int(ch)
300
+ }
301
+ return code, remaining
302
+ }
303
+
304
+ return -1, remaining
305
+ }
306
+
307
+ func interpretCode(ansiCode string, prevState *ansiState) ansiState {
308
+ var state ansiState
309
+ if prevState == nil {
310
+ state = ansiState{-1, -1, 0, -1}
311
+ } else {
312
+ state = ansiState{prevState.fg, prevState.bg, prevState.attr, prevState.lbg}
313
+ }
314
+ if ansiCode[0] != '\x1b' || ansiCode[1] != '[' || ansiCode[len(ansiCode)-1] != 'm' {
315
+ if prevState != nil && strings.HasSuffix(ansiCode, "0K") {
316
+ state.lbg = prevState.bg
317
+ }
318
+ return state
319
+ }
320
+
321
+ if len(ansiCode) <= 3 {
322
+ state.fg = -1
323
+ state.bg = -1
324
+ state.attr = 0
325
+ return state
326
+ }
327
+ ansiCode = ansiCode[2 : len(ansiCode)-1]
328
+
329
+ state256 := 0
330
+ ptr := &state.fg
331
+
332
+ for len(ansiCode) != 0 {
333
+ var num int
334
+ if num, ansiCode = parseAnsiCode(ansiCode); num != -1 {
335
+ switch state256 {
336
+ case 0:
337
+ switch num {
338
+ case 38:
339
+ ptr = &state.fg
340
+ state256++
341
+ case 48:
342
+ ptr = &state.bg
343
+ state256++
344
+ case 39:
345
+ state.fg = -1
346
+ case 49:
347
+ state.bg = -1
348
+ case 1:
349
+ state.attr = state.attr | tui.Bold
350
+ case 2:
351
+ state.attr = state.attr | tui.Dim
352
+ case 3:
353
+ state.attr = state.attr | tui.Italic
354
+ case 4:
355
+ state.attr = state.attr | tui.Underline
356
+ case 5:
357
+ state.attr = state.attr | tui.Blink
358
+ case 7:
359
+ state.attr = state.attr | tui.Reverse
360
+ case 23: // tput rmso
361
+ state.attr = state.attr &^ tui.Italic
362
+ case 24: // tput rmul
363
+ state.attr = state.attr &^ tui.Underline
364
+ case 0:
365
+ state.fg = -1
366
+ state.bg = -1
367
+ state.attr = 0
368
+ state256 = 0
369
+ default:
370
+ if num >= 30 && num <= 37 {
371
+ state.fg = tui.Color(num - 30)
372
+ } else if num >= 40 && num <= 47 {
373
+ state.bg = tui.Color(num - 40)
374
+ } else if num >= 90 && num <= 97 {
375
+ state.fg = tui.Color(num - 90 + 8)
376
+ } else if num >= 100 && num <= 107 {
377
+ state.bg = tui.Color(num - 100 + 8)
378
+ }
379
+ }
380
+ case 1:
381
+ switch num {
382
+ case 2:
383
+ state256 = 10 // MAGIC
384
+ case 5:
385
+ state256++
386
+ default:
387
+ state256 = 0
388
+ }
389
+ case 2:
390
+ *ptr = tui.Color(num)
391
+ state256 = 0
392
+ case 10:
393
+ *ptr = tui.Color(1<<24) | tui.Color(num<<16)
394
+ state256++
395
+ case 11:
396
+ *ptr = *ptr | tui.Color(num<<8)
397
+ state256++
398
+ case 12:
399
+ *ptr = *ptr | tui.Color(num)
400
+ state256 = 0
401
+ }
402
+ }
403
+ }
404
+
405
+ if state256 > 0 {
406
+ *ptr = -1
407
+ }
408
+ return state
409
+ }