k9s/internal/model/fish_buff.go

128 lines
2.6 KiB
Go

package model
import (
"sort"
)
// SuggestionListener listens for suggestions.
type SuggestionListener interface {
BuffWatcher
// SuggestionChanged notifies suggestion changes.
SuggestionChanged(text, sugg string)
}
// SuggestionFunc produces suggestions.
type SuggestionFunc func(text string) sort.StringSlice
// FishBuff represents a suggestion buffer.
type FishBuff struct {
*CmdBuff
suggestionFn SuggestionFunc
suggestion string
suggestions []string
suggestionIndex int
}
// NewFishBuff returns a new command buffer.
func NewFishBuff(key rune, kind BufferKind) *FishBuff {
return &FishBuff{
CmdBuff: NewCmdBuff(key, kind),
suggestionIndex: -1,
}
}
func (c *FishBuff) PrevSuggestion() (string, bool) {
if c.suggestionIndex < 0 {
return "", false
}
c.suggestionIndex--
if c.suggestionIndex < 0 {
c.suggestionIndex = len(c.suggestions) - 1
}
return c.suggestions[c.suggestionIndex], true
}
func (c *FishBuff) NextSuggestion() (string, bool) {
if c.suggestionIndex < 0 {
return "", false
}
c.suggestionIndex++
if c.suggestionIndex >= len(c.suggestions) {
c.suggestionIndex = 0
}
return c.suggestions[c.suggestionIndex], true
}
func (c *FishBuff) ClearSuggestions() {
c.suggestion, c.suggestionIndex = "", -1
}
func (c *FishBuff) CurrentSuggestion() (string, bool) {
if c.suggestionIndex < 0 {
return "", false
}
return c.suggestions[c.suggestionIndex], true
}
func (c *FishBuff) AutoSuggests() bool {
return true
}
func (f *FishBuff) Suggestions() []string {
if f.suggestionFn != nil {
return f.suggestionFn(string(f.buff))
}
return nil
}
// SetSuggestionFn sets up suggestions.
func (f *FishBuff) SetSuggestionFn(fn SuggestionFunc) {
f.suggestionFn = fn
}
// Notify publish suggestions to all listeners.
func (f *FishBuff) Notify() {
if f.suggestionFn == nil {
return
}
cc := f.suggestionFn(string(f.buff))
f.fireSuggestionChanged(cc)
}
// Add adds a new charater to the buffer.
func (f *FishBuff) Add(r rune) {
f.CmdBuff.Add(r)
if f.suggestionFn == nil {
return
}
cc := f.suggestionFn(string(f.buff))
f.fireSuggestionChanged(cc)
}
// Delete removes the last character from the buffer.
func (f *FishBuff) Delete() {
f.CmdBuff.Delete()
if f.suggestionFn == nil {
return
}
cc := f.suggestionFn(string(f.buff))
f.fireSuggestionChanged(cc)
}
func (f *FishBuff) fireSuggestionChanged(ss []string) {
f.suggestions, f.suggestionIndex = ss, 0
if ss == nil {
f.suggestionIndex, f.suggestion = -1, ""
return
}
f.suggestion = ss[f.suggestionIndex]
for _, l := range f.listeners {
if listener, ok := l.(SuggestionListener); ok {
listener.SuggestionChanged(f.GetText(), f.suggestion)
}
}
}