func (l *SyncList) CanPageUp() bool {
	return l.start > 0
}
CanPageUp returns whether a list can still PageUp().
package prompt
import (
	"context"
	"fmt"
	"reflect"
	"sort"
	"strings"
	"github.com/isacikgoz/fuzzy"
)
type interfaceSource []interface{}
func (is interfaceSource) String(i int) string { return fmt.Sprint(is[i]) }
func (is interfaceSource) Len() int { return len(is) }
const NotFound = -1
type SyncList struct {
	items   []interface{}
	scope   []interface{}
	matches map[interface{}][]int
	cursor  int  
	size    int  
	start   int
	find    string
}
func NewList(items interface{}, size int) (*SyncList, error) {
	if size < 1 {
		return nil, fmt.Errorf("list size %d must be greater than 0", size)
	}
	if items == nil || reflect.TypeOf(items).Kind() != reflect.Slice {
		return nil, fmt.Errorf("items %v is not a slice", items)
	}
	slice := reflect.ValueOf(items)
	values := make([]interface{}, slice.Len())
	for i := range values {
		item := slice.Index(i)
		values[i] = item.Interface()
	}
	return &SyncList{
		size:  size,
		items: values,
		scope: values,
	}, nil
}
func (l *SyncList) Prev() {
	if l.cursor > 0 {
		l.cursor--
	}
	if l.start > l.cursor {
		l.start = l.cursor
	}
}
func (l *SyncList) Search(term string) {
	term = strings.Trim(term, " ")
	l.cursor = 0
	l.start = 0
	l.find = term
	l.search(term)
}
func (l *SyncList) CancelSearch() {
	l.cursor = 0
	l.start = 0
	l.scope = l.items
}
func (l *SyncList) search(term string) {
	if len(term) == 0 {
		l.scope = l.items
		return
	}
	l.matches = make(map[interface{}][]int)
	matches := fuzzy.FindFrom(context.Background(), term, interfaceSource(l.items))
	results := make([]fuzzy.Match, 0)
	for match := range matches {
		results = append(results, match)
	}
	sort.Stable(fuzzy.Sortable(results))
	l.scope = make([]interface{}, 0)
	for _, r := range results {
		item := l.items[r.Index]
		l.scope = append(l.scope, item)
		l.matches[item] = r.MatchedIndexes
	}
}
func (l *SyncList) Start() int {
	return l.start
}
func (l *SyncList) SetStart(i int) {
	if i < 0 {
		i = 0
	}
	if i > l.cursor {
		l.start = l.cursor
	} else {
		l.start = i
	}
}
func (l *SyncList) SetCursor(i int) {
	max := len(l.scope) - 1
	if i >= max {
		i = max
	}
	if i < 0 {
		i = 0
	}
	l.cursor = i
	if l.start > l.cursor {
		l.start = l.cursor
	} else if l.start+l.size <= l.cursor {
		l.start = l.cursor - l.size + 1
	}
}
func (l *SyncList) Next() {
	max := len(l.scope) - 1
	if l.cursor < max {
		l.cursor++
	}
	if l.start+l.size <= l.cursor {
		l.start = l.cursor - l.size + 1
	}
}
func (l *SyncList) PageUp() {
	start := l.start - l.size
	if start < 0 {
		l.start = 0
	} else {
		l.start = start
	}
	cursor := l.start
	if cursor < l.cursor {
		l.cursor = cursor
	}
}
func (l *SyncList) PageDown() {
	start := l.start + l.size
	max := len(l.scope) - l.size
	switch {
	case len(l.scope) < l.size:
		l.start = 0
	case start > max:
		l.start = max
	default:
		l.start = start
	}
	cursor := l.start
	if cursor == l.cursor {
		l.cursor = len(l.scope) - 1
	} else if cursor > l.cursor {
		l.cursor = cursor
	}
}
func (l *SyncList) CanPageDown() bool {
	max := len(l.scope)
	return l.start+l.size < max
}