console

package module
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2022 License: MIT Imports: 10 Imported by: 4

README

Go Console

Util package for convenient terminal input and output including a command line environment with command history and fully customizable completion.

See section Command Line Environment for a sophisticated and highly customizable bash-like input environment. Section Custom Completion Handlers contains some details on how command completion works and can be customized.

Basic Input & Output

This package includes the most common output methods known from the fmt package:

console.Print("foo", "bar")          // outputs "foo bar"
console.Printf("hello %s", "world")  // outputs "hello world"
console.Println("foobar")            // outputs "foobar\n"
console.Printlnf("foo%s", "bar")     // outputs "foobar\n"

For basic input you can use ReadLine and ReadPassword for hidden input:

line, err := console.ReadLine()
password, err := console.ReadPassword() // will hide input while typing

See examples/basic-input for an example application.

Command Input

A more advanced input method is provided by ReadCommand. It reads and parses a command from input, respecting all escape characters and quoted phrases:

cmd, err := console.ReadCommand("prompt", nil) // prompt> {user input here}
// example user input: echo foo 'say "hello world"' "white space" escape\ sequence
// cmd[0] = "echo"
// cmd[1] = "foo"
// cmd[2] = "say \"hello world\""
// cmd[3] = "white space"
// cmd[4] = "escape sequence"

You can additionally pass handlers for command history (up and down arrow keys), aswell as completion (tab key). Consider using a Command Line Environment for command-based applications.

See examples/read-command for an example application.

Command Line Environment

The most sophisticated input method is by instantiating a Command Line Environment. It allows you to register commands and handlers for special events and automatically sets correct handlers for command history and completion when reading a command:

// instantiate command line environment
cle := console.NewCommandLineEnvironment()
// register default exit command
cle.RegisterCommand(console.NewExitCommand("exit"))
// register a new command that takes no parameters
cle.RegisterCommand(console.NewParameterlessCommand("hello",
    func(args []string) error {
        // handler method for command execution
        console.Println("world")
    }))

// Run() enters an infinite loop for command input and execution
// if a command returns console.ErrExit() this loop will stop gracefully
if err := cle.Run(); err != nil {
    console.Fatalln(err)
}

In most cases you probably want to allow completion of command arguments. This can be done by passing a completion handler when instantiating a custom command. For simple command arguments you can use the default handlers of this package:

cle.RegisterCommand(console.NewCustomCommand("hello",
    // default completion handler for a fixed set of arguments (fixed order and no flags)
    console.NewFixedArgCompletion(
        // the first argument will offer completions for a fixed set of options
        console.NewOneOfArgCompletion("world", "ma'am", "sir"),
        // you can pass an arbitrary number of completion handlers here for further arguments
    ),
    func(args []string) error {
        // the completion does not enforce presence of arguments
        if len(args) > 0 {
            console.Printlnf("hello %s", args[0])
        }
    }))

To select a file or directory from the local file system, there is a default completion handler available. Use the withFiles flag to control whether files should be offered in the completion list:

cle.RegisterCommand(console.NewCustomCommand("cat",
    // allow user to browse the local file system for completion and include files
    console.NewFixedArgCompletion(console.NewLocalFileSystemArgCompletion(true)),
    // actual command execution handler:
    func(args []string) error {
        // always remember to check arguments
        if len(args) == 0 {
            console.Println("missing arg")
        } else {
            // show content of file...
        }
    }))

See examples/command-line-env, examples/error-handling and examples/browser for example applications.

Customizations

See the following list for possible customizations of the Command Line Environment:

Field Name Description Default
Prompt Callback function to specify the current command prompt. Will be called every time the prompt is displayed. Use cle.SetStaticPrompt to set a static prompt. cle>
PrintOptions Callback function to print options on double-tab. DefaultOptionsPrinter()
ExecUnknownCommad A handler that is called when an unknown command is executed. If set to nil, the execution loop will end returning an unkown command error. Print message and continue
CompleteUnknownCommand Completion handler for unknown commands. nil
ErrorHandler Error handler to handle errors and panics returned from commands. Will end the execution loop and pass through the error if something else than nil is returned. Print error message and continue
RecoverPanickedCommands If set to true, panics from commands are recovered and passed to ErrorHandler. Use console.IsErrCommandPanicked to recognize panics. true
UseCommandNameCompletion If set to false, no completion is available for command names. true
Custom Completion Handlers

Completion handlers are called every time the user presses the tab key. They receive the full, parsed command as input, aswell as the index of the currently edited entry. When using completion handlers for registered commands of a command line environment, you can ignore the first entry as it will always contain the name of the corresponding command. The handler can return the full list of available options because prefix filtering for the current user input will be done automatically:

func completionHandler(cmd []string, index int) []console.CompletionOption {
    return []console.CompletionOption{
        // labelled options will be displayed with custom label in listings
        console.NewLabelledCompletionOption("Greeting", "hello", false),
        // in most cases only the ReplaceString property is required
        console.NewCompletionOption("hedgehog", false),
        console.NewCompletionOption("world", false),
    }
}

The replacement parameter of NewLabelledCompletionOption and NewCompletionOption is the actual value to be used for completion. If the user has already typed h and presses tab, the prefix will match hello and hedgehog, so the longest common prefix he is taken as completion. The user now types l to further specify the desired value and again presses tab. Only one candidate now matches the prefix and so the full replacement string hello is taken as completion. Furthermore, a whitespace character is emitted to begin the next argument because the isPartial parameter is set to false.

