github.com/elves/elvish@v0.15.0/pkg/cli/addons/listing/listing.go (about) 1 // Package listing provides the custom listing addon. 2 package listing 3 4 import ( 5 "github.com/elves/elvish/pkg/cli" 6 "github.com/elves/elvish/pkg/ui" 7 ) 8 9 // Config is the configuration to start the custom listing addon. 10 type Config struct { 11 // Keybinding. 12 Binding cli.Handler 13 // Caption of the listing. If empty, defaults to " LISTING ". 14 Caption string 15 // A function that takes the query string and returns a list of Item's and 16 // the index of the Item to select. Required. 17 GetItems func(query string) (items []Item, selected int) 18 // A function to call when the user has accepted the selected item. If the 19 // return value is true, the listing will not be closed after accpeting. 20 // If unspecified, the Accept function default to a function that does 21 // nothing other than returning false. 22 Accept func(string) bool 23 // Whether to automatically accept when there is only one item. 24 AutoAccept bool 25 } 26 27 // Item is an item to show in the listing. 28 type Item struct { 29 // Passed to the Accept callback in Config. 30 ToAccept string 31 // How the item is shown. 32 ToShow ui.Text 33 } 34 35 // Start starts the custom listing addon. 36 func Start(app cli.App, cfg Config) { 37 if cfg.GetItems == nil { 38 app.Notify("internal error: GetItems must be specified") 39 return 40 } 41 if cfg.Accept == nil { 42 cfg.Accept = func(string) bool { return false } 43 } 44 if cfg.Caption == "" { 45 cfg.Caption = " LISTING " 46 } 47 accept := func(s string) { 48 retain := cfg.Accept(s) 49 if !retain { 50 cli.SetAddon(app, nil) 51 } 52 } 53 w := cli.NewComboBox(cli.ComboBoxSpec{ 54 CodeArea: cli.CodeAreaSpec{ 55 Prompt: cli.ModePrompt(cfg.Caption, true), 56 }, 57 ListBox: cli.ListBoxSpec{ 58 OverlayHandler: cfg.Binding, 59 OnAccept: func(it cli.Items, i int) { 60 accept(it.(items)[i].ToAccept) 61 }, 62 ExtendStyle: true, 63 }, 64 OnFilter: func(w cli.ComboBox, q string) { 65 it, selected := cfg.GetItems(q) 66 w.ListBox().Reset(items(it), selected) 67 if cfg.AutoAccept && len(it) == 1 { 68 accept(it[0].ToAccept) 69 } 70 }, 71 }) 72 cli.SetAddon(app, w) 73 app.Redraw() 74 } 75 76 type items []Item 77 78 func (it items) Len() int { return len(it) } 79 func (it items) Show(i int) ui.Text { return it[i].ToShow }