doing 2.0.20 → 2.0.21

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +1 -1
  5. data/doing.rdoc +1 -1
  6. data/lib/doing/version.rb +1 -1
  7. data/lib/helpers/fzf/.goreleaser.yml +119 -0
  8. data/lib/helpers/fzf/.rubocop.yml +28 -0
  9. data/lib/helpers/fzf/ADVANCED.md +565 -0
  10. data/lib/helpers/fzf/BUILD.md +49 -0
  11. data/lib/helpers/fzf/CHANGELOG.md +1193 -0
  12. data/lib/helpers/fzf/Dockerfile +11 -0
  13. data/lib/helpers/fzf/LICENSE +21 -0
  14. data/lib/helpers/fzf/Makefile +166 -0
  15. data/lib/helpers/fzf/README-VIM.md +486 -0
  16. data/lib/helpers/fzf/README.md +712 -0
  17. data/lib/helpers/fzf/bin/fzf-tmux +233 -0
  18. data/lib/helpers/fzf/doc/fzf.txt +512 -0
  19. data/lib/helpers/fzf/go.mod +17 -0
  20. data/lib/helpers/fzf/go.sum +31 -0
  21. data/lib/helpers/fzf/install +382 -0
  22. data/lib/helpers/fzf/install.ps1 +65 -0
  23. data/lib/helpers/fzf/main.go +14 -0
  24. data/lib/helpers/fzf/man/man1/fzf-tmux.1 +68 -0
  25. data/lib/helpers/fzf/man/man1/fzf.1 +1001 -0
  26. data/lib/helpers/fzf/plugin/fzf.vim +1048 -0
  27. data/lib/helpers/fzf/shell/completion.bash +381 -0
  28. data/lib/helpers/fzf/shell/completion.zsh +329 -0
  29. data/lib/helpers/fzf/shell/key-bindings.bash +96 -0
  30. data/lib/helpers/fzf/shell/key-bindings.fish +172 -0
  31. data/lib/helpers/fzf/shell/key-bindings.zsh +114 -0
  32. data/lib/helpers/fzf/src/LICENSE +21 -0
  33. data/lib/helpers/fzf/src/algo/algo.go +884 -0
  34. data/lib/helpers/fzf/src/algo/algo_test.go +197 -0
  35. data/lib/helpers/fzf/src/algo/normalize.go +492 -0
  36. data/lib/helpers/fzf/src/ansi.go +409 -0
  37. data/lib/helpers/fzf/src/ansi_test.go +427 -0
  38. data/lib/helpers/fzf/src/cache.go +81 -0
  39. data/lib/helpers/fzf/src/cache_test.go +39 -0
  40. data/lib/helpers/fzf/src/chunklist.go +89 -0
  41. data/lib/helpers/fzf/src/chunklist_test.go +80 -0
  42. data/lib/helpers/fzf/src/constants.go +85 -0
  43. data/lib/helpers/fzf/src/core.go +351 -0
  44. data/lib/helpers/fzf/src/history.go +96 -0
  45. data/lib/helpers/fzf/src/history_test.go +68 -0
  46. data/lib/helpers/fzf/src/item.go +44 -0
  47. data/lib/helpers/fzf/src/item_test.go +23 -0
  48. data/lib/helpers/fzf/src/matcher.go +235 -0
  49. data/lib/helpers/fzf/src/merger.go +120 -0
  50. data/lib/helpers/fzf/src/merger_test.go +88 -0
  51. data/lib/helpers/fzf/src/options.go +1691 -0
  52. data/lib/helpers/fzf/src/options_test.go +457 -0
  53. data/lib/helpers/fzf/src/pattern.go +425 -0
  54. data/lib/helpers/fzf/src/pattern_test.go +209 -0
  55. data/lib/helpers/fzf/src/protector/protector.go +8 -0
  56. data/lib/helpers/fzf/src/protector/protector_openbsd.go +10 -0
  57. data/lib/helpers/fzf/src/reader.go +201 -0
  58. data/lib/helpers/fzf/src/reader_test.go +63 -0
  59. data/lib/helpers/fzf/src/result.go +243 -0
  60. data/lib/helpers/fzf/src/result_others.go +16 -0
  61. data/lib/helpers/fzf/src/result_test.go +159 -0
  62. data/lib/helpers/fzf/src/result_x86.go +16 -0
  63. data/lib/helpers/fzf/src/terminal.go +2832 -0
  64. data/lib/helpers/fzf/src/terminal_test.go +638 -0
  65. data/lib/helpers/fzf/src/terminal_unix.go +26 -0
  66. data/lib/helpers/fzf/src/terminal_windows.go +45 -0
  67. data/lib/helpers/fzf/src/tokenizer.go +253 -0
  68. data/lib/helpers/fzf/src/tokenizer_test.go +112 -0
  69. data/lib/helpers/fzf/src/tui/dummy.go +46 -0
  70. data/lib/helpers/fzf/src/tui/light.go +987 -0
  71. data/lib/helpers/fzf/src/tui/light_unix.go +110 -0
  72. data/lib/helpers/fzf/src/tui/light_windows.go +145 -0
  73. data/lib/helpers/fzf/src/tui/tcell.go +721 -0
  74. data/lib/helpers/fzf/src/tui/tcell_test.go +392 -0
  75. data/lib/helpers/fzf/src/tui/ttyname_unix.go +47 -0
  76. data/lib/helpers/fzf/src/tui/ttyname_windows.go +14 -0
  77. data/lib/helpers/fzf/src/tui/tui.go +625 -0
  78. data/lib/helpers/fzf/src/tui/tui_test.go +20 -0
  79. data/lib/helpers/fzf/src/util/atomicbool.go +34 -0
  80. data/lib/helpers/fzf/src/util/atomicbool_test.go +17 -0
  81. data/lib/helpers/fzf/src/util/chars.go +198 -0
  82. data/lib/helpers/fzf/src/util/chars_test.go +46 -0
  83. data/lib/helpers/fzf/src/util/eventbox.go +96 -0
  84. data/lib/helpers/fzf/src/util/eventbox_test.go +61 -0
  85. data/lib/helpers/fzf/src/util/slab.go +12 -0
  86. data/lib/helpers/fzf/src/util/util.go +138 -0
  87. data/lib/helpers/fzf/src/util/util_test.go +40 -0
  88. data/lib/helpers/fzf/src/util/util_unix.go +47 -0
  89. data/lib/helpers/fzf/src/util/util_windows.go +83 -0
  90. data/lib/helpers/fzf/test/fzf.vader +175 -0
  91. data/lib/helpers/fzf/test/test_go.rb +2626 -0
  92. data/lib/helpers/fzf/uninstall +117 -0
  93. metadata +87 -1
@@ -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
+ }