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,45 @@
1
+ // +build windows
2
+
3
+ package fzf
4
+
5
+ import (
6
+ "os"
7
+ "regexp"
8
+ "strings"
9
+ )
10
+
11
+ func notifyOnResize(resizeChan chan<- os.Signal) {
12
+ // TODO
13
+ }
14
+
15
+ func notifyStop(p *os.Process) {
16
+ // NOOP
17
+ }
18
+
19
+ func notifyOnCont(resizeChan chan<- os.Signal) {
20
+ // NOOP
21
+ }
22
+
23
+ func quoteEntry(entry string) string {
24
+ shell := os.Getenv("SHELL")
25
+ if len(shell) == 0 {
26
+ shell = "cmd"
27
+ }
28
+
29
+ if strings.Contains(shell, "cmd") {
30
+ // backslash escaping is done here for applications
31
+ // (see ripgrep test case in terminal_test.go#TestWindowsCommands)
32
+ escaped := strings.Replace(entry, `\`, `\\`, -1)
33
+ escaped = `"` + strings.Replace(escaped, `"`, `\"`, -1) + `"`
34
+ // caret is the escape character for cmd shell
35
+ r, _ := regexp.Compile(`[&|<>()@^%!"]`)
36
+ return r.ReplaceAllStringFunc(escaped, func(match string) string {
37
+ return "^" + match
38
+ })
39
+ } else if strings.Contains(shell, "pwsh") || strings.Contains(shell, "powershell") {
40
+ escaped := strings.Replace(entry, `"`, `\"`, -1)
41
+ return "'" + strings.Replace(escaped, "'", "''", -1) + "'"
42
+ } else {
43
+ return "'" + strings.Replace(entry, "'", "'\\''", -1) + "'"
44
+ }
45
+ }
@@ -0,0 +1,253 @@
1
+ package fzf
2
+
3
+ import (
4
+ "bytes"
5
+ "fmt"
6
+ "regexp"
7
+ "strconv"
8
+ "strings"
9
+
10
+ "github.com/junegunn/fzf/src/util"
11
+ )
12
+
13
+ const rangeEllipsis = 0
14
+
15
+ // Range represents nth-expression
16
+ type Range struct {
17
+ begin int
18
+ end int
19
+ }
20
+
21
+ // Token contains the tokenized part of the strings and its prefix length
22
+ type Token struct {
23
+ text *util.Chars
24
+ prefixLength int32
25
+ }
26
+
27
+ // String returns the string representation of a Token.
28
+ func (t Token) String() string {
29
+ return fmt.Sprintf("Token{text: %s, prefixLength: %d}", t.text, t.prefixLength)
30
+ }
31
+
32
+ // Delimiter for tokenizing the input
33
+ type Delimiter struct {
34
+ regex *regexp.Regexp
35
+ str *string
36
+ }
37
+
38
+ // String returns the string representation of a Delimiter.
39
+ func (d Delimiter) String() string {
40
+ return fmt.Sprintf("Delimiter{regex: %v, str: &%q}", d.regex, *d.str)
41
+ }
42
+
43
+ func newRange(begin int, end int) Range {
44
+ if begin == 1 {
45
+ begin = rangeEllipsis
46
+ }
47
+ if end == -1 {
48
+ end = rangeEllipsis
49
+ }
50
+ return Range{begin, end}
51
+ }
52
+
53
+ // ParseRange parses nth-expression and returns the corresponding Range object
54
+ func ParseRange(str *string) (Range, bool) {
55
+ if (*str) == ".." {
56
+ return newRange(rangeEllipsis, rangeEllipsis), true
57
+ } else if strings.HasPrefix(*str, "..") {
58
+ end, err := strconv.Atoi((*str)[2:])
59
+ if err != nil || end == 0 {
60
+ return Range{}, false
61
+ }
62
+ return newRange(rangeEllipsis, end), true
63
+ } else if strings.HasSuffix(*str, "..") {
64
+ begin, err := strconv.Atoi((*str)[:len(*str)-2])
65
+ if err != nil || begin == 0 {
66
+ return Range{}, false
67
+ }
68
+ return newRange(begin, rangeEllipsis), true
69
+ } else if strings.Contains(*str, "..") {
70
+ ns := strings.Split(*str, "..")
71
+ if len(ns) != 2 {
72
+ return Range{}, false
73
+ }
74
+ begin, err1 := strconv.Atoi(ns[0])
75
+ end, err2 := strconv.Atoi(ns[1])
76
+ if err1 != nil || err2 != nil || begin == 0 || end == 0 {
77
+ return Range{}, false
78
+ }
79
+ return newRange(begin, end), true
80
+ }
81
+
82
+ n, err := strconv.Atoi(*str)
83
+ if err != nil || n == 0 {
84
+ return Range{}, false
85
+ }
86
+ return newRange(n, n), true
87
+ }
88
+
89
+ func withPrefixLengths(tokens []string, begin int) []Token {
90
+ ret := make([]Token, len(tokens))
91
+
92
+ prefixLength := begin
93
+ for idx := range tokens {
94
+ chars := util.ToChars([]byte(tokens[idx]))
95
+ ret[idx] = Token{&chars, int32(prefixLength)}
96
+ prefixLength += chars.Length()
97
+ }
98
+ return ret
99
+ }
100
+
101
+ const (
102
+ awkNil = iota
103
+ awkBlack
104
+ awkWhite
105
+ )
106
+
107
+ func awkTokenizer(input string) ([]string, int) {
108
+ // 9, 32
109
+ ret := []string{}
110
+ prefixLength := 0
111
+ state := awkNil
112
+ begin := 0
113
+ end := 0
114
+ for idx := 0; idx < len(input); idx++ {
115
+ r := input[idx]
116
+ white := r == 9 || r == 32
117
+ switch state {
118
+ case awkNil:
119
+ if white {
120
+ prefixLength++
121
+ } else {
122
+ state, begin, end = awkBlack, idx, idx+1
123
+ }
124
+ case awkBlack:
125
+ end = idx + 1
126
+ if white {
127
+ state = awkWhite
128
+ }
129
+ case awkWhite:
130
+ if white {
131
+ end = idx + 1
132
+ } else {
133
+ ret = append(ret, input[begin:end])
134
+ state, begin, end = awkBlack, idx, idx+1
135
+ }
136
+ }
137
+ }
138
+ if begin < end {
139
+ ret = append(ret, input[begin:end])
140
+ }
141
+ return ret, prefixLength
142
+ }
143
+
144
+ // Tokenize tokenizes the given string with the delimiter
145
+ func Tokenize(text string, delimiter Delimiter) []Token {
146
+ if delimiter.str == nil && delimiter.regex == nil {
147
+ // AWK-style (\S+\s*)
148
+ tokens, prefixLength := awkTokenizer(text)
149
+ return withPrefixLengths(tokens, prefixLength)
150
+ }
151
+
152
+ if delimiter.str != nil {
153
+ return withPrefixLengths(strings.SplitAfter(text, *delimiter.str), 0)
154
+ }
155
+
156
+ // FIXME performance
157
+ var tokens []string
158
+ if delimiter.regex != nil {
159
+ for len(text) > 0 {
160
+ loc := delimiter.regex.FindStringIndex(text)
161
+ if len(loc) < 2 {
162
+ loc = []int{0, len(text)}
163
+ }
164
+ last := util.Max(loc[1], 1)
165
+ tokens = append(tokens, text[:last])
166
+ text = text[last:]
167
+ }
168
+ }
169
+ return withPrefixLengths(tokens, 0)
170
+ }
171
+
172
+ func joinTokens(tokens []Token) string {
173
+ var output bytes.Buffer
174
+ for _, token := range tokens {
175
+ output.WriteString(token.text.ToString())
176
+ }
177
+ return output.String()
178
+ }
179
+
180
+ // Transform is used to transform the input when --with-nth option is given
181
+ func Transform(tokens []Token, withNth []Range) []Token {
182
+ transTokens := make([]Token, len(withNth))
183
+ numTokens := len(tokens)
184
+ for idx, r := range withNth {
185
+ parts := []*util.Chars{}
186
+ minIdx := 0
187
+ if r.begin == r.end {
188
+ idx := r.begin
189
+ if idx == rangeEllipsis {
190
+ chars := util.ToChars([]byte(joinTokens(tokens)))
191
+ parts = append(parts, &chars)
192
+ } else {
193
+ if idx < 0 {
194
+ idx += numTokens + 1
195
+ }
196
+ if idx >= 1 && idx <= numTokens {
197
+ minIdx = idx - 1
198
+ parts = append(parts, tokens[idx-1].text)
199
+ }
200
+ }
201
+ } else {
202
+ var begin, end int
203
+ if r.begin == rangeEllipsis { // ..N
204
+ begin, end = 1, r.end
205
+ if end < 0 {
206
+ end += numTokens + 1
207
+ }
208
+ } else if r.end == rangeEllipsis { // N..
209
+ begin, end = r.begin, numTokens
210
+ if begin < 0 {
211
+ begin += numTokens + 1
212
+ }
213
+ } else {
214
+ begin, end = r.begin, r.end
215
+ if begin < 0 {
216
+ begin += numTokens + 1
217
+ }
218
+ if end < 0 {
219
+ end += numTokens + 1
220
+ }
221
+ }
222
+ minIdx = util.Max(0, begin-1)
223
+ for idx := begin; idx <= end; idx++ {
224
+ if idx >= 1 && idx <= numTokens {
225
+ parts = append(parts, tokens[idx-1].text)
226
+ }
227
+ }
228
+ }
229
+ // Merge multiple parts
230
+ var merged util.Chars
231
+ switch len(parts) {
232
+ case 0:
233
+ merged = util.ToChars([]byte{})
234
+ case 1:
235
+ merged = *parts[0]
236
+ default:
237
+ var output bytes.Buffer
238
+ for _, part := range parts {
239
+ output.WriteString(part.ToString())
240
+ }
241
+ merged = util.ToChars(output.Bytes())
242
+ }
243
+
244
+ var prefixLength int32
245
+ if minIdx < numTokens {
246
+ prefixLength = tokens[minIdx].prefixLength
247
+ } else {
248
+ prefixLength = 0
249
+ }
250
+ transTokens[idx] = Token{&merged, prefixLength}
251
+ }
252
+ return transTokens
253
+ }
@@ -0,0 +1,112 @@
1
+ package fzf
2
+
3
+ import (
4
+ "testing"
5
+ )
6
+
7
+ func TestParseRange(t *testing.T) {
8
+ {
9
+ i := ".."
10
+ r, _ := ParseRange(&i)
11
+ if r.begin != rangeEllipsis || r.end != rangeEllipsis {
12
+ t.Errorf("%v", r)
13
+ }
14
+ }
15
+ {
16
+ i := "3.."
17
+ r, _ := ParseRange(&i)
18
+ if r.begin != 3 || r.end != rangeEllipsis {
19
+ t.Errorf("%v", r)
20
+ }
21
+ }
22
+ {
23
+ i := "3..5"
24
+ r, _ := ParseRange(&i)
25
+ if r.begin != 3 || r.end != 5 {
26
+ t.Errorf("%v", r)
27
+ }
28
+ }
29
+ {
30
+ i := "-3..-5"
31
+ r, _ := ParseRange(&i)
32
+ if r.begin != -3 || r.end != -5 {
33
+ t.Errorf("%v", r)
34
+ }
35
+ }
36
+ {
37
+ i := "3"
38
+ r, _ := ParseRange(&i)
39
+ if r.begin != 3 || r.end != 3 {
40
+ t.Errorf("%v", r)
41
+ }
42
+ }
43
+ }
44
+
45
+ func TestTokenize(t *testing.T) {
46
+ // AWK-style
47
+ input := " abc: def: ghi "
48
+ tokens := Tokenize(input, Delimiter{})
49
+ if tokens[0].text.ToString() != "abc: " || tokens[0].prefixLength != 2 {
50
+ t.Errorf("%s", tokens)
51
+ }
52
+
53
+ // With delimiter
54
+ tokens = Tokenize(input, delimiterRegexp(":"))
55
+ if tokens[0].text.ToString() != " abc:" || tokens[0].prefixLength != 0 {
56
+ t.Error(tokens[0].text.ToString(), tokens[0].prefixLength)
57
+ }
58
+
59
+ // With delimiter regex
60
+ tokens = Tokenize(input, delimiterRegexp("\\s+"))
61
+ if tokens[0].text.ToString() != " " || tokens[0].prefixLength != 0 ||
62
+ tokens[1].text.ToString() != "abc: " || tokens[1].prefixLength != 2 ||
63
+ tokens[2].text.ToString() != "def: " || tokens[2].prefixLength != 8 ||
64
+ tokens[3].text.ToString() != "ghi " || tokens[3].prefixLength != 14 {
65
+ t.Errorf("%s", tokens)
66
+ }
67
+ }
68
+
69
+ func TestTransform(t *testing.T) {
70
+ input := " abc: def: ghi: jkl"
71
+ {
72
+ tokens := Tokenize(input, Delimiter{})
73
+ {
74
+ ranges := splitNth("1,2,3")
75
+ tx := Transform(tokens, ranges)
76
+ if joinTokens(tx) != "abc: def: ghi: " {
77
+ t.Errorf("%s", tx)
78
+ }
79
+ }
80
+ {
81
+ ranges := splitNth("1..2,3,2..,1")
82
+ tx := Transform(tokens, ranges)
83
+ if string(joinTokens(tx)) != "abc: def: ghi: def: ghi: jklabc: " ||
84
+ len(tx) != 4 ||
85
+ tx[0].text.ToString() != "abc: def: " || tx[0].prefixLength != 2 ||
86
+ tx[1].text.ToString() != "ghi: " || tx[1].prefixLength != 14 ||
87
+ tx[2].text.ToString() != "def: ghi: jkl" || tx[2].prefixLength != 8 ||
88
+ tx[3].text.ToString() != "abc: " || tx[3].prefixLength != 2 {
89
+ t.Errorf("%s", tx)
90
+ }
91
+ }
92
+ }
93
+ {
94
+ tokens := Tokenize(input, delimiterRegexp(":"))
95
+ {
96
+ ranges := splitNth("1..2,3,2..,1")
97
+ tx := Transform(tokens, ranges)
98
+ if joinTokens(tx) != " abc: def: ghi: def: ghi: jkl abc:" ||
99
+ len(tx) != 4 ||
100
+ tx[0].text.ToString() != " abc: def:" || tx[0].prefixLength != 0 ||
101
+ tx[1].text.ToString() != " ghi:" || tx[1].prefixLength != 12 ||
102
+ tx[2].text.ToString() != " def: ghi: jkl" || tx[2].prefixLength != 6 ||
103
+ tx[3].text.ToString() != " abc:" || tx[3].prefixLength != 0 {
104
+ t.Errorf("%s", tx)
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ func TestTransformIndexOutOfBounds(t *testing.T) {
111
+ Transform([]Token{}, splitNth("1"))
112
+ }
@@ -0,0 +1,46 @@
1
+ // +build !ncurses
2
+ // +build !tcell
3
+ // +build !windows
4
+
5
+ package tui
6
+
7
+ type Attr int32
8
+
9
+ func HasFullscreenRenderer() bool {
10
+ return false
11
+ }
12
+
13
+ func (a Attr) Merge(b Attr) Attr {
14
+ return a | b
15
+ }
16
+
17
+ const (
18
+ AttrUndefined = Attr(0)
19
+ AttrRegular = Attr(1 << 7)
20
+ AttrClear = Attr(1 << 8)
21
+
22
+ Bold = Attr(1)
23
+ Dim = Attr(1 << 1)
24
+ Italic = Attr(1 << 2)
25
+ Underline = Attr(1 << 3)
26
+ Blink = Attr(1 << 4)
27
+ Blink2 = Attr(1 << 5)
28
+ Reverse = Attr(1 << 6)
29
+ )
30
+
31
+ func (r *FullscreenRenderer) Init() {}
32
+ func (r *FullscreenRenderer) Pause(bool) {}
33
+ func (r *FullscreenRenderer) Resume(bool, bool) {}
34
+ func (r *FullscreenRenderer) Clear() {}
35
+ func (r *FullscreenRenderer) Refresh() {}
36
+ func (r *FullscreenRenderer) Close() {}
37
+
38
+ func (r *FullscreenRenderer) GetChar() Event { return Event{} }
39
+ func (r *FullscreenRenderer) MaxX() int { return 0 }
40
+ func (r *FullscreenRenderer) MaxY() int { return 0 }
41
+
42
+ func (r *FullscreenRenderer) RefreshWindows(windows []Window) {}
43
+
44
+ func (r *FullscreenRenderer) NewWindow(top int, left int, width int, height int, preview bool, borderStyle BorderStyle) Window {
45
+ return nil
46
+ }