prompt

package module
v0.0.0-...-d343df3 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2025 License: MIT Imports: 18 Imported by: 1

README

Command line prompter

Command line prompter for terminal user interaction with the following features:

  • input prompt scans into any variable type (string, bool, int, time.Time, ..., or custom types)
  • input is editable in-place
  • select prompt with options
  • enter and yes/no prompt
  • input validation

See also github.com/tdewolff/argp for a command line argument parser.

TODO: capture terminal resize event TODO: handle long labels for prompt/select

Installation

Make sure you have Git and Go (1.13 or higher) installed, run

mkdir Project
cd Project
go mod init
go get -u github.com/tdewolff/prompt

Then add the following import

import (
    "github.com/tdewolff/prompt"
)

Examples

Input prompt

A regular prompt requesting user input. When the target is a primary type (except boolean) or implements the Stringer interface, it will be editable in-place.

package main

import "github.com/tdewolff/prompt"

func main() {
    // Validators verify the user input to match conditions.
    validators := []prompt.Validator{prompt.StrLength(5, 10), prompt.Suffix("suffix")}

    var val string
    deflt := prompt.Default("value", 3)  // set text caret to the 3rd character
    if err := prompt.Prompt(&val, "Label", deflt, validators...); err != nil {
        panic(err)
    }
    fmt.Println("Result:", val)
}

where val can be of any primary type, such as string, []byte, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, or time.Time.

When the value is editable it allowd users to use keys such as: Left, Ctrl + B to move left; Right, Ctrl + F to move right; Home, Ctrl + A to go to start; End, Ctrl + E to go to end; Backspace and Delete to delete a character; Ctrl + K and Ctrl + U to delete from the caret to the start and end of the input respectively; Enter, Ctrl + D to confirm input; and Ctrl + C, Esc to quit.

Select prompt

A list selection prompt that allows the user to select amongst predetermined options.

package main

import "github.com/tdewolff/prompt"

func main() {
    val, deflt := "", "Yellow"  // can be ints if you need the index into options
    options := []string{"Red", "Orange", "Green", "Yellow", "Blue", "Purple"}
    if err := prompt.Select(&val, "Label", options, deflt); err != nil {
        panic(err)
    }
    fmt.Println("Selected:", val)
}

The select prompt allows users to use keys such as: Up, Shift + Tab to go up; Down, Tab to go down; Enter, Ctrl + D to select option; Ctrl + C to quit; and Esc to cancel the selection.

When there are many options, it is possible to enter a query to filter options.

Yes/No prompt

A yes or no prompt returning true or false.

package main

import "github.com/tdewolff/prompt"

func main() {
    deflt := false
    if prompt.YesNo("Label", deflt) {
        fmt.Println("Yes")
    } else {
        fmt.Println("No")
    }
}

true is any of 1, y, yes, t, true and is case-insensitive.

false is any of 0, n, no, f, false and is case-insensitive.

Enter prompt

A prompt that waits for Enter to be pressed.

package main

import "github.com/tdewolff/prompt"

func main() {
    prompt.Enter("Are you done?")  // waits for enter
}
Validators
Not(Validator)     // logical NOT
And(Validator...)  // logical AND
Or(Validator...)   // logical OR

Is(any)       // is exact match
In([]any)     // in list
NotIn([]any)  // not in list

StrLength(min, max int)           // limit string length (inclusive)
NumRange(min, max float64)        // limit int/uint/float range (inclusive)
DateRange(min, max time.Time)     // limit time.Time range (inclusive)
Prefix(afix string)
Suffix(afix string)
Pattern(pattern, message string)  // pattern match and error message
EmailAddress()
IPAddress()                       // valid IPv4 or IPv6 address
IPv4Address()
IPv6Address()
Port()                            // server port
Path()                            // Unix path
AbsolutePath()                    // Unix absolute path
UserName()                        // valid Unix user name
TopDomainName()                   // such as example.com
DomainName()                      // such as sub.example.com
FQDN()                            // such as sub.example.com.
Dir()                             // existing directory
File()                            // existing file

