func (f *finder) _draw() {
	width, height := f.term.Size()
	f.term.Clear()
	maxWidth := width
	if f.opt.previewFunc != nil {
		maxWidth = width/2 - 1
	}
	maxHeight := height
	var promptLinePad int
	for _, r := range []rune(f.opt.promptString) {
		style := tcell.StyleDefault.
			Foreground(tcell.ColorBlue).
			Background(tcell.ColorDefault)
		f.term.SetContent(promptLinePad, maxHeight-1, r, nil, style)
		promptLinePad++
	}
	var r rune
	var w int
	for _, r = range f.state.input {
		style := tcell.StyleDefault.
			Foreground(tcell.ColorDefault).
			Background(tcell.ColorDefault).
			Bold(true)
		f.term.SetContent(promptLinePad+w, maxHeight-1, r, nil, style)
		w += runewidth.RuneWidth(r)
	}
	f.term.ShowCursor(promptLinePad+f.state.cursorX, maxHeight-1)
	maxHeight--
	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--
	}
	for i, r := range fmt.Sprintf("%d/%d", len(f.state.matched), len(f.state.items)) {
		style := tcell.StyleDefault.
			Foreground(tcell.ColorYellow).
			Background(tcell.ColorDefault)
		f.term.SetContent(2+i, maxHeight-1, r, nil, style)
	}
	maxHeight--
	itemAreaHeight := maxHeight - 1
	matched := f.state.matched
	offset := f.state.cursorY
	y := f.state.y
	matched = matched[y-offset:]
	for i, m := range matched {
		if i > itemAreaHeight {
			break
		}
		if i == f.state.cursorY {
			style := tcell.StyleDefault.
				Foreground(tcell.ColorRed).
				Background(tcell.ColorBlack)
			f.term.SetContent(0, maxHeight-1-i, '>', nil, style)
			f.term.SetContent(1, maxHeight-1-i, ' ', nil, style)
		}
		if f.opt.multi {
			if _, ok := f.state.selection[m.Idx]; ok {
				style := tcell.StyleDefault.
					Foreground(tcell.ColorRed).
					Background(tcell.ColorBlack)
				f.term.SetContent(1, maxHeight-1-i, '>', nil, style)
			}
		}
		var posIdx int
		w := 2
		for j, r := range []rune(f.state.items[m.Idx]) {
			style := tcell.StyleDefault.
				Foreground(tcell.ColorDefault).
				Background(tcell.ColorDefault)
			hasHighlighted := false
			if posIdx < len(f.state.input) {
				from, to := m.Pos[0], m.Pos[1]
				if !(from == -1 && to == -1) && (from <= j && j <= to) {
					if unicode.ToLower(f.state.input[posIdx]) == unicode.ToLower(r) {
						style = tcell.StyleDefault.
							Foreground(tcell.ColorGreen).
							Background(tcell.ColorDefault)
						hasHighlighted = true
						posIdx++
					}
				}
			}
			if i == f.state.cursorY {
				if hasHighlighted {
					style = tcell.StyleDefault.
						Foreground(tcell.ColorDarkCyan).
						Bold(true).
						Background(tcell.ColorBlack)
				} else {
					style = tcell.StyleDefault.
						Foreground(tcell.ColorYellow).
						Bold(true).
						Background(tcell.ColorBlack)
				}
			}
			rw := runewidth.RuneWidth(r)
			if w+rw+2 > maxWidth {
				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, maxHeight-1-i, r, nil, style)
				w += rw
			}
		}
	}
}
_draw is used from draw with a timer.
package fuzzyfinder
import (
	"context"
	"flag"
	"fmt"
	"reflect"
	"sort"
	"strings"
	"sync"
	"time"
	"unicode"
	"unicode/utf8"
	"github.com/gdamore/tcell/v2"
	"github.com/ktr0731/go-fuzzyfinder/matching"
	runewidth "github.com/mattn/go-runewidth"
	"github.com/pkg/errors"
)
var (
	ErrAbort   = errors.New("abort")
	errEntered = errors.New("entered")
)
type state struct {
	items      []string            
	allMatched []matching.Matched  
	matched    []matching.Matched  
	x int
	cursorX int
	y int
	cursorY int
	input []rune
	selection map[int]int
	selectionIdx int
}
type finder struct {
	term      terminal
	stateMu   sync.RWMutex
	state     state
	drawTimer *time.Timer
	eventCh   chan struct{}
	opt       *opt
}
func newFinder() *finder {
	return &finder{}
}
func (f *finder) initFinder(items []string, matched []matching.Matched, opt opt) error {
	if f.term == nil {
		screen, err := tcell.NewScreen()
		if err != nil {
			return errors.Wrap(err, "failed to new screen")
		}
		f.term = &termImpl{
			screen: screen,
		}
		if err := f.term.Init(); err != nil {
			return errors.Wrap(err, "failed to initialize screen")
		}
	}
	f.opt = &opt
	f.state = state{}
	if opt.multi {
		f.state.selection = map[int]int{}
	}
	f.state.items = items
	f.state.matched = matched
	f.state.allMatched = matched
	if !isInTesting() {
		f.drawTimer = time.AfterFunc(0, func() {
			f._draw()
			f._drawPreview()
			f.term.Show()
		})
		f.drawTimer.Stop()
	}
	f.eventCh = make(chan struct{}, 30)  
	return nil
}
func (f *finder) updateItems(items []string, matched []matching.Matched) {
	f.stateMu.Lock()
	f.state.items = items
	f.state.matched = matched
	f.state.allMatched = matched
	f.stateMu.Unlock()
	f.eventCh <- struct{}{}
}