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

Add option to remove filters from select-type prompts #463

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

zimeg
Copy link
Contributor

@zimeg zimeg commented Oct 31, 2022

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)

The select prompt without an option to filter

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)

The multiselect prompt without an option to filter

Notes

  • A HideFilter option was not added to the global PromptConfig. This was (not) done since HideFilter: true in the PromptConfig would be overridden by the default value of HideFilter: 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.

Comment on lines -43 to +47
ShowAnswer bool
PageEntries []core.OptionAnswer
Checked map[int]bool
SelectedIndex int
Answer string
ShowAnswer bool
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was rearranged to better match select.go

@samcofer
Copy link

samcofer commented Apr 5, 2023

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.

@zimeg
Copy link
Contributor Author

zimeg commented Sep 14, 2023

@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}}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants