promptui

package module
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jul 26, 2018 License: BSD-3-Clause Imports: 12 Imported by: 0

README

promptui

Interactive prompt for command-line applications.

We built Promptui because we wanted to make it easy and fun to explore cloud services with manifold cli.

Code of Conduct | Contribution Guidelines

GitHub release GoDoc Travis Go Report Card License

Overview

promptui

Promptui is a library providing a simple interface to create command-line prompts for go. It can be easily integrated into spf13/cobra, urfave/cli or any cli go application.

Promptui has two main input modes:

  • Prompt provides a single line for user input. Prompt supports optional live validation, confirmation and masking the input.

  • Select provides a list of options to choose from. Select supports pagination, search, detailed view and custom templates.

For a full list of options check GoDoc.

Basic Usage

Prompt
package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/manifoldco/promptui"
)

func main() {
	validate := func(input string) error {
		_, err := strconv.ParseFloat(input, 64)
		if err != nil {
			return errors.New("Invalid number")
		}
		return nil
	}

	prompt := promptui.Prompt{
		Label:    "Number",
		Validate: validate,
	}

	result, err := prompt.Run()

	if err != nil {
		fmt.Printf("Prompt failed %v\n", err)
		return
	}

	fmt.Printf("You choose %q\n", result)
}
Select
package main

import (
	"fmt"

	"github.com/manifoldco/promptui"
)

func main() {
	prompt := promptui.Select{
		Label: "Select Day",
		Items: []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
			"Saturday", "Sunday"},
	}

	_, result, err := prompt.Run()

	if err != nil {
		fmt.Printf("Prompt failed %v\n", err)
		return
	}

	fmt.Printf("You choose %q\n", result)
}
More Examples

See full list of examples

Documentation

Overview

Package promptui is a library providing a simple interface to create command-line prompts for go. It can be easily integrated into spf13/cobra, urfave/cli or any cli go application.

promptui has two main input modes:

Prompt provides a single line for user input. It supports optional live validation, confirmation and masking the input.

Select provides a list of options to choose from. It supports pagination, search, detailed view and custom templates.

Example (Prompt)

This is an example for the Prompt mode of promptui. In this example, a prompt is created with a validator function that validates the given value to make sure its a number. If successful, it will output the chosen number in a formatted message.

validate := func(input string) error {
	_, err := strconv.ParseFloat(input, 64)
	if err != nil {
		return errors.New("Invalid number")
	}
	return nil
}

prompt := Prompt{
	Label:    "Number",
	Validate: validate,
}

result, err := prompt.Run()

if err != nil {
	fmt.Printf("Prompt failed %v\n", err)
	return
}

fmt.Printf("You choose %q\n", result)
Output:

Example (Select)

This is an example for the Select mode of promptui. In this example, a select is created with the days of the week as its items. When an item is selected, the selected day will be displayed in a formatted message.

prompt := Select{
	Label: "Select Day",
	Items: []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
		"Saturday", "Sunday"},
}

_, result, err := prompt.Run()

if err != nil {
	fmt.Printf("Prompt failed %v\n", err)
	return
}

fmt.Printf("You choose %q\n", result)
Output:

Index

Examples

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.

View Source
const SelectedAdd = -1

SelectedAdd is used internally inside SelectWithAdd when the add option is selected in select mode. Since -1 is not a possible selected index, this ensure that add mode is always unique inside SelectWithAdd's logic.

Variables

View Source
var (
	// KeyEnter is the default key for submission/selection.
	KeyEnter rune = readline.CharEnter

	// KeyBackspace is the default key for deleting input text.
	KeyBackspace rune = readline.CharBackspace

	// KeyPrev is the default key to go up during selection.
	KeyPrev        rune = readline.CharPrev
	KeyPrevDisplay      = "↑"

	// KeyNext is the default key to go down during selection.
	KeyNext        rune = readline.CharNext
	KeyNextDisplay      = "↓"

	// KeyBackward is the default key to page up during selection.
	KeyBackward        rune = readline.CharBackward
	KeyBackwardDisplay      = "←"

	// KeyForward is the default key to page down during selection.
	KeyForward        rune = readline.CharForward
	KeyForwardDisplay      = "→"
)

These runes are used to identity the commands entered by the user in the command prompt. They map to specific actions of promptui in prompt mode and can be remapped if necessary.

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 ErrAbort = errors.New("")

