frostfs-node/cmd/frostfs-lens/internal/tui/input.go

78 lines
2 KiB
Go
Raw Normal View History

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) {})
}
})
}