survey
survey copied to clipboard
Add option to remove filters from select-type prompts
Summary
This PR provides an option to remove the filter from the Select
and MultiSelect
prompts. This is given as an option to restrict selection movement to the arrow keys to prevent options from being hidden by accidental keystrokes. 👻
Preview
Select
color := ""
prompt := &survey.Select{
Message: "Select a color:",
Options: []string{"red", "blue", "green"},
HideFilter: true,
}
survey.AskOne(prompt, &color)

MultiSelect
days := []string{}
prompt := &survey.MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
HideFilter: true,
}
survey.AskOne(prompt, &days)

Notes
- A
HideFilter
option was not added to the globalPromptConfig
. This was (not) done sinceHideFilter: true
in thePromptConfig
would be overridden by the default value ofHideFilter: false
in prompts where this value is not defined. -
HelpInput
isn't impacted by the removal of filtering, meaning.Help
text will still be shown after pressing the help key.
Just wanted to ping this PR, as this would be really helpful in a CLI I'm developing where the list of options can be extremely long, but generally filtering is disruptive to a users workflow.
@samcofer This same effect can be achieved with a permissive Filter
and some adjustments to the selection template. The following snippet can be used to match the first preview:
package main
import (
"github.com/AlecAivazis/survey/v2"
)
func main() {
survey.SelectQuestionTemplate = `
{{- define "option"}}
{{- if eq .SelectedIndex .CurrentIndex }}{{color .Config.Icons.SelectFocus.Format }}{{ .Config.Icons.SelectFocus.Text }} {{else}}{{color "default"}} {{end}}
{{- .CurrentOpt.Value}}{{ if ne ($.GetDescription .CurrentOpt) "" }} - {{color "cyan"}}{{ $.GetDescription .CurrentOpt }}{{end}}
{{- color "reset"}}
{{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"}}
{{- color "default+hb"}}{{ .Message }}{{color "reset"}}
{{- if .ShowAnswer}}{{color "cyan"}} {{.Answer}}{{color "reset"}}{{"\n"}}
{{- else}}
{{- " "}}{{- color "cyan"}}[Use arrows to move{{- if and .Help (not .ShowHelp)}}, {{ .Config.HelpInput }} for more help{{end}}]{{color "reset"}}
{{- "\n"}}
{{- range $ix, $option := .PageEntries}}
{{- template "option" $.IterateOption $ix $option}}
{{- end}}
{{- end}}`
color := ""
prompt := &survey.Select{
Message: "Select a color:",
Options: []string{"red", "blue", "green"},
Filter: func(filterValue string, optValue string, optIndex int) bool {
return true
},
}
survey.AskOne(prompt, &color)
}
The Filter
that always returns true means every option will match the filtering value, so typing won't change the results shown. The updates to the template hide any input provided to the filter. Both of these together remove filtering effects!
This dropdown shows the differences between the default template and this one.
{{- define "option"}}
{{- if eq .SelectedIndex .CurrentIndex }}{{color .Config.Icons.SelectFocus.Format }}{{ .Config.Icons.SelectFocus.Text }} {{else}}{{color "default"}} {{end}}
{{- .CurrentOpt.Value}}{{ if ne ($.GetDescription .CurrentOpt) "" }} - {{color "cyan"}}{{ $.GetDescription .CurrentOpt }}{{end}}
{{- color "reset"}}
{{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"}}
-{{- color "default+hb"}}{{ .Message }}{{ .FilterMessage }}{{color "reset"}}
+{{- color "default+hb"}}{{ .Message }}{{color "reset"}}
{{- if .ShowAnswer}}{{color "cyan"}} {{.Answer}}{{color "reset"}}{{"\n"}}
{{- else}}
- {{- " "}}{{- color "cyan"}}[Use arrows to move, type to filter{{- if and .Help (not .ShowHelp)}}, {{ .Config.HelpInput }} for more help{{end}}]{{color "reset"}}
+ {{- " "}}{{- color "cyan"}}[Use arrows to move{{- if and .Help (not .ShowHelp)}}, {{ .Config.HelpInput }} for more help{{end}}]{{color "reset"}}
{{- "\n"}}
{{- range $ix, $option := .PageEntries}}
{{- template "option" $.IterateOption $ix $option}}
{{- end}}
{{- end}}