78 lines
2 KiB
Go
78 lines
2 KiB
Go
|
package tui
|
||
|
|
||
|
import (
|
||
|
"github.com/gdamore/tcell/v2"
|
||
|
"github.com/rivo/tview"
|
||
|
)
|
||
|
|
||
|
type InputFieldWithHistory struct {
|
||
|
*tview.InputField
|
||
|
history []string
|
||
|
historyLimit int
|
||
|
historyPointer int
|
||
|
currentContent string
|
||
|
}
|
||
|
|
||
|
func NewInputFieldWithHistory(historyLimit int) *InputFieldWithHistory {
|
||
|
return &InputFieldWithHistory{
|
||
|
InputField: tview.NewInputField(),
|
||
|
historyLimit: historyLimit,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (f *InputFieldWithHistory) AddToHistory(s string) {
|
||
|
// Stop scrolling history on history change, need to start scrolling again.
|
||
|
defer func() { f.historyPointer = len(f.history) }()
|
||
|
|
||
|
// Used history data for search prompt, so just make that data recent.
|
||
|
if f.historyPointer != len(f.history) && s == f.history[f.historyPointer] {
|
||
|
f.history = append(f.history[:f.historyPointer], f.history[f.historyPointer+1:]...)
|
||
|
f.history = append(f.history, s)
|
||
|
}
|
||
|
|
||
|
if len(f.history) == f.historyLimit {
|
||
|
f.history = f.history[1:]
|
||
|
}
|
||
|
f.history = append(f.history, s)
|
||
|
}
|
||
|
|
||
|
func (f *InputFieldWithHistory) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
|
||
|
return f.WrapInputHandler(func(event *tcell.EventKey, _ func(tview.Primitive)) {
|
||
|
switch event.Key() {
|
||
|
case tcell.KeyDown:
|
||
|
if len(f.history) == 0 {
|
||
|
return
|
||
|
}
|
||
|
// Need to start iterating before.
|
||
|
if f.historyPointer == len(f.history) {
|
||
|
return
|
||
|
}
|
||
|
// Iterate to most recent prompts.
|
||
|
f.historyPointer++
|
||
|
// Stop iterating over history.
|
||
|
if f.historyPointer == len(f.history) {
|
||
|
f.InputField.SetText(f.currentContent)
|
||
|
return
|
||
|
}
|
||
|
f.InputField.SetText(f.history[f.historyPointer])
|
||
|
case tcell.KeyUp:
|
||
|
if len(f.history) == 0 {
|
||
|
return
|
||
|
}
|
||
|
// Start iterating over history.
|
||
|
if f.historyPointer == len(f.history) {
|
||
|
f.currentContent = f.InputField.GetText()
|
||
|
}
|
||
|
// End of history.
|
||
|
if f.historyPointer == 0 {
|
||
|
return
|
||
|
}
|
||
|
// Iterate to least recent prompts.
|
||
|
f.historyPointer--
|
||
|
f.InputField.SetText(f.history[f.historyPointer])
|
||
|
default:
|
||
|
f.InputField.InputHandler()(event, func(tview.Primitive) {})
|
||
|
}
|
||
|
})
|
||
|
}
|