License

Released under the MIT license.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Checklist

func Checklist(idst interface{}, label string, ioptions interface{}) error

func Clip

func Clip(x, a, b int) int

func Default

func Default(idst, ideflt interface{}) defaultValue

Default is the default value used for Prompt.

func DefaultProgressStyle

func DefaultProgressStyle(b []byte, f float64)

func DefaultWithCaret

func DefaultWithCaret(idst, ideflt interface{}, pos int) defaultValue

Default is the default value with the initial text caret position used for Prompt. A position of -1 means at the end of the value.

func Enter

func Enter(label string)

Enter is a prompt that requires the Enter key to continue.

func MakeRawTerminal

func MakeRawTerminal(hide bool) (func() error, error)

func Max

func Max(a, b int) int

func Min

func Min(a, b int) int

func NonZeroDefault

func NonZeroDefault(idst, ideflt interface{}) defaultValue

NonZeroDefault is the default value used for Prompt. The default value will be empty when the destination is its zero value.

func Prompt

func Prompt(idst interface{}, label string, validators ...Validator) error

Prompt is a regular text prompt that can read into a (string,[]byte,bool,int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64,float32,float64,time.Time) or a type that implements the Scanner interface. The idst must be a pointer to a variable, its value determines the default/initial value. The initial value will be editable in-place. To set the text caret initial position when idst is editable, use prompt.Default(value, position). When editing, you can use the Left or Ctrl+B, Right or Ctrl+F, Home or Ctrl+A, End or Ctrl+E to move around; Backspace and Delete to delete a character; Ctrl+U and Ctrl+K to delete from the caret to the beginning and the end of the line respectively; Ctrl+C and Escape to quit; and Ctrl+Z and Enter to confirm the input. All validators must be satisfies, otherwise an error is printed and the answer should be corrected.

func Select

func Select(idst interface{}, label string, ioptions interface{}) error

Select is a list selection prompt that allows to select one of the list of possible values. The ioptions must be a slice of options. The idst must be a pointer to a variable and must of the same type as the options (set the option value) or an integer (set the option index). The value od idst determines the initial selected value. Users can select an option using Up, Ctrl+P, 'k', or Shift+Tab to move up, Down, Ctrl+N, 'j', or Tab to move down. Both wraps around. Ctrl+C or Escape to quit, and Ctrl+Z, Enter, or Ctrl+D to select an option.

func TerminalSize

func TerminalSize() (int, int, error)

func YesNo

func YesNo(label string, deflt bool) bool

YesNo is a prompt that requires a yes or no answer. It returns true for any of (1,y,yes,t,true), and false for any of (0,n,no,f,false). It is case-insensitive.

Types

type DownloadProgress

type DownloadProgress struct {
	Progress
	// contains filtered or unexported fields
}

func NewDownloadProgress

func NewDownloadProgress(prefix string, resp *http.Response, style ProgressStyle) *DownloadProgress

func (*DownloadProgress) Add

func (p *DownloadProgress) Add(value int64)

func (*DownloadProgress) Close

func (p *DownloadProgress) Close() error

func (*DownloadProgress) Read

func (p *DownloadProgress) Read(b []byte) (int, error)

func (*DownloadProgress) Set

func (p *DownloadProgress) Set(value int64)

type Form

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

func NewForm

func NewForm() *Form

func (*Form) Print

func (f *Form) Print(label string, ival interface{})

func (*Form) Prompt

func (f *Form) Prompt(idst interface{}, label string, validators ...Validator)

func (*Form) Select

func (f *Form) Select(idst interface{}, label string, ioptions interface{})

func (*Form) Send

func (f *Form) Send() error

type MultiDownloadProgress

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

func NewMultiDownloadProgress

func NewMultiDownloadProgress(style ProgressStyle) *MultiDownloadProgress

func (*MultiDownloadProgress) Add

func (p *MultiDownloadProgress) Add(prefix string, resp *http.Response) io.ReadCloser

