survey

package module
v2.0.0-...-a6eaf7f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2024 License: MIT Imports: 20 Imported by: 0

README

Survey

GoDoc

A library for building interactive and accessible prompts on terminals supporting ANSI escape sequences.

⚠️ This project is no longer maintained. For an alternative, please check out: https://github.com/charmbracelet/bubbletea ⚠️

Hey everyone! I finally came to terms with the fact that I can no longer dedicate enough time to keep this library alive. This project outgrew my wildest expectations and was such a great experience. If someone else wants to take over maintainence, please reach out

package main

import (
    "fmt"
    "github.com/adrianbrandt/survey/v2"
)

// the questions to ask
var qs = []*survey.Question{
    {
        Name:     "name",
        Prompt:   &survey.Input{Message: "What is your name?"},
        Validate: survey.Required,
        Transform: survey.Title,
    },
    {
        Name: "color",
        Prompt: &survey.Select{
            Message: "Choose a color:",
            Options: []string{"red", "blue", "green"},
            Default: "red",
        },
    },
    {
        Name: "age",
        Prompt:   &survey.Input{Message: "How old are you?"},
    },
}

func main() {
    // the answers will be written to this struct
    answers := struct {
        Name          string                  // survey will match the question and field names
        FavoriteColor string `survey:"color"` // or you can tag fields to match a specific name
        Age           int                     // if the types don't match, survey will convert it
    }{}

    // perform the questions
    err := survey.Ask(qs, &answers)
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    fmt.Printf("%s chose %s.", answers.Name, answers.FavoriteColor)
}

Examples

Examples can be found in the examples/ directory. Run them to see basic behavior:

go run examples/simple.go
go run examples/validation.go

Running the Prompts

There are two primary ways to execute prompts and start collecting information from your users: Ask and AskOne. The primary difference is whether you are interested in collecting a single piece of information or if you have a list of questions to ask whose answers should be collected in a single struct. For most basic usecases, Ask should be enough. However, for surveys with complicated branching logic, we recommend that you break out your questions into multiple calls to both of these functions to fit your needs.

Configuring the Prompts

Most prompts take fine-grained configuration through fields on the structs you instantiate. It is also possible to change survey's default behaviors by passing AskOpts to either Ask or AskOne. Examples in this document will do both interchangeably:

prompt := &Select{
    Message: "Choose a color:",
    Options: []string{"red", "blue", "green"},
    // can pass a validator directly
    Validate: survey.Required,
}

// or define a default for the single call to `AskOne`
// the answer will get written to the color variable
survey.AskOne(prompt, &color, survey.WithValidator(survey.Required))

// or define a default for every entry in a list of questions
// the answer will get copied into the matching field of the struct as shown above
survey.Ask(questions, &answers, survey.WithValidator(survey.Required))

Prompts

Input
name := ""
prompt := &survey.Input{
    Message: "ping",
}
survey.AskOne(prompt, &name)
Suggestion Options
file := ""
prompt := &survey.Input{
    Message: "inform a file to save:",
    Suggest: func (toComplete string) []string {
        files, _ := filepath.Glob(toComplete + "*")
        return files
    },
}
}
survey.AskOne(prompt, &file)
Multiline
text := ""
prompt := &survey.Multiline{
    Message: "ping",
}
survey.AskOne(prompt, &text)
Password
password := ""
prompt := &survey.Password{
    Message: "Please type your password",
}
survey.AskOne(prompt, &password)
Confirm
name := false
prompt := &survey.Confirm{
    Message: "Do you like pie?",
}
survey.AskOne(prompt, &name)
Select
color := ""
prompt := &survey.Select{
    Message: "Choose a color:",
    Options: []string{"red", "blue", "green"},
}
survey.AskOne(prompt, &color)

Fields and values that come from a Select prompt can be one of two different things. If you pass an int the field will have the value of the selected index. If you instead pass a string, the string value selected will be written to the field.

The user can also press esc to toggle the ability cycle through the options with the j and k keys to do down and up respectively.

By default, the select prompt is limited to showing 7 options at a time and will paginate lists of options longer than that. This can be changed a number of ways:

// as a field on a single select
prompt := &survey.MultiSelect{..., PageSize: 10}

// or as an option to Ask or AskOne
survey.AskOne(prompt, &days, survey.WithPageSize(10))
Select options description

The optional description text can be used to add extra information to each option listed in the select prompt:

