k9s/internal/model/fish_buff.go

138 lines
2.9 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of K9s
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
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,
}
}
// PrevSuggestion returns the prev suggestion.
func (f *FishBuff) PrevSuggestion() (string, bool) {
if len(f.suggestions) == 0 {
return "", false
}
if f.suggestionIndex < 0 {
f.suggestionIndex = 0
} else {
f.suggestionIndex--
}
if f.suggestionIndex < 0 {
f.suggestionIndex = len(f.suggestions) - 1
}
return f.suggestions[f.suggestionIndex], true
}
// NextSuggestion returns the next suggestion.
func (f *FishBuff) NextSuggestion() (string, bool) {
if len(f.suggestions) == 0 {
return "", false
}
if f.suggestionIndex < 0 {
f.suggestionIndex = 0
} else {
f.suggestionIndex++
}
if f.suggestionIndex >= len(f.suggestions) {
f.suggestionIndex = 0
}
return f.suggestions[f.suggestionIndex], true
}
// ClearSuggestions clear out all suggestions.
func (f *FishBuff) ClearSuggestions() {
if len(f.suggestions) > 0 {
f.suggestions = f.suggestions[:0]
}
f.suggestionIndex = -1
}
// CurrentSuggestion returns the current suggestion.
func (f *FishBuff) CurrentSuggestion() (string, bool) {
if len(f.suggestions) == 0 || f.suggestionIndex < 0 || f.suggestionIndex >= len(f.suggestions) {
return "", false
}
return f.suggestions[f.suggestionIndex], true
}
// AutoSuggests returns true if model implements auto suggestions.
func (*FishBuff) AutoSuggests() bool {
return true
}
// Suggestions returns suggestions.
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(_ bool) {
if f.suggestionFn == nil {
return
}
f.fireSuggestionChanged(f.suggestionFn(string(f.buff)))
}
// Add adds a new character to the buffer.
func (f *FishBuff) Add(r rune) {
f.CmdBuff.Add(r)
f.Notify(false)
}
// Delete removes the last character from the buffer.
func (f *FishBuff) Delete() {
f.CmdBuff.Delete()
f.Notify(true)
}
func (f *FishBuff) fireSuggestionChanged(ss []string) {
f.suggestions, f.suggestionIndex = ss, 0
var suggest string
if len(ss) == 0 {
f.suggestionIndex = -1
} else {
suggest = ss[f.suggestionIndex]
}
f.SetText(f.GetText(), suggest)
}