Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Commit

Permalink
Add Description function to multi select (#446)
Browse files Browse the repository at this point in the history
* feat: Add Description function to multi select

* Add multi select description test

* reset color

* push test for multi select descriptions

Co-authored-by: Alec Aivazis <alec@aivazis.com>
  • Loading branch information
Konkrad and AlecAivazis committed Sep 22, 2022
1 parent a98a037 commit 734e799
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 2 deletions.
14 changes: 13 additions & 1 deletion multiselect.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type MultiSelect struct {
VimMode bool
FilterMessage string
Filter func(filter string, value string, index int) bool
Description func(value string, index int) string
filter string
selectedIndex int
checked map[int]bool
Expand All @@ -43,6 +44,7 @@ type MultiSelectTemplateData struct {
Checked map[int]bool
SelectedIndex int
ShowHelp bool
Description func(value string, index int) string
PageEntries []core.OptionAnswer
Config *PromptConfig

Expand All @@ -59,12 +61,19 @@ func (m MultiSelectTemplateData) IterateOption(ix int, opt core.OptionAnswer) in
return copy
}

func (m MultiSelectTemplateData) GetDescription(opt core.OptionAnswer) string {
if m.Description == nil {
return ""
}
return m.Description(opt.Value, opt.Index)
}

var MultiSelectQuestionTemplate = `
{{- define "option"}}
{{- if eq .SelectedIndex .CurrentIndex }}{{color .Config.Icons.SelectFocus.Format }}{{ .Config.Icons.SelectFocus.Text }}{{color "reset"}}{{else}} {{end}}
{{- if index .Checked .CurrentOpt.Index }}{{color .Config.Icons.MarkedOption.Format }} {{ .Config.Icons.MarkedOption.Text }} {{else}}{{color .Config.Icons.UnmarkedOption.Format }} {{ .Config.Icons.UnmarkedOption.Text }} {{end}}
{{- color "reset"}}
{{- " "}}{{- .CurrentOpt.Value}}
{{- " "}}{{- .CurrentOpt.Value}}{{ if ne ($.GetDescription .CurrentOpt) "" }} - {{color "cyan"}}{{ $.GetDescription .CurrentOpt }}{{color "reset"}}{{end}}
{{end}}
{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
Expand Down Expand Up @@ -179,6 +188,7 @@ func (m *MultiSelect) OnChange(key rune, config *PromptConfig) {
SelectedIndex: idx,
Checked: m.checked,
ShowHelp: m.showingHelp,
Description: m.Description,
PageEntries: opts,
Config: config,
}
Expand Down Expand Up @@ -272,6 +282,7 @@ func (m *MultiSelect) Prompt(config *PromptConfig) (interface{}, error) {
tmplData := MultiSelectTemplateData{
MultiSelect: *m,
SelectedIndex: idx,
Description: m.Description,
Checked: m.checked,
PageEntries: opts,
Config: config,
Expand Down Expand Up @@ -342,6 +353,7 @@ func (m *MultiSelect) Cleanup(config *PromptConfig, val interface{}) error {
Checked: m.checked,
Answer: answer,
ShowAnswer: true,
Description: m.Description,
Config: config,
},
)
Expand Down
117 changes: 117 additions & 0 deletions multiselect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ func TestMultiSelectRender(t *testing.T) {
Default: []string{"bar", "buz"},
}

descriptions := []string{"oof", "rab", "zab", "zub"}

helpfulPrompt := prompt
helpfulPrompt.Help = "This is helpful"

Expand Down Expand Up @@ -127,6 +129,121 @@ func TestMultiSelectRender(t *testing.T) {
"\n",
),
},
{
"description all",
prompt,
MultiSelectTemplateData{
SelectedIndex: 2,
PageEntries: core.OptionAnswerList(prompt.Options),
Checked: map[int]bool{1: true, 3: true},
Description: func(value string, index int) string {
return descriptions[index]
},
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf(" %s foo - oof", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar - rab", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz - zab", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s buz - zub\n", defaultIcons().MarkedOption.Text),
},
"\n",
),
},
{
"description even",
prompt,
MultiSelectTemplateData{
SelectedIndex: 2,
PageEntries: core.OptionAnswerList(prompt.Options),
Checked: map[int]bool{1: true, 3: true},
Description: func(value string, index int) string {

if index%2 == 0 {
return descriptions[index]
}

return ""
},
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf(" %s foo - oof", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz - zab", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s buz\n", defaultIcons().MarkedOption.Text),
},
"\n",
),
},
{
"description never",
prompt,
MultiSelectTemplateData{
SelectedIndex: 2,
PageEntries: core.OptionAnswerList(prompt.Options),
Checked: map[int]bool{1: true, 3: true},
Description: func(value string, index int) string {
return ""
},
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf(" %s foo", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s buz\n", defaultIcons().MarkedOption.Text),
},
"\n",
),
},
{
"description repeat value",
prompt,
MultiSelectTemplateData{
SelectedIndex: 2,
PageEntries: core.OptionAnswerList(prompt.Options),
Checked: map[int]bool{1: true, 3: true},
Description: func(value string, index int) string {
return value
},
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf(" %s foo - foo", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar - bar", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz - baz", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s buz - buz\n", defaultIcons().MarkedOption.Text),
},
"\n",
),
},
{
"description print index",
prompt,
MultiSelectTemplateData{
SelectedIndex: 2,
PageEntries: core.OptionAnswerList(prompt.Options),
Checked: map[int]bool{1: true, 3: true},
Description: func(value string, index int) string {
return fmt.Sprint(index)
},
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf(" %s foo - 0", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar - 1", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz - 2", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s buz - 3\n", defaultIcons().MarkedOption.Text),
},
"\n",
),
},
}

for _, test := range tests {
Expand Down
14 changes: 13 additions & 1 deletion tests/multiselect.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

import (
"fmt"

"github.com/AlecAivazis/survey/v2"
"github.com/AlecAivazis/survey/v2/tests/util"
TestUtil "github.com/AlecAivazis/survey/v2/tests/util"
)

var answer = []string{}
Expand Down Expand Up @@ -42,6 +44,16 @@ var table = []TestUtil.TestTableEntry{
Default: []string{"Sundayaa"},
}, &answer, nil,
},
{
"descriptions", &survey.MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
Description: func(value string, index int) string {
return value + fmt.Sprint(index)

},
}, &answer, nil,
},
}

func main() {
Expand Down

0 comments on commit 734e799

Please sign in to comment.