ErrAbort is the error returned when confirm prompts are supplied "n"

View Source
var ErrEOF = errors.New("^D")

ErrEOF is the error returned from prompts when EOF is encountered.

View Source
var ErrInterrupt = errors.New("^C")

ErrInterrupt is the error returned from prompts when an interrupt (ctrl-c) is encountered.

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 ResetCode = fmt.Sprintf("%s%dm", esc, reset)

ResetCode is the character code used to reset the terminal formatting

Functions

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.

Types

type Key added in v0.2.0

type Key struct {
	// Code is a rune that will be used to compare against typed keys with readline.
	// Check https://github.com/chzyer/readline for a list of codes
	Code rune

	// Display is the string that will be displayed inside the help menu to help inform the user
	// of which key to use on his keyboard for various functions.
	Display string
}

Key defines a keyboard code and a display representation for the help menu.

type Prompt

type Prompt struct {
	// Label is the value displayed on the command line prompt.
	//
	// The value for Label can be a simple string or a struct that will need to be accessed by dot notation
	// inside the templates. For example, `{{ .Name }}` will display the name property of a struct.
	Label interface{}

	// Default is the initial value for the prompt. This value will be displayed next to the prompt's label
	// and the user will be able to view or change it depending on the options.
	Default string

	// AllowEdit lets the user edit the default value. If false, any key press
	// other than <Enter> automatically clears the default value.
	AllowEdit bool

	// Validate is an optional function that fill be used against the entered value in the prompt to validate it.
	Validate ValidateFunc

	// Mask is an optional rune that sets which character to display instead of the entered characters. This
	// allows hiding private information like passwords.
	Mask rune

	// Templates can be used to customize the prompt output. If nil is passed, the
	// default templates are used. See the PromptTemplates docs for more info.
	Templates *PromptTemplates

	// IsConfirm makes the prompt ask for a yes or no ([Y/N]) question rather than request an input. When set,
	// most properties related to input will be ignored.
	IsConfirm bool

	// IsVimMode enables vi-like movements (hjkl) and editing.
	IsVimMode bool
	// contains filtered or unexported fields
}

Prompt represents a single line text field input with options for validation and input masks.

Example

This example shows how to use the prompt validator and templates to create a stylized prompt. The validator will make sure the value entered is a parseable float while the templates will color the value to show validity.

// The validate function follows the required validator signature.
validate := func(input string) error {
	_, err := strconv.ParseFloat(input, 64)
	return err
}

// Each template displays the data received from the prompt with some formatting.
templates := &PromptTemplates{
	Prompt:  "{{ . }} ",
	Valid:   "{{ . | green }} ",
	Invalid: "{{ . | red }} ",
	Success: "{{ . | bold }} ",
}

prompt := Prompt{
	Label:     "Spicy Level",
	Templates: templates,
	Validate:  validate,
}

result, err := prompt.Run()

if err != nil {
	fmt.Printf("Prompt failed %v\n", err)
	return
}

// The result of the prompt, if valid, is displayed in a formatted message.
fmt.Printf("You answered %s\n", result)
Output:

func (*Prompt) Run

func (p *Prompt) Run() (string, error)

Run executes the prompt. Its displays the label and default value if any, asking the user to enter a value. Run will keep the prompt alive until it has been canceled from the command prompt or it has received a valid value. It will return the value and an error if any occurred during the prompt's execution.

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 dur to an error triggered from
	// 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
}

PromptTemplates allow a prompt to be customized following stdlib text/template syntax. Custom state, colors and background color are available for use inside the templates and are documented inside the Variable section of the docs.

Examples

text/templates use a special notation to display programmable content. Using the double bracket notation, the value can be printed with specific helper functions. For example

This displays the value given to the template as pure, unstylized text.

'{{ . }}'

This displays the value colored in cyan

'{{ . | cyan }}'

This displays the value colored in red with a cyan background-color

'{{ . | red | cyan }}'

See the doc of text/template for more info: https://golang.org/pkg/text/template/

type Select