The first label parameter of NewLabelledCompletionOption can be set to an arbitrary value and does not affect the actual completion in any way. It is displayed instead of the actual replacement property in the options list on double-tab. This can be useful when completion is used on hierachical structures like file systems where you only want to display the file names and not the full path.

Custom Completion Arg

You can also extend the NewFixedArgCompletion with custom types that implement ArgCompletion:

type ArgCompletion interface {
    GetCompletionOptions(currentCommand []string, entryIndex int) (options []CompletionOption)
}

Applications

See s3client for a real-world application using go-console.

Documentation

Index

Constants

View Source
const (
	// KeyEscape represents the escape key
	KeyEscape = Key(keyboard.KeyEsc)
	// KeyCtrlC represents the key combination Ctrl+C
	KeyCtrlC = Key(keyboard.KeyCtrlC)
	// KeyCtrlW represents the key combination Ctrl+W
	KeyCtrlW = Key(keyboard.KeyCtrlW)
	// KeyCtrlS represents the key combination Ctrl+S
	KeyCtrlS = Key(keyboard.KeyCtrlS)
	// KeyUp represents the arrow up key
	KeyUp = Key(keyboard.KeyArrowUp)
	// KeyDown represents the arrow down key
	KeyDown = Key(keyboard.KeyArrowDown)
	// KeyLeft represents the arrow left key
	KeyLeft = Key(keyboard.KeyArrowLeft)
	// KeyRight represents the arrow right key
	KeyRight = Key(keyboard.KeyArrowRight)
	// KeyHome represents the home (Pos1) key
	KeyHome = Key(keyboard.KeyHome)
	// KeyEnd represents the end key
	KeyEnd = Key(keyboard.KeyEnd)
	// KeyPageUp represents the page up key
	KeyPageUp = Key(keyboard.KeyPgup)
	// KeyPageDown represents the page down key
	KeyPageDown = Key(keyboard.KeyPgdn)
	// KeyBackspace represents the backspace key
	KeyBackspace = Key(keyboard.KeyBackspace2)
	// KeyDelete represents the delete key
	KeyDelete = Key(keyboard.KeyDelete)
	// KeyEnter represents the enter key
	KeyEnter = Key(keyboard.KeyEnter)
	// KeyTab represents the tabulator key
	KeyTab = Key(keyboard.KeyTab)
	// KeySpace represents the space key
	KeySpace = Key(keyboard.KeySpace)
)

Variables

View Source
var (
	// DefaultInput can be used to redirect input sources.
	DefaultInput Input
	// DefaultOutput can be used to redirect output destinations.
	DefaultOutput Output
)

Functions

func BeginReadKey added in v0.9.9

func BeginReadKey() error

BeginReadKey opens a raw TTY and allows you to use ReadKey.

func EndReadKey added in v0.9.9

func EndReadKey() error

EndReadKey closes the raw TTY opened by BeginReadKey and discards all unprocessed key events.

func Fatal

func Fatal(a ...interface{})

Fatal calls Print and exits with code 1.

func Fatalf

func Fatalf(format string, a ...interface{})

Fatalf calls Printf and exits with code 1.

func Fatalln

func Fatalln(a ...interface{})

Fatalln calls Println and exits with code 1.

func Fatallnf

func Fatallnf(format string, a ...interface{})

Fatallnf calls Printlnf and exits with code 1.

func GetSize added in v0.9.0

func GetSize() (int, int, error)

GetSize returns the current terminal dimensions in characters.

func Print

func Print(a ...interface{}) (int, error)

Print writes a set of objects separated by whitespaces to Stdout.

func PrintList

func PrintList(obj interface{}) error

PrintList prints all array or map values in a regular grid.

func Printf

func Printf(format string, a ...interface{}) (int, error)

Printf writes a formatted string to Stdout.

func Println

func Println(a ...interface{}) (int, error)

Println writes a set of objects separated by whitespaces to Stdout and ends the line.

func Printlnf

func Printlnf(format string, a ...interface{}) (int, error)

Printlnf writes a formatted string to Stdout and ends the line.

func ReadLine

func ReadLine() (string, error)

ReadLine reads a line from Stdin.

This method should not be used in conjunction with Stdin read from other packages as it might leave an orphaned '\n' in the input buffer for '\r\n' line breaks.

func ReadPassword

func ReadPassword() (string, error)

ReadPassword reads a line from Stdin while hiding the user input.

This method should not be used in conjunction with Stdin read from other packages as it might leave an orphaned '\n' in the input buffer for '\r\n' line breaks.

func SupportsColors added in v0.9.2

func SupportsColors() bool

SupportsColors returns true when the current terminal supports ANSI colors.

func WithReadKeyContext added in v0.9.3

func WithReadKeyContext(f func() error) error

WithReadKeyContext executes the given function with surrounding BeginReadKey and EndReadKey calls.

Types

type Input added in v0.9.3

type Input interface {
	ReadLine() (string, error)
	ReadPassword() (string, error)
	BeginReadKey() error
	ReadKey() (Key, rune, error)
	EndReadKey() error
}

Input defines functionality to handle console input.

type Key

type Key keyboard.Key

Key represents a key.

func ReadKey

func ReadKey() (Key, rune, error)

ReadKey returns a key and the corresponding rune or an error. BeginReadKey needs to be called first.

func (Key) String

func (k Key) String() string

type Output added in v0.9.3

type Output interface {
	Print(string) (int, error)
	GetSize() (int, int, error)
	SupportsColors() bool
	Exit(int)
}

Output defines functionality to handle console output and os responses.

Jump to

Keyboard shortcuts

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