diff --git a/fuzzing_test.go b/fuzzing_test.go index cb1fdb1..49b83ee 100644 --- a/fuzzing_test.go +++ b/fuzzing_test.go @@ -135,10 +135,13 @@ func TestFuzz(t *testing.T) { var ( iface interface{} promptStr string + header string ) fuzz.Fuzz(&promptStr) + fuzz.Fuzz(&header) opts := []fuzzyfinder.Option{ fuzzyfinder.WithPromptString(promptStr), + fuzzyfinder.WithHeader(header), } if *hotReload { iface = &tracks diff --git a/fuzzyfinder.go b/fuzzyfinder.go index a6e19ed..caa2d51 100644 --- a/fuzzyfinder.go +++ b/fuzzyfinder.go @@ -123,6 +123,8 @@ func (f *finder) _draw() { maxWidth = width/2 - 1 } + maxHeight := height + // prompt line var promptLinePad int @@ -132,7 +134,7 @@ func (f *finder) _draw() { Foreground(tcell.ColorBlue). Background(tcell.ColorDefault) - f.term.SetContent(promptLinePad, height-1, r, nil, style) + f.term.SetContent(promptLinePad, maxHeight-1, r, nil, style) promptLinePad++ } var r rune @@ -144,10 +146,25 @@ func (f *finder) _draw() { Bold(true) // Add a space between '>' and runes. - f.term.SetContent(promptLinePad+w, height-1, r, nil, style) + f.term.SetContent(promptLinePad+w, maxHeight-1, r, nil, style) w += runewidth.RuneWidth(r) } - f.term.ShowCursor(promptLinePad+f.state.cursorX, height-1) + f.term.ShowCursor(promptLinePad+f.state.cursorX, maxHeight-1) + + maxHeight-- + + // Header line + if len(f.opt.header) > 0 { + w = 0 + for _, r := range []rune(runewidth.Truncate(f.opt.header, maxWidth-2, "..")) { + style := tcell.StyleDefault. + Foreground(tcell.ColorGreen). + Background(tcell.ColorDefault) + f.term.SetContent(2+w, maxHeight-1, r, nil, style) + w += runewidth.RuneWidth(r) + } + maxHeight-- + } // Number line for i, r := range fmt.Sprintf("%d/%d", len(f.state.matched), len(f.state.items)) { @@ -155,11 +172,12 @@ func (f *finder) _draw() { Foreground(tcell.ColorYellow). Background(tcell.ColorDefault) - f.term.SetContent(2+i, height-2, r, nil, style) + f.term.SetContent(2+i, maxHeight-1, r, nil, style) } + maxHeight-- // Item lines - itemAreaHeight := height - 2 - 1 + itemAreaHeight := maxHeight - 1 matched := f.state.matched offset := f.state.cursorY y := f.state.y @@ -175,8 +193,8 @@ func (f *finder) _draw() { Foreground(tcell.ColorRed). Background(tcell.ColorBlack) - f.term.SetContent(0, height-3-i, '>', nil, style) - f.term.SetContent(1, height-3-i, ' ', nil, style) + f.term.SetContent(0, maxHeight-1-i, '>', nil, style) + f.term.SetContent(1, maxHeight-1-i, ' ', nil, style) } if f.opt.multi { @@ -185,7 +203,7 @@ func (f *finder) _draw() { Foreground(tcell.ColorRed). Background(tcell.ColorBlack) - f.term.SetContent(1, height-3-i, '>', nil, style) + f.term.SetContent(1, maxHeight-1-i, '>', nil, style) } } @@ -226,11 +244,11 @@ func (f *finder) _draw() { rw := runewidth.RuneWidth(r) // Shorten item cells. if w+rw+2 > maxWidth { - f.term.SetContent(w, height-3-i, '.', nil, style) - f.term.SetContent(w+1, height-3-i, '.', nil, style) + f.term.SetContent(w, maxHeight-1-i, '.', nil, style) + f.term.SetContent(w+1, maxHeight-1-i, '.', nil, style) break } else { - f.term.SetContent(w, height-3-i, r, nil, style) + f.term.SetContent(w, maxHeight-1-i, r, nil, style) w += rw } } diff --git a/option.go b/option.go index 54ad27e..432df3b 100644 --- a/option.go +++ b/option.go @@ -6,6 +6,7 @@ type opt struct { multi bool hotReload bool promptString string + header string } type mode int @@ -70,3 +71,10 @@ func withMulti() Option { o.multi = true } } + +// WithHeader enables to set the header. +func WithHeader(s string) Option { + return func(o *opt) { + o.header = s + } +}