color := ""
prompt := &survey.Select{
    Message: "Choose a color:",
    Options: []string{"red", "blue", "green"},
    Description: func(value string, index int) string {
        if value == "red" {
            return "My favorite color"
        }
        return ""
    },
}
survey.AskOne(prompt, &color)

// Assuming that the user chose "red - My favorite color":
fmt.Println(color) //=> "red"
MultiSelect

Example

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

Fields and values that come from a MultiSelect prompt can be one of two different things. If you pass an int the field will have a slice of the selected indices. If you instead pass a string, a slice of the string values selected will be written to the field.

The user can also press esc to toggle the ability cycle through the options with the j and k keys to do down and up respectively.

By default, the MultiSelect prompt is limited to showing 7 options at a time and will paginate lists of options longer than that. This can be changed a number of ways:

// as a field on a single select
prompt := &survey.MultiSelect{..., PageSize: 10}

// or as an option to Ask or AskOne
survey.AskOne(prompt, &days, survey.WithPageSize(10))
Editor

Launches the user's preferred editor (defined by the $VISUAL or $EDITOR environment variables) on a temporary file. Once the user exits their editor, the contents of the temporary file are read in as the result. If neither of those are present, notepad (on Windows) or vim (Linux or Mac) is used.

You can also specify a pattern for the name of the temporary file. This can be useful for ensuring syntax highlighting matches your usecase.

prompt := &survey.Editor{
    Message: "Shell code snippet",
    FileName: "*.sh",
}

survey.AskOne(prompt, &content)

Filtering Options

By default, the user can filter for options in Select and MultiSelects by typing while the prompt is active. This will filter out all options that don't contain the typed string anywhere in their name, ignoring case.

A custom filter function can also be provided to change this behavior:

func myFilter(filterValue string, optValue string, optIndex int) bool {
    // only include the option if it includes the filter and has length greater than 5
    return strings.Contains(optValue, filterValue) && len(optValue) >= 5
}

// configure it for a specific prompt
&Select{
    Message: "Choose a color:",
    Options: []string{"red", "blue", "green"},
    Filter: myFilter,
}

// or define a default for all of the questions
survey.AskOne(prompt, &color, survey.WithFilter(myFilter))

Keeping the filter active

By default the filter will disappear if the user selects one of the filtered elements. Once the user selects one element the filter setting is gone.

However the user can prevent this from happening and keep the filter active for multiple selections in a e.g. MultiSelect:

// configure it for a specific prompt
&Select{
    Message:    "Choose a color:",
    Options:    []string{"light-green", "green", "dark-green", "red"},
    KeepFilter: true,
}

// or define a default for all of the questions
survey.AskOne(prompt, &color, survey.WithKeepFilter(true))

Validation

Validating individual responses for a particular question can be done by defining a Validate field on the survey.Question to be validated. This function takes an interface{} type and returns an error to show to the user, prompting them for another response. Like usual, validators can be provided directly to the prompt or with survey.WithValidator:

q := &survey.Question{
    Prompt: &survey.Input{Message: "Hello world validation"},
    Validate: func (val interface{}) error {
        // since we are validating an Input, the assertion will always succeed
        if str, ok := val.(string) ; !ok || len(str) > 10 {
            return errors.New("This response cannot be longer than 10 characters.")
        }
	return nil
    },
}

color := ""
prompt := &survey.Input{ Message: "Whats your name?" }

// you can pass multiple validators here and survey will make sure each one passes
survey.AskOne(prompt, &color, survey.WithValidator(survey.Required))
Built-in Validators

survey comes prepackaged with a few validators to fit common situations. Currently these validators include:

name valid types description notes
Required any Rejects zero values of the response type Boolean values pass straight through since the zero value (false) is a valid response
MinLength(n) string Enforces that a response is at least the given length
MaxLength(n) string Enforces that a response is no longer than the given length
MaxItems(n) []OptionAnswer Enforces that a response has no more selections of the indicated
MinItems(n) []OptionAnswer Enforces that a response has no less selections of the indicated

Help Text

All of the prompts have a Help field which can be defined to provide more information to your users:

&survey.Input{
    Message: "What is your phone number:",
    Help:    "Phone number should include the area code",
}

Removing the "Select All" and "Select None" options

By default, users can select all of the multi-select options using the right arrow key. To prevent users from being able to do this (and remove the <right> to all message from the prompt), use the option WithRemoveSelectAll:

import (
    "github.com/adrianbrandt/survey/v2"
)

number := ""
prompt := &survey.Input{
    Message: "This question has the select all option removed",
}

survey.AskOne(prompt, &number, survey.WithRemoveSelectAll())

Also by default, users can use the left arrow key to unselect all of the options. To prevent users from being able to do this (and remove the <left> to none message from the prompt), use the option WithRemoveSelectNone:

import (
    "github.com/adrianbrandt/survey/v2"
)

number := ""
prompt := &survey.Input{
    Message: "This question has the select all option removed",
}

survey.AskOne(prompt, &number, survey.WithRemoveSelectNone())
Changing the input rune

In some situations, ? is a perfectly valid response. To handle this, you can change the rune that survey looks for with WithHelpInput:

import (
    "github.com/adrianbrandt/survey/v2"
)

number := ""
prompt := &survey.Input{
    Message: "If you have this need, please give me a reasonable message.",
    Help:    "I couldn't come up with one.",
}

survey.AskOne(prompt, &number, survey.WithHelpInput('^'))

Changing the Icons

Changing the icons and their color/format can be done by passing the WithIcons option. The format follows the patterns outlined here. For example:

import (
    "github.com/adrianbrandt/survey/v2"
)

number := ""
prompt := &survey.Input{
    Message: "If you have this need, please give me a reasonable message.",
    Help:    "I couldn't come up with one.",
}

survey.AskOne(prompt, &number, survey.WithIcons(func(icons *survey.IconSet) {
    // you can set any icons
    icons.Question.Text = "⁇"
    // for more information on formatting the icons, see here: https://github.com/mgutz/ansi#style-format
    icons.Question.Format = "yellow+hb"
}))

The icons and their default text and format are summarized below:

name text format description
Error X red Before an error
Help i cyan Before help text
Question ? green+hb Before the message of a prompt
SelectFocus > green Marks the current focus in Select and MultiSelect prompts
UnmarkedOption [ ] default+hb Marks an unselected option in a MultiSelect prompt
MarkedOption [x] cyan+b Marks a chosen selection in a MultiSelect prompt

Custom Types

survey will assign prompt answers to your custom types if they implement this interface:

type Settable interface {
    WriteAnswer(field string, value interface{}) error
}

Here is an example how to use them:

type MyValue struct {
    value string
}
func (my *MyValue) WriteAnswer(name string, value interface{}) error {
     my.value = value.(string)
}

myval := MyValue{}
survey.AskOne(
    &survey.Input{
        Message: "Enter something:",
    },
    &myval
)

Testing

You can test your program's interactive prompts using go-expect. The library can be used to expect a match on stdout and respond on stdin. Since os.Stdout in a go test process is not a TTY, if you are manipulating the cursor or using survey, you will need a way to interpret terminal / ANSI escape sequences for things like CursorLocation. vt10x.NewVT10XConsole will create a go-expect console that also multiplexes stdio to an in-memory virtual terminal.

For some examples, you can see any of the tests in this repo.

FAQ

What kinds of IO are supported by survey?

survey aims to support most terminal emulators; it expects support for ANSI escape sequences. This means that reading from piped stdin or writing to piped stdout is not supported, and likely to break your application in these situations. See #337

Why isn't Ctrl-C working?

Ordinarily, when you type Ctrl-C, the terminal recognizes this as the QUIT button and delivers a SIGINT signal to the process, which terminates it. However, Survey temporarily configures the terminal to deliver control codes as ordinary input bytes. When Survey reads a ^C byte (ASCII \x03, "end of text"), it interrupts the current survey and returns a github.com/adrianbrandt/survey/v2/terminal.InterruptErr from Ask or AskOne. If you want to stop the process, handle the returned error in your code:

err := survey.AskOne(prompt, &myVar)
if err != nil {
	if err == terminal.InterruptErr {
		log.Fatal("interrupted")
	}
	...
}

Documentation

Index

Constants

View Source
const (
	FGBold attribute
	FGFaint
	FGItalic
	FGUnderline
)

The possible state of text inside the application, either Bold, faint, italic or underline.

These constants are called through the use of the Styler function.

View Source
const (
	FGBlack attribute = iota + 30
	FGRed
	FGGreen
	FGYellow
	FGBlue
	FGMagenta
	FGCyan
	FGWhite
)

The possible colors of text inside the application.

These constants are called through the use of the Styler function.

View Source
const (
	BGBlack attribute = iota + 40
	BGRed
	BGGreen
	BGYellow
	BGBlue
	BGMagenta
	BGCyan
	BGWhite
)

The possible background colors of text inside the application.

These constants are called through the use of the Styler function.

Variables

View Source
var (
	// IconInitial is the icon used when starting in prompt mode and the icon next to the label when
	// starting in select mode.
	IconInitial = Styler(FGBlue)("?")

	// IconGood is the icon used when a good answer is entered in prompt mode.
	IconGood = Styler(FGGreen)("✔")

	// IconWarn is the icon used when a good, but potentially invalid answer is entered in prompt mode.
	IconWarn = Styler(FGYellow)("⚠")

	// IconBad is the icon used when a bad answer is entered in prompt mode.
	IconBad = Styler(FGRed)("✗")

	// IconSelect is the icon used to identify the currently selected item in select mode.
	IconSelect = Styler(FGBold)("▸")
)

These are the default icons used by promptui for select and prompts. These should not be overridden and instead customized through the use of custom templates

View Source
var ConfirmQuestionTemplate = `` /* 571-byte string literal not displayed */

Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format

View Source
var EditorQuestionTemplate = `` /* 656-byte string literal not displayed */

Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format

View Source
var ErrorTemplate = `{{color .Icon.Format }}{{ .Icon.Text }} Sorry, your reply was invalid: {{ .Error.Error }}{{color "reset"}}
`
View Source
var FuncMap = template.FuncMap{
	"black":     Styler(FGBlack),
	"red":       Styler(FGRed),
	"green":     Styler(FGGreen),
	"yellow":    Styler(FGYellow),
	"blue":      Styler(FGBlue),
	"magenta":   Styler(FGMagenta),
	"cyan":      Styler(FGCyan),
	"white":     Styler(FGWhite),
	"bgBlack":   Styler(BGBlack),
	"bgRed":     Styler(BGRed),
	"bgGreen":   Styler(BGGreen),
	"bgYellow":  Styler(BGYellow),
	"bgBlue":    Styler(BGBlue),
	"bgMagenta": Styler(BGMagenta),
	"bgCyan":    Styler(BGCyan),
	"bgWhite":   Styler(BGWhite),
	"bold":      Styler(FGBold),
	"faint":     Styler(FGFaint),
	"italic":    Styler(FGItalic),
	"underline": Styler(FGUnderline),
}

FuncMap defines template helpers for the output. It can be extended as a regular map.

The functions inside the map link the state, color and background colors strings detected in templates to a Styler function that applies the given style using the corresponding constant.

View Source
var InputQuestionTemplate = `` /* 1153-byte string literal not displayed */

Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format

View Source
var MultiSelectQuestionTemplate = `` /* 1425-byte string literal not displayed */
View Source
var MultilineQuestionTemplate = `` /* 566-byte string literal not displayed */

Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format

View Source
var PasswordQuestionTemplate = `` /* 392-byte string literal not displayed */

PasswordQuestionTemplate is a template with color formatting. See Documentation: https://github.com/mgutz/ansi#style-format

View Source
var ResetCode = fmt.Sprintf("%s%dm", esc, reset)

ResetCode is the character code used to reset the terminal formatting

View Source
var SelectQuestionTemplate = `` /* 1033-byte string literal not displayed */

Functions

func ApplyTemplate

func ApplyTemplate(tmplStr string, data interface{}) (string, error)

func Ask

func Ask(qs []*Question, response interface{}, opts ...AskOpt) error

Ask performs the prompt loop, asking for validation when appropriate. The response type can be one of two options. If a struct is passed, the answer will be written to the field whose name matches the Name field on the corresponding question. Field types should be something that can be casted from the response type designated in the documentation. Note, a survey tag can also be used to identify a Otherwise, a map[string]interface{} can be passed, responses will be written to the key with the matching name. For example:

qs := []*survey.Question{
	{
		Name:     "name",
		Prompt:   &survey.Input{Message: "What is your name?"},
		Validate: survey.Required,
		Transform: survey.Title,
	},
}

answers := struct{ Name string }{}

err := survey.Ask(qs, &answers)

func AskOne

func AskOne(p Prompt, response interface{}, opts ...AskOpt) error

AskOne performs the prompt for a single prompt and asks for validation if required. Response types should be something that can be casted from the response type designated in the documentation. For example:

name := ""
prompt := &survey.Input{
	Message: "name",
}

survey.AskOne(prompt, &name)

func Required

func Required(val interface{}) error

Required does not allow an empty value

func Styler

func Styler(attrs ...attribute) func(interface{}) string

Styler is a function that accepts multiple possible styling transforms from the state, color and background colors constants and transforms them into a templated string to apply those styles in the CLI.

The returned styling function accepts a string that will be extended with the wrapping function's styling attributes.

func Title

func Title(ans interface{}) interface{}

Title is a `Transformer`. It receives an answer value and returns a copy of the "ans" with all Unicode letters that begin words mapped to their title case.

Note that if "ans" is not a string then it will return a nil value, meaning that the above answer will not be affected by this call at all.

func ToLower

func ToLower(ans interface{}) interface{}

ToLower is a `Transformer`. It receives an answer value and returns a copy of the "ans" with all Unicode letters mapped to their lower case.

Note that if "ans" is not a string then it will return a nil value, meaning that the above answer will not be affected by this call at all.

Types

type AskOpt

type AskOpt func(options *AskOptions) error

AskOpt allows setting optional ask options.

func WithFilter

func WithFilter(filter func(filter string, value string, index int) (include bool)) AskOpt

WithFilter specifies the default filter to use when asking questions.

func WithHelpInput

func WithHelpInput(r rune) AskOpt

WithHelpInput changes the character that prompts look for to give the user helpful information.

func WithHideCharacter

func WithHideCharacter(char rune) AskOpt

WithHideCharacter sets the default character shown instead of the password for password inputs

func WithIcons

func WithIcons(setIcons func(*IconSet)) AskOpt

WithIcons sets the icons that will be used when prompting the user

func WithKeepFilter

func WithKeepFilter(KeepFilter bool) AskOpt

WithKeepFilter sets the if the filter is kept after selections

func WithPageSize

func WithPageSize(pageSize int) AskOpt

WithPageSize sets the default page size used by prompts

func WithRemoveSelectAll

func WithRemoveSelectAll() AskOpt

WithRemoveSelectAll remove the select all option in Multiselect

func WithRemoveSelectNone

func WithRemoveSelectNone() AskOpt

WithRemoveSelectNone remove the select none/unselect all in Multiselect

func WithShowCursor

func WithShowCursor(ShowCursor bool) AskOpt

WithShowCursor sets the show cursor behavior when prompting the user

func WithStdio

func WithStdio(in terminal.FileReader, out terminal.FileWriter, err io.Writer) AskOpt

WithStdio specifies the standard input, output and error files survey interacts with. By default, these are os.Stdin, os.Stdout, and os.Stderr.

func WithValidator

func WithValidator(v Validator) AskOpt

WithValidator specifies a validator to use while prompting the user

type AskOptions

type AskOptions struct {
	Stdio        terminal.Stdio
	Validators   []Validator
	PromptConfig PromptConfig
}

AskOptions provides additional options on ask.

type Confirm

type Confirm struct {
	Renderer
	Message string
	Default bool
	Help    string
}

Confirm is a regular text input that accept yes/no answers. Response type is a bool.

func (*Confirm) Cleanup

func (c *Confirm) Cleanup(config *PromptConfig, val interface{}) error

Cleanup overwrite the line with the finalized formatted version

func (*Confirm) Prompt

func (c *Confirm) Prompt(config *PromptConfig) (interface{}, error)

Prompt prompts the user with a simple text field and expects a reply followed by a carriage return.

likesPie := false
prompt := &survey.Confirm{ Message: "What is your name?" }
survey.AskOne(prompt, &likesPie)

type ConfirmTemplateData

type ConfirmTemplateData struct {
	Confirm
	Answer   string
	ShowHelp bool
	Config   *PromptConfig
}

data available to the templates when processing

type Editor

type Editor struct {
	Renderer
	Message       string
	Default       string
	Help          string
	Editor        string
	HideDefault   bool
	AppendDefault bool
	FileName      string
}

Editor launches an instance of the users preferred editor on a temporary file. The editor to use is determined by reading the $VISUAL or $EDITOR environment variables. If neither of those are present, notepad (on Windows) or vim (others) is used. The launch of the editor is triggered by the enter key. Since the response may be long, it will not be echoed as Input does, instead, it print <Received>. Response type is a string.

message := ""
prompt := &survey.Editor{ Message: "What is your commit message?" }
survey.AskOne(prompt, &message)

func (*Editor) Cleanup

func (e *Editor) Cleanup(config *PromptConfig, val interface{}) error

func (*Editor) Prompt

func (e *Editor) Prompt(config *PromptConfig) (interface{}, error)

func (*Editor) PromptAgain

func (e *Editor) PromptAgain(config *PromptConfig, invalid interface{}, err error) (interface{}, error)

type EditorTemplateData

type EditorTemplateData struct {
	Editor
	Answer     string
	ShowAnswer bool
	ShowHelp   bool
	Config     *PromptConfig
}

data available to the templates when processing

type ErrorTemplateData

type ErrorTemplateData struct {
	Error error
	Icon  Icon
}

type Icon

type Icon struct {
	Text   string
	Format string
}

Icon holds the text and format to show for a particular icon

type IconSet

type IconSet struct {
	HelpInput      Icon
	Error          Icon
	Help           Icon
	Question       Icon
	MarkedOption   Icon
	UnmarkedOption Icon
	SelectFocus    Icon
}

IconSet holds the icons to use for various prompts

type Input

type Input struct {
	Renderer
	Message string
	Default string
	Help    string
	Suggest func(toComplete string) []string
	// contains filtered or unexported fields
}

Input is a regular text input that prints each character the user types on the screen and accepts the input with the enter key. Response type is a string.

name := ""
prompt := &survey.Input{ Message: "What is your name?" }
survey.AskOne(prompt, &name)

func (*Input) Cleanup

func (i *Input) Cleanup(config *PromptConfig, val interface{}) error

func (*Input) Prompt

func (i *Input) Prompt(config *PromptConfig) (interface{}, error)

type InputTemplateData

type InputTemplateData struct {
	Input
	ShowAnswer    bool
	ShowHelp      bool
	Answer        string
	PageEntries   []core.OptionAnswer
	SelectedIndex int
	Config        *PromptConfig
}

data available to the templates when processing

type IterableOpts

type IterableOpts interface {
	IterateOption(int, core.OptionAnswer) interface{}
}

type MultiSelect

type MultiSelect struct {
	Renderer
	Message       string
	Options       []string
	Default       interface{}
	Help          string
	PageSize      int
	VimMode       bool
	FilterMessage string
	Filter        func(filter string, value string, index int) bool
	Description   func(value string, index int) string
	// contains filtered or unexported fields
}

MultiSelect is a prompt that presents a list of various options to the user for them to select using the arrow keys and enter. Response type is a slice of strings.

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

func (*MultiSelect) Cleanup

func (m *MultiSelect) Cleanup(config *PromptConfig, val interface{}) error

Cleanup removes the options section, and renders the ask like a normal question.

func (*MultiSelect) OnChange

func (m *MultiSelect) OnChange(key rune, config *PromptConfig)

OnChange is called on every keypress.

func (*MultiSelect) Prompt

func (m *MultiSelect) Prompt(config *PromptConfig) (interface{}, error)

type MultiSelectTemplateData

type MultiSelectTemplateData struct {
	MultiSelect
	Answer        string
	ShowAnswer    bool
	Checked       map[int]bool
	SelectedIndex int
	ShowHelp      bool
	Description   func(value string, index int) string
	PageEntries   []core.OptionAnswer
	Config        *PromptConfig

	// These fields are used when rendering an individual option
	CurrentOpt   core.OptionAnswer
	CurrentIndex int
}

data available to the templates when processing

func (MultiSelectTemplateData) GetDescription

func (m MultiSelectTemplateData) GetDescription(opt core.OptionAnswer) string

func (MultiSelectTemplateData) IterateOption

func (m MultiSelectTemplateData) IterateOption(ix int, opt core.OptionAnswer) interface{}

IterateOption sets CurrentOpt and CurrentIndex appropriately so a multiselect option can be rendered individually

type MultiSelectTemplates

type MultiSelectTemplates struct {
	// Label is a text/template for the main command line label. Defaults to printing the label as it with
	// the IconInitial.
	Label string

	// Active is a text/template for when an item is currently active within the list.
	Active string

	// Inactive is a text/template for when an item is not currently active inside the list. This
	// template is used for all items unless they are active or selected.
	Inactive string

	// Selected is a text/template for when an item was successfully selected.
	Selected string

	// Details is a text/template for when an item current active to show
	// additional information. It can have multiple lines.
	//
	// Detail will always be displayed for the active element and thus can be used to display additional
	// information on the element beyond its label.
	//
	// promptui will not trim spaces and tabs will be displayed if the template is indented.
	Details string

	// Help is a text/template for displaying instructions at the top. By default
	// it shows keys for movement and search.
	Help string

	// FuncMap is a map of helper functions that can be used inside of templates according to the text/template
	// documentation.
	//
	// By default, FuncMap contains the color functions used to color the text in templates. If FuncMap
	// is overridden, the colors functions must be added in the override from promptui.FuncMap to work.
	FuncMap template.FuncMap
	// contains filtered or unexported fields
}

type Multiline

type Multiline struct {
	Renderer
	Message string
	Default string
	Help    string
}

func (*Multiline) Cleanup

func (i *Multiline) Cleanup(config *PromptConfig, val interface{}) error

func (*Multiline) Prompt

func (i *Multiline) Prompt(config *PromptConfig) (interface{}, error)

type MultilineTemplateData

type MultilineTemplateData struct {
	Multiline
	Answer     string
	ShowAnswer bool
	ShowHelp   bool
	Config     *PromptConfig
}

data available to the templates when processing

type OptionAnswer

type OptionAnswer = core.OptionAnswer

OptionAnswer is an ergonomic alias for core.OptionAnswer

type Password

type Password struct {
	Renderer
	Message string
	Help    string
}

Password is like a normal Input but the text shows up as *'s and there is no default. Response type is a string.

password := ""
prompt := &survey.Password{ Message: "Please type your password" }
survey.AskOne(prompt, &password)

func (*Password) Cleanup

func (prompt *Password) Cleanup(config *PromptConfig, val interface{}) error

Cleanup hides the string with a fixed number of characters.

func (*Password) Prompt

func (p *Password) Prompt(config *PromptConfig) (interface{}, error)

type PasswordTemplateData

type PasswordTemplateData struct {
	Password
	ShowHelp bool
	Config   *PromptConfig
}

type Prompt

type Prompt interface {
	Prompt(config *PromptConfig) (interface{}, error)
	Cleanup(*PromptConfig, interface{}) error
	Error(*PromptConfig, error) error
}

Prompt is the primary interface for the objects that can take user input and return a response.

type PromptAgainer

type PromptAgainer interface {
	PromptAgain(config *PromptConfig, invalid interface{}, err error) (interface{}, error)
}

PromptAgainer Interface for Prompts that support prompting again after invalid input

type PromptConfig

type PromptConfig struct {
	PageSize         int
	Icons            IconSet
	HelpInput        string
	SuggestInput     string
	Filter           func(filter string, option string, index int) bool
	KeepFilter       bool
	ShowCursor       bool
	RemoveSelectAll  bool
	RemoveSelectNone bool
	HideCharacter    rune
}

PromptConfig holds the global configuration for a prompt

type PromptTemplates

type PromptTemplates struct {
	// Prompt is a text/template for the prompt label displayed on the left side of the prompt.
	Prompt string

	// Prompt is a text/template for the prompt label when IsConfirm is set as true.
	Confirm string

	// Valid is a text/template for the prompt label when the value entered is valid.
	Valid string

	// Invalid is a text/template for the prompt label when the value entered is invalid.
	Invalid string

	// Success is a text/template for the prompt label when the user has pressed entered and the value has been
	// deemed valid by the validation function. The label will keep using this template even when the prompt ends
	// inside the console.
	Success string

	// Prompt is a text/template for the prompt label when the value is invalid due to an error triggered by
	// the prompt's validation function.
	ValidationError string

	// FuncMap is a map of helper functions that can be used inside of templates according to the text/template
	// documentation.
	//
	// By default, FuncMap contains the color functions used to color the text in templates. If FuncMap
	// is overridden, the colors functions must be added in the override from promptui.FuncMap to work.
	FuncMap template.FuncMap
	// contains filtered or unexported fields
}

type Question

type Question struct {
	Name      string
	Prompt    Prompt
	Validate  Validator
	Transform Transformer
	Templates *PromptTemplates
}

Question is the core data structure for a survey questionnaire.

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

func (*Renderer) AppendRenderedText

func (r *Renderer) AppendRenderedText(text string)

AppendRenderedText appends text to the renderer's text buffer which is used to track of what has been printed. The buffer is used to calculate how many lines to erase before updating the prompt.

func (*Renderer) Error

func (r *Renderer) Error(config *PromptConfig, invalid error) error

func (*Renderer) NewCursor

func (r *Renderer) NewCursor() *terminal.Cursor

func (*Renderer) NewRuneReader

func (r *Renderer) NewRuneReader() *terminal.RuneReader

func (*Renderer) OffsetCursor

func (r *Renderer) OffsetCursor(offset int)

func (*Renderer) Render

func (r *Renderer) Render(tmpl string, data interface{}, details string) error

func (*Renderer) RenderWithCursorOffset

func (r *Renderer) RenderWithCursorOffset(tmpl string, data IterableOpts, opts []core.OptionAnswer, idx int, details string) error

func (*Renderer) Stdio

func (r *Renderer) Stdio() terminal.Stdio

func (*Renderer) WithStdio

func (r *Renderer) WithStdio(stdio terminal.Stdio)

type Select

type Select struct {
	Renderer
	Message       string
	Options       []string
	Items         interface{}
	Default       interface{}
	Help          string
	PageSize      int
	VimMode       bool
	FilterMessage string
	Filter        func(filter string, value string, index int) bool
	Description   func(value string, index int) string

	Templates *SelectTemplates
	// contains filtered or unexported fields
}

Select is a prompt that presents a list of various options to the user for them to select using the arrow keys and enter. Response type is a string.

color := ""
prompt := &survey.Select{
	Message: "Choose a color:",
	Options: []string{"red", "blue", "green"},
}
survey.AskOne(prompt, &color)

func (*Select) Cleanup

func (s *Select) Cleanup(config *PromptConfig, val interface{}) error

func (*Select) OnChange

func (s *Select) OnChange(key rune, config *PromptConfig) bool

OnChange is called on every keypress.

func (*Select) Prompt

func (s *Select) Prompt(config *PromptConfig) (interface{}, error)

type SelectTemplateData

type SelectTemplateData struct {
	Select
	PageEntries   []core.OptionAnswer
	SelectedIndex int
	Answer        string
	ShowAnswer    bool
	ShowHelp      bool
	Description   func(value string, index int) string
	Config        *PromptConfig

	CurrentOpt   core.OptionAnswer
	CurrentIndex int
}

func (SelectTemplateData) GetDescription

func (s SelectTemplateData) GetDescription(opt core.OptionAnswer) string

func (SelectTemplateData) IterateOption

func (s SelectTemplateData) IterateOption(ix int, opt core.OptionAnswer) interface{}

IterateOption sets CurrentOpt and CurrentIndex appropriately so a select option can be rendered individually

type SelectTemplates

type SelectTemplates struct {
	Label   string
	Details string
	FuncMap template.FuncMap
	// contains filtered or unexported fields
}

type Transformer

type Transformer func(ans interface{}) (newAns interface{})

Transformer is a function passed to a Question after a user has provided a response. The function can be used to implement a custom logic that will result to return a different representation of the given answer.

Look `TransformString`, `ToLower` `Title` and `ComposeTransformers` for more.

func ComposeTransformers

func ComposeTransformers(transformers ...Transformer) Transformer

ComposeTransformers is a variadic function used to create one transformer from many.

func TransformString

func TransformString(f func(s string) string) Transformer

TransformString returns a `Transformer` based on the "f" function which accepts a string representation of the answer and returns a new one, transformed, answer. Take for example the functions inside the std `strings` package, they can be converted to a compatible `Transformer` by using this function, i.e: `TransformString(strings.Title)`, `TransformString(strings.ToUpper)`.

Note that `TransformString` is just a helper, `Transformer` can be used to transform any type of answer.

type Validator

type Validator func(ans interface{}) error

Validator is a function passed to a Question after a user has provided a response. If the function returns an error, then the user will be prompted again for another response.

func ComposeValidators

func ComposeValidators(validators ...Validator) Validator

ComposeValidators is a variadic function used to create one validator from many.

func MaxItems

func MaxItems(numberItems int) Validator

MaxItems requires that the list is no longer than the specified value

func MaxLength

func MaxLength(length int) Validator

MaxLength requires that the string is no longer than the specified value

func MinItems

func MinItems(numberItems int) Validator

MinItems requires that the list is longer or equal in length to the specified value

func MinLength

func MinLength(length int) Validator

MinLength requires that the string is longer or equal in length to the specified value

Directories

Path Synopsis
tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL