package mode
import (
)
type Completion interface {
tk.ComboBox
}
type CompletionSpec struct {
Bindings tk.Bindings
Name string
Replace diag.Ranging
Items []CompletionItem
Filter FilterSpec
}
type CompletionItem struct {
ToShow string
ShowStyle ui.Style
ToInsert string
}
type completion struct {
tk.ComboBox
attached tk.CodeArea
}
var errNoCandidates = errors.New("no candidates")
func ( cli.App, CompletionSpec) (Completion, error) {
if len(.Items) == 0 {
return nil, errNoCandidates
}
:= tk.NewComboBox(tk.ComboBoxSpec{
CodeArea: tk.CodeAreaSpec{
Prompt: modePrompt(" COMPLETING "+.Name+" ", true),
Highlighter: .Filter.Highlighter,
},
ListBox: tk.ListBoxSpec{
Horizontal: true,
Bindings: .Bindings,
OnSelect: func( tk.Items, int) {
:= .(completionItems)[].ToInsert
.CodeArea().MutateState(func( *tk.CodeAreaState) {
.Pending = tk.PendingCode{
From: .Replace.From, To: .Replace.To, Content: }
})
},
OnAccept: func( tk.Items, int) {
.SetAddon(nil, true)
},
ExtendStyle: true,
},
OnFilter: func( tk.ComboBox, string) {
.ListBox().Reset(filterCompletionItems(.Items, .Filter.makePredicate()), 0)
},
})
return completion{, .CodeArea()}, nil
}
func ( completion) ( bool) {
.attached.MutateState(func( *tk.CodeAreaState) {
if {
.ApplyPending()
} else {
.Pending = tk.PendingCode{}
}
})
}
type completionItems []CompletionItem
func ( []CompletionItem, func(string) bool) completionItems {
var []CompletionItem
for , := range {
if (.ToShow) {
= append(, )
}
}
return
}
func ( completionItems) ( int) ui.Text {
return ui.Text{&ui.Segment{Style: [].ShowStyle, Text: [].ToShow}}
}
func ( completionItems) () int { return len() }