func (*MultiDownloadProgress) Stop

func (p *MultiDownloadProgress) Stop()

type MultiDownloadProgressItem

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

func (*MultiDownloadProgressItem) Close

func (p *MultiDownloadProgressItem) Close() error

func (*MultiDownloadProgressItem) Read

func (p *MultiDownloadProgressItem) Read(b []byte) (int, error)

type Number

type Number interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64
}

type PercentProgress

type PercentProgress[T Number] struct {
	Progress
	// contains filtered or unexported fields
}

func NewPercentProgress

func NewPercentProgress[T Number](prefix string, maximum T, style ProgressStyle) *PercentProgress[T]

func (*PercentProgress[T]) Add

func (p *PercentProgress[T]) Add(value T)

func (*PercentProgress[T]) Set

func (p *PercentProgress[T]) Set(value T)

type Progress

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

func NewProgress

func NewProgress(prefix, suffix string, style ProgressStyle) *Progress

func (*Progress) Print

func (p *Progress) Print(f float64)

func (*Progress) Start

func (p *Progress) Start()

func (*Progress) Stop

func (p *Progress) Stop()

type ProgressStyle

type ProgressStyle func([]byte, float64)

type Validator

type Validator func(any) error

Validator is a validator interface.

func AbsolutePath

func AbsolutePath() Validator

AbsolutePath matches an absolute file path.

func After

func After(after any) Validator

After matches if the input is after the given number of date.

func And

func And(validators ...Validator) Validator

And evaluates multiple validators using the logical AND operator, i.e. must satisfy all validators. This is only useful inside logical OR validators.

func Before

func Before(before any) Validator

Before matches if the input is before the given number of date.

func DateRange

func DateRange(min, max time.Time) Validator

DateRange matches if the input is in the given time range (inclusive). Use time.Time's zero value for an open limit.

func Dir

func Dir() Validator

Dir matches a path to an existing directory on the system.

func DomainName

func DomainName() Validator

DomainName matches a domain name.

func EmailAddress

func EmailAddress() Validator

EmailAddress matches a valid e-mail address.

func FQDN

func FQDN() Validator

FQDN matches a fully qualified domain name.

func File

func File() Validator

File matches a path to an existing file on the system.

func IPAddress

func IPAddress() Validator

IPAddress matches an IPv4 or IPv6 address.

func IPv4Address

func IPv4Address() Validator

IPv4Address matches an IPv4 address.

func IPv6Address

func IPv6Address() Validator

IPv6Address matches an IPv6 address.

func In

func In(list any) Validator

In matches if the input matches any element of the list.

func Is

func Is(elem any) Validator

Is matches if the input matches the given value.

func Not

func Not(validator Validator) Validator

Not evaluates the validator using the logical NOT operator, i.e. satisfies if the validator does not satisfy.

func NotIn

func NotIn(list any) Validator

NotIn matches if the input does not match any element of the list.

func NumRange

func NumRange(min, max float64) Validator

NumRange matches if the input is in the given number range (inclusive). Use NaN or +/-Inf for an open limit.

func Or

func Or(validators ...Validator) Validator

Or evaluates multiple validators using the logical OR operator, i.e. at least one validator must be satisfied.

func Path

func Path() Validator

Path matches any file path.

func Pattern

func Pattern(pattern, message string) Validator

Pattern matches the given pattern.

func Port

func Port() Validator

Port matches a valid port number.

func Prefix

func Prefix(afix string) Validator

Prefix matches if the input has the given prefix.

func StrLength

func StrLength(min, max int) Validator

StrLength matches if the input length is in the given range (inclusive). Use -1 for an open limit.

func Suffix

func Suffix(afix string) Validator

Suffix matches if the input has the given suffix.

func TelephoneNumber

func TelephoneNumber() Validator

TelephoneNumber matches a valid telephone number.

func TopDomainName

func TopDomainName() Validator

TopDomainName matches a top-level domain name.

func UserName

func UserName() Validator

UserName matches a valid Unix user name.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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