doing 2.0.20 → 2.0.21

Sign up to get free protection for your applications and to get access to all the features.
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
+ }