readline
readline copied to clipboard
Enable other kinds of autocompletion besides prefix
I'm trying to implement a fuzzy-search-based autocompleter and wrote the following:
package main
import (
"github.com/chzyer/readline"
"github.com/renstrom/fuzzysearch/fuzzy"
)
func nodeAutocompleter(s *state) readline.AutoCompleter {
haystack := make([]string, len(s.Nodes))
i := 0
for _, n := range s.Nodes {
haystack[i] = n.repr()
i++
}
return FuzzyCompleter{haystack}
}
type FuzzyCompleter struct {
haystack []string
}
func (fz FuzzyCompleter) Do(line []rune, pos int) ([][]rune, int) {
needle := string(line)
results := fuzzy.Find(needle, fz.haystack)
out := make([][]rune, len(results))
for i, result := range results {
out[i] = []rune(result)
}
return out, 0
}
The completer returned by nodeAutocompleter
works, it is great, but when I do select an option, it shows wrongly on the screen. For example, if my options are [mango grape passionfruit]
and I write pe
, the autocompleter will show me only grape
as an option -- great! -- but if I go on and select it, the line will display pegrape
.
This happens, if I could grasp it correctly, because when writing the selected value to the line readline
does not erase it and rewrite, but relies on the .Do()
function returning the number of characters that matched from the beggining of the autocompleted selection, which doesn't make sense in my case.
I don't know if this solution is feasible, but perhaps readline
could erase the number of chars returned by .Do()
from the actual line before writing the full content of the selected option, instead of stripping out that same number from the selected option.
Does that make sense?