First, install the latest version with go get
.
$ go get -u github.com/koki-develop/go-fzf
Next, import go-fzf.
import "github.com/koki-develop/go-fzf"
First, initialize Fuzzy Finder with fzf.New()
.
f, err := fzf.New()
if err != nil {
// ...
}
Next, Find()
launches Fuzzy Finder.
The first argument is the slice of the item to be searched.
The second argument is a function that returns the text of the i-th item.
idxs, err := f.Find(items, func(i int) string { return items[i] })
if err != nil {
// ...
}
fzf.WithLimit()
can be used to set the number of items that can be selected.
f, err := fzf.New(fzf.WithLimit(4))
if err != nil {
// ...
}
fzf.WithNoLimit()
allows unlimited item selection.
f, err := fzf.New(fzf.WithNoLimit(true)) // no limit
if err != nil {
// ...
}
fzf.WithCaseSensitive()
can be used to make fuzzy searches case-sensitive.
f, err := fzf.New(fzf.WithCaseSensitive(true))
if err != nil {
// ...
}
fzf.WithKeyMap()
can be used to customize the key mapping.
The key mapping that can be customized are as follows
Up
- Move cursor up.Down
- Move cursor down.Toggle
- Select or unselect items.Choose
- Complete search.Abort
- Abort search.
f, err := fzf.New(
fzf.WithNoLimit(true),
fzf.WithKeyMap(fzf.KeyMap{
Up: []string{"up", "ctrl+b"}, // ↑, Ctrl+b
Down: []string{"down", "ctrl+f"}, // ↓, Ctrl+f
Toggle: []string{"tab"}, // tab
Choose: []string{"enter"}, // Enter
Abort: []string{"esc"}, // esc
}),
)
if err != nil {
// ...
}
Hot reloading can be enabled using fzf.WithHotReload()
.
var items []string
var mu sync.Mutex
go func() {
i := 0
for {
time.Sleep(50 * time.Millisecond)
mu.Lock()
items = append(items, strconv.Itoa(i))
mu.Unlock()
i++
}
}()
// Pass locker
f, err := fzf.New(fzf.WithHotReload(&mu))
if err != nil {
// ...
}
// Note that a pointer to slice must be passed.
idxs, err := f.Find(&items, func(i int) string { return items[i] })
if err != nil {
// ...
}
- Prompt
- Cursor
- Prefix of selected/unselected items
- Position of input
- Placeholder for input
- Count View
- Preview Window
- Styles
fzf.WithPrompt()
can be used to set the prompt string.
f, err := fzf.New(fzf.WithPrompt("=> "))
if err != nil {
// ...
}
fzf.WithCursor()
can be used to set the cursor string.
f, err := fzf.New(fzf.WithCursor("=> "))
if err != nil {
// ...
}
fzf.WithSelectedPrefix()
can be used to set the prefix of selected items.
Similarly, fzf.WithUnselectedPrefix()
can be used to set the prefix of unselected items.
f, err := fzf.New(
fzf.WithNoLimit(true),
fzf.WithSelectedPrefix("[x] "),
fzf.WithUnselectedPrefix("[ ] "),
)
if err != nil {
// ...
}
fzf.WithInputPosition()
can be used to set the position of input.
f, err := fzf.New(
fzf.WithInputPosition(fzf.InputPositionBottom),
)
if err != nil {
// ...
}
fzf.WithCursor()
can be used to set the placeholder for input.
f, err := fzf.New(fzf.WithInputPlaceholder("Search..."))
if err != nil {
// ...
}
WithCountViewEnabled()
can be used to enable/disable the count view (enabled by default).
WithCountView()
can be used to set the function that renders the count view.
The argument of the function is a fzf.CountViewMeta
structure containing the necessary information for the count view.
f, err := fzf.New(
fzf.WithNoLimit(true),
fzf.WithCountViewEnabled(true),
fzf.WithCountView(func(meta fzf.CountViewMeta) string {
return fmt.Sprintf("items: %d, selected: %d", meta.ItemsCount, meta.SelectedCount)
}),
)
if err != nil {
// ...
}
You can set a function to render a preview window by passing fzf.PreviewWindow()
to the Find()
method.
The function argument is passed the index of the item at the cursor line and the size of the preview window.
files, err := os.ReadDir(".")
if err != nil {
// ...
}
f, err := fzf.New()
if err != nil {
// ...
}
idxs, err := f.Find(
files,
func(i int) string { return files[i].Name() },
fzf.WithPreviewWindow(func(i, width, height int) string {
info, _ := files[i].Info()
return fmt.Sprintf(
"Name: %s\nModTime: %s\nSize: %d bytes",
info.Name(), info.ModTime(), info.Size(),
)
}),
)
if err != nil {
// ...
}
WithStyles()
can be used to set the style of each component.
See reference for available styles.
f, err := fzf.New(
fzf.WithNoLimit(true),
fzf.WithStyles(
fzf.WithStylePrompt(fzf.Style{Faint: true}), // Prompt
fzf.WithStyleInputPlaceholder(fzf.Style{Faint: true, ForegroundColor: "#ff0000"}), // Placeholder for input
fzf.WithStyleInputText(fzf.Style{Italic: true}), // Input text
fzf.WithStyleCursor(fzf.Style{Bold: true}), // Cursor
fzf.WithStyleCursorLine(fzf.Style{Bold: true}), // Cursor line
fzf.WithStyleMatches(fzf.Style{ForegroundColor: "#ff0000"}), // Matched characters
fzf.WithStyleSelectedPrefix(fzf.Style{ForegroundColor: "#ff0000"}), // Prefix of selected items
fzf.WithStyleUnselectedPrefix(fzf.Style{Faint: true}), // Prefix of unselected items
),
)
if err != nil {
// ...
}