Documentation ¶
Overview ¶
Package wmenu creates menus for cli programs. It uses wlog for it's interface with the command line. It uses os.Stdin, os.Stdout, and os.Stderr with concurrency by default. wmenu allows you to change the color of the different parts of the menu. This package also creates it's own error structure so you can type assert if you need to. wmenu will validate all responses before calling any function. It will also figure out which function should be called so you don't have to.
Example (ErrorDuplicate) ¶
reader := strings.NewReader("1 1\r\n") //Simulates the user typing "1 1" and hitting the [enter] key optFunc := func() error { fmt.Println("Option 0 was chosen.") return nil } multiFunc := func(opts []Opt) error { for _, opt := range opts { fmt.Printf("%s has an id of %d.\n", opt.Text, opt.ID) } return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.MultipleAction(multiFunc) menu.Option("Option 0", "0", false, optFunc) menu.Option("Option 1", "1", false, nil) menu.Option("Option 2", "2", false, nil) err := menu.Run() if err != nil { if IsDuplicateErr(err) { fmt.Println("We caught the err: " + err.Error()) } else { log.Fatal(err) } }
Output: 0) Option 0 1) Option 1 2) Option 2 Choose an option. We caught the err: Duplicated response: 1
Example (ErrorInvalid) ¶
reader := strings.NewReader("3\r\n") //Simulates the user typing "3" and hitting the [enter] key optFunc := func() error { fmt.Println("Option 0 was chosen.") return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.Option("Option 0", "0", false, optFunc) menu.Option("Option 1", "1", false, nil) menu.Option("Option 2", "2", false, nil) err := menu.Run() if err != nil { if IsInvalidErr(err) { fmt.Println("We caught the err: " + err.Error()) } else { log.Fatal(err) } }
Output: 0) Option 0 1) Option 1 2) Option 2 Choose an option. We caught the err: Invalid response: 3
Example (ErrorNoResponse) ¶
reader := strings.NewReader("\r\n") //Simulates the user hitting the [enter] key optFunc := func() error { fmt.Println("Option 0 was chosen.") return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.Option("Option 0", "0", false, optFunc) menu.Option("Option 1", "1", false, nil) menu.Option("Option 2", "2", false, nil) err := menu.Run() if err != nil { if IsNoResponseErr(err) { fmt.Println("We caught the err: " + err.Error()) } else { log.Fatal(err) } }
Output: 0) Option 0 1) Option 1 2) Option 2 Choose an option. We caught the err: No response
Example (ErrorTooMany) ¶
reader := strings.NewReader("1 2\r\n") //Simulates the user typing "1 2" and hitting the [enter] key optFunc := func() error { fmt.Println("Option 0 was chosen.") return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.Option("Option 0", "0", false, optFunc) menu.Option("Option 1", "1", false, nil) menu.Option("Option 2", "2", false, nil) err := menu.Run() if err != nil { if IsTooManyErr(err) { fmt.Println("We caught the err: " + err.Error()) } else { log.Fatal(err) } }
Output: 0) Option 0 1) Option 1 2) Option 2 Choose an option. We caught the err: Too many responses
Example (Multiple) ¶
reader := strings.NewReader("1,2\r\n") //Simulates the user typing "1,2" and hitting the [enter] key optFunc := func() error { fmt.Println("Option 0 was chosen.") return nil } multiFunc := func(opts []Opt) error { for _, opt := range opts { fmt.Printf("%s has an id of %d.\n", opt.Text, opt.ID) } return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.MultipleAction(multiFunc) menu.SetSeparator(",") menu.Option("Option 0", "0", true, optFunc) menu.Option("Option 1", "1", false, nil) menu.Option("Option 2", "2", true, nil) err := menu.Run() if err != nil { log.Fatal(err) }
Output: 0) *Option 0 1) Option 1 2) *Option 2 Choose an option. Option 1 has an id of 1. Option 2 has an id of 2.
Example (MultipleDefault) ¶
reader := strings.NewReader("\r\n") //Simulates the user hitting the [enter] key optFunc := func() error { fmt.Println("Option 0 was chosen.") return nil } multiFunc := func(opts []Opt) error { for _, opt := range opts { fmt.Printf("%s has an id of %d.\n", opt.Text, opt.ID) } return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.MultipleAction(multiFunc) menu.Option("Option 0", "0", true, optFunc) menu.Option("Option 1", "1", false, nil) menu.Option("Option 2", "2", true, nil) err := menu.Run() if err != nil { log.Fatal(err) }
Output: 0) *Option 0 1) Option 1 2) *Option 2 Choose an option. Option 0 has an id of 0. Option 2 has an id of 2.
Example (OptionValue) ¶
type NameEntity struct { FirstName string LastName string } reader := strings.NewReader("1\r\n") //Simulates the user typing "1" and hitting the [enter] key optFunc := func() error { fmt.Println("Option 0 was chosen.") return nil } actFunc := func(opt Opt) error { name, ok := opt.Value.(NameEntity) if !ok { log.Fatal("Could not cast option's value to NameEntity") } fmt.Printf("%s has an id of %d.\n", opt.Text, opt.ID) fmt.Printf("Hello, %s %s.\n", name.FirstName, name.LastName) return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.Action(actFunc) menu.Option("Option 0", NameEntity{"Bill", "Bob"}, true, optFunc) menu.Option("Option 1", NameEntity{"John", "Doe"}, false, nil) menu.Option("Option 2", NameEntity{"Jane", "Doe"}, false, nil) err := menu.Run() if err != nil { log.Fatal(err) }
Output: 0) *Option 0 1) Option 1 2) Option 2 Choose an option. Option 1 has an id of 1. Hello, John Doe.
Example (SimpleDefault) ¶
reader := strings.NewReader("\r\n") //Simulates the user hitting the [enter] key optFunc := func() error { fmt.Fprint(os.Stdout, "Option 0 was chosen.") return nil } menu := NewMenu("Choose an option.") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.Option("Option 0", "0", true, optFunc) menu.Option("Option 1", "1", false, nil) menu.Option("Option 2", "2", false, nil) err := menu.Run() if err != nil { log.Fatal(err) }
Output: 0) *Option 0 1) Option 1 2) Option 2 Choose an option. Option 0 was chosen.
Example (YesNo) ¶
reader := strings.NewReader("y\r\n") //Simulates the user typing "y" and hitting the [enter] key actFunc := func(opt Opt) error { fmt.Printf("%s has an id of %d.\n", opt.Text, opt.ID) fmt.Printf("But has a value of %s.\n", opt.Value.(string)) return nil } menu := NewMenu("Would you like to start?") menu.ChangeReaderWriter(reader, os.Stdout, os.Stderr) menu.Action(actFunc) menu.IsYesNo(0) err := menu.Run() if err != nil { log.Fatal(err) }
Output: Would you like to start? (Y/n) y has an id of 0. But has a value of yes.
Index ¶
- Variables
- func Clear()
- func IsDuplicateErr(err error) bool
- func IsInvalidErr(err error) bool
- func IsMenuErr(err error) bool
- func IsNoResponseErr(err error) bool
- func IsTooManyErr(err error) bool
- type Menu
- func (m *Menu) Action(function func(Opt) error)
- func (m *Menu) AddColor(optionColor, questionColor, responseColor, errorColor wlog.Color)
- func (m *Menu) ChangeReaderWriter(reader io.Reader, writer, errorWriter io.Writer)
- func (m *Menu) ClearOnMenuRun()
- func (m *Menu) IsYesNo(def int)
- func (m *Menu) LoopOnInvalid()
- func (m *Menu) MultipleAction(function func([]Opt) error)
- func (m *Menu) Option(title string, value interface{}, isDefault bool, function func() error)
- func (m *Menu) Run() error
- func (m *Menu) SetDefaultIcon(icon string)
- func (m *Menu) SetSeparator(sep string)
- func (m *Menu) SetTries(i int)
- type MenuError
- type Opt
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( //ErrInvalid is returned if a response from user was an invalid option ErrInvalid = errors.New("Invalid response") //ErrTooMany is returned if multiSelect is false and a user tries to select multiple options ErrTooMany = errors.New("Too many responses") //ErrNoResponse is returned if there were no responses and no action to call ErrNoResponse = errors.New("No response") //ErrDuplicate is returned is a user selects an option twice ErrDuplicate = errors.New("Duplicated response") )
Functions ¶
func IsDuplicateErr ¶
IsDuplicateErr checks to see if err is of type duplicate returned by menu.
func IsInvalidErr ¶
IsInvalidErr checks to see if err is of type invalid error returned by menu.
func IsMenuErr ¶
IsMenuErr checks to see if it is a menu err. This is a general check not a specific one.
func IsNoResponseErr ¶
IsNoResponseErr checks to see if err is of type no response returned by menu.
func IsTooManyErr ¶
IsTooManyErr checks to see if err is of type too many returned by menu.
Types ¶
type Menu ¶
type Menu struct {
// contains filtered or unexported fields
}
Menu is used to display options to a user. A user can then select options and Menu will validate the response and perform the correct action.
func (*Menu) Action ¶
Action adds a default action to use in certain scenarios. If the selected option (by default or user selected) does not have a function applied to it this will be called. If there are no default options and no option was selected this will be called with an option that has an ID of -1.
func (*Menu) AddColor ¶
AddColor will change the color of the menu items. optionColor changes the color of the options. questionColor changes the color of the questions. errorColor changes the color of the question. Use wlog.None if you do not want to change the color.
func (*Menu) ChangeReaderWriter ¶
ChangeReaderWriter changes where the menu listens and writes to. reader is where user input is collected. writer and errorWriter is where the menu should write to.
func (*Menu) ClearOnMenuRun ¶
func (m *Menu) ClearOnMenuRun()
ClearOnMenuRun will clear the screen when a menu is ran. This is checked when LoopOnInvalid is activated. Meaning if an error occurred then it will clear the screen before asking again.
func (*Menu) IsYesNo ¶
IsYesNo sets the menu to a yes/no state. Does not show options but does ask question. Will also parse the answer to allow for all variants of yes/no (IE Y yes No ...) Specify the default value using def. 0 is for yes and 1 is for no. Both will call the Action function you specified. Opt{ID: 0, Text: "y"} for yes and Opt{ID: 1, Text: "n"} for no will be passed to the function.
func (*Menu) LoopOnInvalid ¶
func (m *Menu) LoopOnInvalid()
LoopOnInvalid is used if an invalid option was given then it will prompt the user again.
func (*Menu) MultipleAction ¶
MultipleAction is called when multiple options are selected (by default or user selected). If this is set then it uses the separator string specified by SetSeparator (Default is a space) to separate the responses. If this is not set then it is implied that the menu only allows for one option to be selected.
func (*Menu) Option ¶
Option adds an option to the menu for the user to select from. value is an empty interface that can be used to pass anything through to the function. title is the string the user will select isDefault is whether this option is a default option (IE when no options are selected). function is what is called when only this option is selected. If function is nil then it will default to the menu's Action.
func (*Menu) Run ¶
Run is used to execute the menu. It will print to options and question to the screen. It will only clear the screen if ClearOnMenuRun is activated. This will validate all responses. Errors are of type MenuError.
func (*Menu) SetDefaultIcon ¶
SetDefaultIcon sets the icon used to identify which options will be selected by default
func (*Menu) SetSeparator ¶
SetSeparator sets the separator to use when multiple options are valid responses. Default value is a space.