Skip to content

Commit 09200ef

Browse files
wsnyWilliam Snyders
and
William Snyders
authored
add initial query and select one options (#185)
Co-authored-by: William Snyders <[email protected]>
1 parent 8d345ee commit 09200ef

8 files changed

+190
-0
lines changed

fuzzyfinder.go

+12
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ func (f *finder) initFinder(items []string, matched []matching.Matched, opt opt)
129129
f.drawTimer.Stop()
130130
}
131131
f.eventCh = make(chan struct{}, 30) // A large value
132+
133+
if opt.query != "" {
134+
f.state.input = []rune(opt.query)
135+
f.state.cursorX = runewidth.StringWidth(opt.query)
136+
f.state.x = len(opt.query)
137+
f.filter()
138+
}
139+
132140
return nil
133141
}
134142

@@ -736,6 +744,10 @@ func (f *finder) find(slice interface{}, itemFunc func(i int) string, opts []Opt
736744

737745
close(inited)
738746

747+
if opt.selectOne && len(f.state.matched) == 1 {
748+
return []int{f.state.matched[0].Idx}, nil
749+
}
750+
739751
go func() {
740752
for {
741753
select {

fuzzyfinder_test.go

+107
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,113 @@ func TestFind_withContext(t *testing.T) {
473473
})
474474
}
475475

476+
func TestFind_WithQuery(t *testing.T) {
477+
t.Parallel()
478+
var (
479+
things = []string{"one", "three2one"}
480+
thingFunc = func(i int) string {
481+
return things[i]
482+
}
483+
events = append(runes("one"), key(input{tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone}))
484+
)
485+
486+
t.Run("no initial query", func(t *testing.T) {
487+
f, term := fuzzyfinder.NewWithMockedTerminal()
488+
term.SetEventsV2(events...)
489+
490+
assertWithGolden(t, func(t *testing.T) string {
491+
idx, err := f.Find(things, thingFunc)
492+
if err != nil {
493+
t.Fatalf("Find must not return an error, but got '%s'", err)
494+
}
495+
if idx != 0 {
496+
t.Errorf("expected index: 0, but got %d", idx)
497+
}
498+
res := term.GetResult()
499+
return res
500+
})
501+
})
502+
503+
t.Run("has initial query", func(t *testing.T) {
504+
f, term := fuzzyfinder.NewWithMockedTerminal()
505+
term.SetEventsV2(events...)
506+
507+
assertWithGolden(t, func(t *testing.T) string {
508+
idx, err := f.Find(things, thingFunc, fuzzyfinder.WithQuery("three2"))
509+
510+
if err != nil {
511+
t.Fatalf("Find must not return an error, but got '%s'", err)
512+
}
513+
if idx != 1 {
514+
t.Errorf("expected index: 1, but got %d", idx)
515+
}
516+
res := term.GetResult()
517+
return res
518+
})
519+
})
520+
}
521+
522+
func TestFind_WithSelectOne(t *testing.T) {
523+
t.Parallel()
524+
525+
cases := map[string]struct {
526+
things []string
527+
moreOpts []fuzzyfinder.Option
528+
expected int
529+
abort bool
530+
}{
531+
"only one option": {
532+
things: []string{"one"},
533+
expected: 0,
534+
},
535+
"more than one": {
536+
things: []string{"one", "two"},
537+
abort: true,
538+
},
539+
"has initial query": {
540+
things: []string{"one", "two"},
541+
moreOpts: []fuzzyfinder.Option{
542+
fuzzyfinder.WithQuery("two"),
543+
},
544+
expected: 1,
545+
},
546+
}
547+
548+
for name, c := range cases {
549+
c := c
550+
551+
t.Run(name, func(t *testing.T) {
552+
t.Parallel()
553+
f, term := fuzzyfinder.NewWithMockedTerminal()
554+
term.SetEventsV2(key(input{tcell.KeyEsc, rune(tcell.KeyEsc), tcell.ModNone}))
555+
556+
assertWithGolden(t, func(t *testing.T) string {
557+
idx, err := f.Find(
558+
c.things,
559+
func(i int) string {
560+
return c.things[i]
561+
},
562+
append(c.moreOpts, fuzzyfinder.WithSelectOne())...,
563+
)
564+
if c.abort {
565+
if !errors.Is(err, fuzzyfinder.ErrAbort) {
566+
t.Fatalf("Find must return ErrAbort, but got '%s'", err)
567+
}
568+
} else {
569+
if err != nil {
570+
t.Fatalf("Find must not return an error, but got '%s'", err)
571+
}
572+
if idx != c.expected {
573+
t.Errorf("expected index: %d, but got %d", c.expected, idx)
574+
}
575+
}
576+
res := term.GetResult()
577+
return res
578+
})
579+
})
580+
}
581+
}
582+
476583
func TestFind_error(t *testing.T) {
477584
t.Parallel()
478585

option.go

+16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ type opt struct {
1515
header string
1616
beginAtTop bool
1717
context context.Context
18+
query string
19+
selectOne bool
1820
}
1921

2022
type mode int
@@ -127,3 +129,17 @@ func WithContext(ctx context.Context) Option {
127129
o.context = ctx
128130
}
129131
}
132+
133+
// WithQuery enables to set the initial query.
134+
func WithQuery(s string) Option {
135+
return func(o *opt) {
136+
o.query = s
137+
}
138+
}
139+
140+
// WithQuery enables to set the initial query.
141+
func WithSelectOne() Option {
142+
return func(o *opt) {
143+
o.selectOne = true
144+
}
145+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
3+
4+
5+
6+
7+
8+
> three2one
9+
1/2
10+
> three2one█
11+

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
3+
4+
5+
6+
7+
three2one
8+
> one
9+
2/2
10+
> one█
11+

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
3+
4+
5+
6+
7+
8+
9+
10+
11+

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
3+
4+
5+
6+
7+
two
8+
> one
9+
2/2
10+
> █
11+

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
3+
4+
5+
6+
7+
8+
9+
10+
11+


0 commit comments

Comments
 (0)