From c818a0c789ee6b8327cf55de5415109181f63bcb Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 11 Jan 2021 19:45:19 +0100 Subject: [PATCH] Improved autocomplete handling, incuding proper handling of the Tab key. Resolves #546 --- inputfield.go | 55 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/inputfield.go b/inputfield.go index 635da32..858bcc3 100644 --- a/inputfield.go +++ b/inputfield.go @@ -249,11 +249,13 @@ func (i *InputField) Autocomplete() *InputField { // Fill it with the entries. currentEntry := -1 + suffixLength := 9999 // I'm just waiting for the day somebody opens an issue with this number being too small. i.autocompleteList.Clear() for index, entry := range entries { i.autocompleteList.AddItem(entry, "", 0, nil) - if currentEntry < 0 && entry == i.text { + if strings.HasPrefix(entry, i.text) && len(entry)-len(i.text) < suffixLength { currentEntry = index + suffixLength = len(i.text) - len(entry) } } @@ -481,6 +483,21 @@ func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p return true } + // Change the autocomplete selection. + autocompleteSelect := func(offset int) { + count := i.autocompleteList.GetItemCount() + newEntry := i.autocompleteList.GetCurrentItem() + offset + if newEntry >= count { + newEntry = 0 + } else if newEntry < 0 { + newEntry = count - 1 + } + i.autocompleteList.SetCurrentItem(newEntry) + currentText, _ = i.autocompleteList.GetItemText(newEntry) // Don't trigger changed function twice. + currentText = stripTags(currentText) + i.SetText(currentText) + } + // Finish up. finish := func(key tcell.Key) { if i.done != nil { @@ -558,36 +575,34 @@ func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p home() case tcell.KeyEnd, tcell.KeyCtrlE: end() - case tcell.KeyEnter, tcell.KeyEscape: // We might be done. + case tcell.KeyEnter: + if i.autocompleteList != nil { + autocompleteSelect(0) + i.autocompleteList = nil + } else { + finish(key) + } + case tcell.KeyEscape: if i.autocompleteList != nil { i.autocompleteList = nil } else { finish(key) } - case tcell.KeyDown, tcell.KeyTab: // Autocomplete selection. + case tcell.KeyTab: if i.autocompleteList != nil { - count := i.autocompleteList.GetItemCount() - newEntry := i.autocompleteList.GetCurrentItem() + 1 - if newEntry >= count { - newEntry = 0 - } - i.autocompleteList.SetCurrentItem(newEntry) - currentText, _ = i.autocompleteList.GetItemText(newEntry) // Don't trigger changed function twice. - currentText = stripTags(currentText) - i.SetText(currentText) + autocompleteSelect(0) + } else { + finish(key) + } + case tcell.KeyDown: + if i.autocompleteList != nil { + autocompleteSelect(1) } else { finish(key) } case tcell.KeyUp, tcell.KeyBacktab: // Autocomplete selection. if i.autocompleteList != nil { - newEntry := i.autocompleteList.GetCurrentItem() - 1 - if newEntry < 0 { - newEntry = i.autocompleteList.GetItemCount() - 1 - } - i.autocompleteList.SetCurrentItem(newEntry) - currentText, _ = i.autocompleteList.GetItemText(newEntry) // Don't trigger changed function twice. - currentText = stripTags(currentText) - i.SetText(currentText) + autocompleteSelect(-1) } else { finish(key) }