type Select struct {
	// Label is the text displayed on top of the list to direct input. The IconInitial value "?" will be
	// appended automatically to the label so it does not need to be added.
	//
	// The value for Label can be a simple string or a struct that will need to be accessed by dot notation
	// inside the templates. For example, `{{ .Name }}` will display the name property of a struct.
	Label interface{}

	// Items are the items to display inside the list. It expect a slice of any kind of values, including strings.
	//
	// If using a slice a strings, promptui will use those strings directly into its base templates or the
	// provided templates. If using any other type in the slice, it will attempt to transform it into a string
	// before giving it to its templates. Custom templates will override this behavior if using the dot notation
	// inside the templates.
	//
	// For example, `{{ .Name }}` will display the name property of a struct.
	Items interface{}

	// Size is the number of items that should appear on the select before scrolling is necessary. Defaults to 5.
	Size int

	// IsVimMode sets whether to use vim mode when using readline in the command prompt. Look at
	// https://godoc.org/github.com/chzyer/readline#Config for more information on readline.
	IsVimMode bool

	// Templates can be used to customize the select output. If nil is passed, the
	// default templates are used. See the SelectTemplates docs for more info.
	Templates *SelectTemplates

	// Keys is the set of keys used in select mode to control the command line interface. See the SelectKeys docs for
	// more info.
	Keys *SelectKeys

	// Searcher is a function that can be implemented to refine the base searching algorithm in selects.
	//
	// Search is a function that will receive the searched term and the item's index and should return a boolean
	// for whether or not the terms are alike. It is unimplemented by default and search will not work unless
	// it is implemented.
	Searcher list.Searcher

	// StartInSearchMode sets whether or not the select mdoe should start in search mode or selection mode.
	// For search mode to work, the Search property must be implemented.
	StartInSearchMode bool
	// contains filtered or unexported fields
}

Select represents a list of items used to enable selections, they can be used as search engines, menus or as a list of items in a cli based prompt.

Example

This examples shows a complex and customized select.

package main

import (
	"fmt"
	"strings"
)

// Any type can be given to the select's item as long as the templates properly implement the dot notation
// to display it.
type pepper struct {
	Name     string
	HeatUnit int
	Peppers  int
}

// This examples shows a complex and customized select.
func main() {
	// The select will show a series of peppers stored inside a slice of structs. To display the content of the struct,
	// the usual dot notation is used inside the templates to select the fields and color them.
	peppers := []pepper{
		{Name: "Bell Pepper", HeatUnit: 0, Peppers: 0},
		{Name: "Banana Pepper", HeatUnit: 100, Peppers: 1},
		{Name: "Poblano", HeatUnit: 1000, Peppers: 2},
		{Name: "Jalapeño", HeatUnit: 3500, Peppers: 3},
		{Name: "Aleppo", HeatUnit: 10000, Peppers: 4},
		{Name: "Tabasco", HeatUnit: 30000, Peppers: 5},
		{Name: "Malagueta", HeatUnit: 50000, Peppers: 6},
		{Name: "Habanero", HeatUnit: 100000, Peppers: 7},
		{Name: "Red Savina Habanero", HeatUnit: 350000, Peppers: 8},
		{Name: "Dragon’s Breath", HeatUnit: 855000, Peppers: 9},
	}

	// The Active and Selected templates set a small pepper icon next to the name colored and the heat unit for the
	// active template. The details template is show at the bottom of the select's list and displays the full info
	// for that pepper in a multi-line template.
	templates := &SelectTemplates{
		Label:    "{{ . }}?",
		Active:   "\U0001F336 {{ .Name | cyan }} ({{ .HeatUnit | red }})",
		Inactive: "  {{ .Name | cyan }} ({{ .HeatUnit | red }})",
		Selected: "\U0001F336 {{ .Name | red | cyan }}",
		Details: `
--------- Pepper ----------
{{ "Name:" | faint }}	{{ .Name }}
{{ "Heat Unit:" | faint }}	{{ .HeatUnit }}
{{ "Peppers:" | faint }}	{{ .Peppers }}`,
	}

	// A searcher function is implemented which enabled the search mode for the select. The function follows
	// the required searcher signature and finds any pepper whose name contains the searched string.
	searcher := func(input string, index int) bool {
		pepper := peppers[index]
		name := strings.Replace(strings.ToLower(pepper.Name), " ", "", -1)
		input = strings.Replace(strings.ToLower(input), " ", "", -1)

		return strings.Contains(name, input)
	}

	prompt := Select{
		Label:     "Spicy Level",
		Items:     peppers,
		Templates: templates,
		Size:      4,
		Searcher:  searcher,
	}

	i, _, err := prompt.Run()

	if err != nil {
		fmt.Printf("Prompt failed %v\n", err)
		return
	}

	// The selected pepper will be displayed with its name and index in a formatted message.
	fmt.Printf("You choose number %d: %s\n", i+1, peppers[i].Name)
}
Output:

