clt

package module
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2020 License: MIT Imports: 13 Imported by: 2

README

CLT - Command Line Tools for Go

CLT is a toolset for building elegant command line interfaces in Go. CLT includes elements like styled text, tables, selections from a list, and more so that you can quickly build CLIs with interactive elements without the hassle of dealing with formatting all these yourself.

Go Doc documentation is available at [Godoc] and examples are located in the examples directory. This readme strives to show you the major features.

Styled Text

package main

import (
	"fmt"
	"github.com/BTBurke/clt"
)

func main() {
	fmt.Printf("This is %s text\n", clt.Styled(clt.Red).ApplyTo("red"))
	fmt.Printf("This is %s text\n", clt.SStyled("blue and underlined", clt.Blue, clt.Underline))
	fmt.Printf("This is %s text\n", clt.SStyled("blue on a white background", clt.Blue, clt.Background(clt.White))
	fmt.Printf("This is %s text\n", clt.Styled(clt.Italic).ApplyTo("italic"))
	fmt.Printf("This is %s text\n", clt.SStyled("bold", clt.Bold)
}

console output

The general operation of the style function is to first call clt.Styled(<Style1>, <Style2>, ...). This creates a style that can then be applied to a string via the .ApplyTo(<string>) method. A shortcut method clt.SStyled("string", styles...) can help eliminate some of the boilerplate.

Tables

CLT provides an easy-to-use library for building text tables. It provides layout algorithms for multi-column tables and the ability to style each column or individual cells using clt.Styled.

Tables detect the terminal width and intelligently decide how cell contents should be wrapped to fit on screen.

package main

import "github.com/BTBurke/clt"

func main() {

	// Create a table with 3 columns
	t := clt.NewTable(5)

	// Add a title
	t.Title("Hockey Standings")

	// Set column headers
	t.ColumnHeaders("Team", "Points", "W", "L", "OT")

	// Add some rows
	t.AddRow("Washington Capitals", "42", "18", "11", "6")
	t.AddRow("NJ Devils", "31", "12", "18", "7")

	// Render the table
	t.Show()
}

Produces:

console output

More examples

See examples/table_example.go for more examples. Also, see the GoDoc for the details of the table library.

Progress Bars

CLT provides four kinds of progress indicators:

  • Spinner - Useful for when you want to show progress but don't know exactly when an action will complete

  • Bar - Useful when you have a defined number of iterations to completion and you can update progress during processing

  • Incremental - Userful when you have multiple go routines doing some work and you want to update total progress without each go routine having to synchronize state

  • Loading - Useful for when you are making a remote call and you want to give a visual indication that something is going on in the background, but you want it to disappear as soon as the call ends. It also has a configurable delay so that the loading indicator will only appear when the call takes longer than the delay to complete.

Example:

See examples/progress_example.go for the example in the screencast below.

console output

Progress bars use go routines to update the progress status while your app does other processing. Remember to close out the progress element with either a call to Success() or Fail() to terminate this routine.

Interactive Sessions

CLT provides building blocks to create interactive sessions, giving you flexible functions to ask the user for input.

See examples/interactive_example.go for examples of creating interactive interfaces.

Interactions
Interaction Use
Ask Ask for a response with optional validation
AskWithDefault Ask with a preconfigured default value
AskWithHint Ask with a hint that shows how the input should be formatted
AskPassword Ask for a password without any echo to the terminal while the user types
AskYesNo Ask a yes or no question with a default to either
AskFromTable User picks an option from a table of possibilities
Pause Paginate some output with Press [Enter] to continue.
PauseWithPrompt Paginate some output with a custom prompt to continue
Warn Issue a warning that is visually separated from other text by style changes
Error Show an error message and exit the process
Say Thin wrapper around fmt.Printf that helps build interactive sessions in a fluent style and take care of common spacing issues

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Colors
	Black   = Color{30, 39}
	Red     = Color{31, 39}
	Green   = Color{32, 39}
	Yellow  = Color{33, 39}
	Blue    = Color{34, 39}
	Magenta = Color{35, 39}
	Cyan    = Color{36, 39}
	White   = Color{37, 39}
	Default = Color{39, 39}

	// Shortcut Colors
	K   = Color{30, 39}
	R   = Color{31, 39}
	G   = Color{32, 39}
	Y   = Color{33, 39}
	B   = Color{34, 39}
	M   = Color{35, 39}
	C   = Color{36, 39}
	W   = Color{37, 39}
	Def = Color{39, 39}

	// Textstyles
	Bold      = Textstyle{1, 22}
	Italic    = Textstyle{3, 23}
	Underline = Textstyle{4, 24}
)

Functions

func IsNo

func IsNo(s string) bool

IsNo returns true if the response is some form of no or n

func IsYes

func IsYes(s string) bool

IsYes returns true if the response is some form of yes or y

func SStyled

func SStyled(content string, s ...Styler) string

SStyled is a shorter version of Styled(s...).ApplyTo(content)

Types

type Cell

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

Cell represents a cell in the table. Most often you'll create a cell using StyledCell in conjuction with AddStyledRow

func StyledCell

func StyledCell(v string, sty *Style) Cell

StyledCell returns a new cell with a custom style for use with AddStyledRow

type Col

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

Col is a column of a table. Use ColumnHeaders, ColumnStyles, etc. to adjust default styling and header properties. You can always override a particular cell in a column by passing in a different Cell style when you AddStyledRow.

type Color

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

Color represents a ANSI-coded color style for text

func Background

func Background(c Color) Color

Background returns a style that sets the background to the appropriate color

func (Color) Codes

func (c Color) Codes() (int, int)

Codes returns ANSI styling values for a color

type InteractiveSession

type InteractiveSession struct {
	Prompt  string
	Default string
	ValHint string
	// contains filtered or unexported fields
}

InteractiveSession creates a system for collecting user input in response to questions and choices

func NewInteractiveSession

func NewInteractiveSession(opts ...SessionOption) *InteractiveSession

NewInteractiveSession returns a new InteractiveSession outputting to Stdout and reading from Stdin by default, but other inputs and outputs may be specified with SessionOptions

func (*InteractiveSession) Ask

func (i *InteractiveSession) Ask(prompt string, validators ...ValidationFunc) string

Ask is a terminator for an interactive session that results in returning the user's input. Validators can optionally be applied to ensure that acceptable input is returned or the question will be asked again.

func (*InteractiveSession) AskFromTable

func (i *InteractiveSession) AskFromTable(prompt string, choices map[string]string, def string) string

AskFromTable creates a table to select choices from. It has a built-in validation function that will ensure that only the options listed are valid choices.

func (*InteractiveSession) AskPassword

func (i *InteractiveSession) AskPassword(validators ...ValidationFunc) string

AskPassword is a terminator that asks for a password and does not echo input to the terminal.

func (*InteractiveSession) AskPasswordPrompt added in v1.1.0

func (i *InteractiveSession) AskPasswordPrompt(prompt string, validators ...ValidationFunc) string

AskPasswordPrompt is a terminator that asks for a password with a custom prompt

func (*InteractiveSession) AskWithDefault

func (i *InteractiveSession) AskWithDefault(prompt string, defaultChoice string, validators ...ValidationFunc) string

AskWithDefault is like ask, but sets a default choice that the user can select by pressing enter.

func (*InteractiveSession) AskWithHint

func (i *InteractiveSession) AskWithHint(prompt string, hint string, validators ...ValidationFunc) string

AskWithHint is like ask, but gives a hint about the proper format of the response. This is useful combined with a validation function to get input in the right format.

func (*InteractiveSession) AskYesNo

func (i *InteractiveSession) AskYesNo(prompt string, defaultChoice string) string

AskYesNo asks the user a yes or no question with a default value. Defaults of `y` or `yes` will set the default to yes. Anything else will default to no. You can use IsYes or IsNo to act on the response without worrying about what version of y, Y, YES, yes, etc. that the user entered.

func (*InteractiveSession) Error

func (i *InteractiveSession) Error(format string, args ...interface{})

Error is a terminator that gives an informational error message to the user in format Error: <user defined string>. Exits the program returning status code 1

func (*InteractiveSession) Pause

func (i *InteractiveSession) Pause()

Pause is a terminator that will render long-form text added via the another method that returns *InteractiveSession and will wait for the user to press enter to continue. It is useful for long-form content or paging.

func (*InteractiveSession) PauseWithPrompt

func (i *InteractiveSession) PauseWithPrompt(format string, args ...interface{})

PauseWithPrompt is a terminator that will render long-form text added via the another method that returns *InteractiveSession and will wait for the user to press enter to continue. This will use the custom prompt specified by format and args.

func (*InteractiveSession) Reset added in v1.2.0

func (i *InteractiveSession) Reset()

Reset allows reuse of the same interactive session by reseting its state and keeping its current input and output

func (*InteractiveSession) Say

func (i *InteractiveSession) Say(format string, args ...interface{}) *InteractiveSession

Say is a short form of fmt.Fprintf but allows you to chain additional terminators to the interactive session to collect user input

func (*InteractiveSession) Warn

func (i *InteractiveSession) Warn(format string, args ...interface{}) *InteractiveSession

Warn adds an informational warning message to the user in format Warning: <user defined string>

type Justification

type Justification int

Justification sets the default placement of text inside each cell of a column

const (
	Left Justification = iota
	Center
	Right
)

Column justification flags

type Progress

type Progress struct {
	// Prompt to display before spinner or bar
	Prompt string
	// Approximate length of the total progress display, including
	// the prompt and the ..., does not include status indicator
	// at the end (e.g, the spinner, FAIL, OK, or XX%)
	DisplayLength int
	// contains filtered or unexported fields
}

Progress structure used to render progress and loading indicators

func NewIncrementalProgressBar added in v1.3.0

func NewIncrementalProgressBar(steps int, format string, args ...interface{}) *Progress

NewIncrementalProgressBar returns a new progress bar with a fixed number of steps. This can be useful when you want independent go routines to update total progress as they finish work without knowing the total state of the system. You can call `defer mybar.Increment()` in your go routine to update the value of the bar by one increment.

func NewLoadingMessage

func NewLoadingMessage(message string, spinner Spinner, delay time.Duration) *Progress

NewLoadingMessage creates a spinning loading indicator followed by a message. The loading indicator does not indicate sucess or failure and disappears when you call either Success() or Failure(). This is useful to show action when making remote calls that are expected to be short. The delay parameter is to prevent flickering when the remote call finishes quickly. If you finish your call and call Success() or Failure() within the delay period, the loading indicator will never be shown.

func NewProgressBar

func NewProgressBar(format string, args ...interface{}) *Progress

NewProgressBar returns a new progress bar with prompt <message> display length defaults to 20

func NewProgressSpinner

func NewProgressSpinner(format string, args ...interface{}) *Progress

NewProgressSpinner returns a new spinner with prompt <message> display length defaults to 30.

func (*Progress) Fail

func (p *Progress) Fail()

Fail should be called on a progress bar or spinner if a failure occurs

func (*Progress) Increment added in v1.3.0

func (p *Progress) Increment()

Increment updates a stepped progress bar

func (*Progress) Start

func (p *Progress) Start()

Start launches a Goroutine to render the progress bar or spinner and returns control to the caller for further processing. Spinner will update automatically every 250ms until Success() or Fail() is called. Bars will update by calling Update(<pct_complete>). You must always finally call either Success() or Fail() to terminate the go routine.

func (*Progress) Success

func (p *Progress) Success()

Success should be called on a progress bar or spinner after completion is successful

func (*Progress) Update

func (p *Progress) Update(pct float64)

Update the progress bar using a number [0, 1.0] to represent the percentage complete

type Row

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

Row is a row of cells in a table. You want to use AddRow or AddStyledRow to create one.

type SessionOption added in v1.1.0

type SessionOption func(i *InteractiveSession)

SessionOption optionally configures aspects of the interactive session

func WithInput added in v1.1.0

func WithInput(r io.Reader) SessionOption

WithInput uses an input other than os.Stdin

func WithOutput added in v1.1.0

func WithOutput(w io.Writer) SessionOption

WithOutput uses an output other than os.Stdout

type Spinner

type Spinner []string

Spinner is a set of unicode strings that show a moving progress indication in the terminal

var (
	// Wheel created with pipes and slashes
	Wheel Spinner = []string{"|", "/", "-", "\\"}
	// Bouncing dots
	Bouncing Spinner = []string{"⠁", "⠂", "⠄", "⠂"}
	// Clock that spins two hours per step
	Clock Spinner = []string{"🕐 ", "🕑 ", "🕒 ", "🕓 ", "🕔 ", "🕕 ", "🕖 ", "🕗 ", "🕘 ", "🕙 ", "🕚 "}
	// Dots that spin around a rectangle
	Dots Spinner = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
)

type Style

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

Style represents a computed style from one or more colors or textstyles as the ANSI code suitable for terminal output

func Styled

func Styled(s ...Styler) *Style

Styled contructs a composite style from one of more color or textstyle values. Styles can be applied to a string via ApplyTo or as a shortcut use SStyled which returns a string directly Example: Styled(White, Underline)

func (*Style) ApplyTo

func (s *Style) ApplyTo(content string) string

ApplyTo applies styles created using the Styled command to a string to generate an styled output using ANSI terminal codes

type Styler

type Styler interface {
	Codes() (int, int)
}

Styler is an interface that is fulfilled by either a Color or Textstyle to be applied to a string

type Table

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

Table is a table output to the console. Use NewTable to construct the table with sensible defaults. Tables detect the terminal width and step through a number of rendering strategies to intelligently wrap column information to fit within the available space.

func NewTable

func NewTable(numColumns int, options ...TableOption) *Table

NewTable creates a new table with a given number of columns, setting the default justfication to left, and attempting to detect the existing terminal size to set size defaults.

func (*Table) AddRow

func (t *Table) AddRow(rowStrings ...string) *Table

AddRow adds a new row to the table given an array of strings for each column's content. You can set styles on a row by using AddStyledRow instead. If you add more cells than available columns, the cells will be silently truncated. If there are fewer values than columns, the remaining columns will be empty.

func (*Table) AddStyledRow

func (t *Table) AddStyledRow(cells ...Cell) *Table

AddStyledRow adds a new row to the table with custom styles for each Cell. If you add more cells than available columns, the cells will be silently truncated. If there are fewer values than columns, the remaining columns will be empty.

func (*Table) AsString

func (t *Table) AsString() string

AsString returns the rendered table as a string instead of immediately writing to the configured writer

func (*Table) ColumnHeaderStyles

func (t *Table) ColumnHeaderStyles(styles ...*Style) *Table

ColumnHeaderStyles sets the column header styles.

func (*Table) ColumnHeaders

func (t *Table) ColumnHeaders(headers ...string) *Table

ColumnHeaders sets the column headers with an array of strings The default style is Underline and Bold. This can be changed through a call to ColumnHeaderStyles.

func (*Table) ColumnStyles

func (t *Table) ColumnStyles(styles ...*Style) *Table

ColumnStyles sets the default styles for each column in the row except the column headers.

func (*Table) Justification

func (t *Table) Justification(cellJustifications ...Justification) *Table

Justification sets the justification of each column. If you pass more justifications than the number of columns they will be silently dropped.

func (*Table) SetWriter

func (t *Table) SetWriter(w io.Writer)

SetWriter sets the output writer if not writing to Stdout

func (*Table) Show

func (t *Table) Show()

Show will render the table using the headers, title, and styles previously set.

func (*Table) ShowPage

func (t *Table) ShowPage(n int)

ShowPage will render the table but pauses every n rows to paginate the output. If n=0, it will use the detected terminal height to make sure that the number of rows shown will fit in a single page.

func (*Table) Title

func (t *Table) Title(s string, styles ...Styler) *Table

Title sets the title for the table. The default style is bold, but can be changed by passing your own styles

type TableOption

type TableOption func(t *Table) error

TableOption is a function that sets an option on a table

func MaxHeight

func MaxHeight(h int) TableOption

MaxHeight sets the table maximum height that can be used for pagination of long tables. Use this only when you want to reduce the maximum height of the table to something less than the detected height of the terminal. Normally you don't need to use this and should prefer the auto detection.

func MaxWidth

func MaxWidth(w int) TableOption

MaxWidth sets the max width of the table. The actual max width will be set to the smaller of this number of the detected width of the terminal. Very small max widths can be a problem because the layout engine will not be able to find a strategy to render the table.

func Spacing

func Spacing(n int) TableOption

Spacing adjusts the spacing of the table. For n=2, there will be one whitespace line between each row

type Textstyle

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

Textstyle represents a ANSI-coded text style

func (Textstyle) Codes

func (t Textstyle) Codes() (int, int)

Codes returns ANSI styling values for a textstyle

type Title

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

Title is a special cell that is rendered at the center top of the table that can contain its own styling.

type ValidationFunc

type ValidationFunc func(s string) (bool, error)

ValidationFunc is a type alias for a validator that takes a string and returns true if it passes validation. Error provides a helpful error message to the user that is shown before re-asking the question.

func AllowedOptions

func AllowedOptions(options []string) ValidationFunc

AllowedOptions builds a new validator from a []string of options

func Required

func Required() ValidationFunc

Required validates that the length of the input is greater than 0

func ValidateYesNo

func ValidateYesNo() ValidationFunc

ValidateYesNo is a validation function that ensures that a yes/no question receives a valid response. Use IsYes or IsNo to test for a particular yes or no response.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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