func (*Select) Run

func (s *Select) Run() (int, string, error)

Run executes the select list. Its displays the label and the list of items, asking the user to chose any value within to list. Run will keep the prompt alive until it has been canceled from the command prompt or it has received a valid value. It will return the value and an error if any occurred during the select's execution.

type SelectKeys added in v0.2.0

type SelectKeys struct {
	// Next is the key used to move to the next element inside the list. Defaults to down arrow key.
	Next Key

	// Prev is the key used to move to the previous element inside the list. Defaults to up arrow key.
	Prev Key

	// PageUp is the key used to jump back to the first element inside the list. Defaults to left arrow key.
	PageUp Key

	// PageUp is the key used to jump forward to the last element inside the list. Defaults to right arrow key.
	PageDown Key

	// Search is the key used to trigger the search mode for the list. Default to the "/" key.
	Search Key
}

SelectKeys defines the available keys used by select mode to enable the user to move around the list and trigger search mode. See the Key struct docs for more information on keys.

type SelectTemplates

type SelectTemplates 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
}

SelectTemplates allow a select list to be customized following stdlib text/template syntax. Custom state, colors and background color are available for use inside the templates and are documented inside the Variable section of the docs.

Examples

text/templates use a special notation to display programmable content. Using the double bracket notation, the value can be printed with specific helper functions. For example

This displays the value given to the template as pure, unstylized text. Structs are transformed to string with this notation.

'{{ . }}'

This displays the name property of the value colored in cyan

'{{ .Name | cyan }}'

This displays the label property of value colored in red with a cyan background-color

'{{ .Label | red | cyan }}'

See the doc of text/template for more info: https://golang.org/pkg/text/template/

Notes

Setting any of these templates will remove the icons from the default templates. They must be added back in each of their specific templates. The styles.go constants contains the default icons.

type SelectWithAdd

type SelectWithAdd struct {
	// Label is the text displayed on top of the list to direct input. The IconInitial value "?" will be
	// appended automatically to the label so it does not need to be added.
	Label string

	// Items are the items to display inside the list. Each item will be listed individually with the
	// AddLabel as the first item of the list.
	Items []string

	// AddLabel is the label used for the first item of the list that enables adding a new item.
	// Selecting this item in the list displays the add item prompt using promptui/prompt.
	AddLabel string

	// Validate is an optional function that fill be used against the entered value in the prompt to validate it.
	// If the value is valid, it is returned to the callee to be added in the list.
	Validate ValidateFunc

	// IsVimMode sets whether to use vim mode when using readline in the command prompt. Look at
	// https://godoc.org/github.com/chzyer/readline#Config for more information on readline.
	IsVimMode bool
}

SelectWithAdd represents a list for selecting a single item inside a list of items with the possibility to add new items to the list.

Example

This example shows how to create a SelectWithAdd that will add each new item it is given to the list of items until one is chosen.

items := []string{"Vim", "Emacs", "Sublime", "VSCode", "Atom"}
index := -1
var result string
var err error

for index < 0 {
	prompt := SelectWithAdd{
		Label:    "What's your text editor",
		Items:    items,
		AddLabel: "Add your own",
	}

	index, result, err = prompt.Run()

	if index == -1 {
		items = append(items, result)
	}
}

if err != nil {
	fmt.Printf("Prompt failed %v\n", err)
	return
}

fmt.Printf("You choose %s\n", result)
Output:

func (*SelectWithAdd) Run

func (sa *SelectWithAdd) Run() (int, string, error)

Run executes the select list. Its displays the label and the list of items, asking the user to chose any value within to list or add his own. Run will keep the prompt alive until it has been canceled from the command prompt or it has received a valid value.

If the addLabel is selected in the list, this function will return a -1 index with the added label and no error. Otherwise, it will return the index and the value of the selected item. In any case, if an error is triggered, it will also return the error as its third return value.

type ValidateFunc

type ValidateFunc func(string) error

ValidateFunc is a placeholder type for any validation functions that validates a given input. It should return a ValidationError if the input is not valid.

Directories

Path Synopsis
_examples

Jump to

Keyboard shortcuts

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