term

package
v0.0.0-...-8820093 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2013 License: Apache-2.0 Imports: 3 Imported by: 2

Documentation

Overview

Package term provides a basic terminal emulation framework.

The TTY class abstracts the logic of providing line editing and line buffering, as well as escape sequence recognition. When creating a TTY with the NewTTY function, interactive echo will automatically be enabled if the provided io.Reader's underlying object also implements io.Writer.

Line editing capabilities (Line mode)

The line editing facilities are very basic; you can type, and you can backspace out characters up to the beginning of the line. Note that for all internal purposes, typing a control character (e.g. ^D or ^C) starts a new line, including for line history below.

You can also use the arrow keys for editing:

LEFT   Move back one character
RIGHT  Move forward one character
DOWN   Move to the end of the line
UP     Restore previous line (see below)

Line history (Line mode)

Currently the TTY only has a single-line history. Pressing the return key will save the current line in that history, and pressing the "up" arrow at any time will restore the previous line.

Example

The following example reads from standard input, calling runCommand with the complete lines it accumulates.

tty := term.NewTTY(os.Stdin)

line := ""
for {
    n, err := tty.Read(raw)
    if err != nil {
        log.Printf("read: %s", err)
        return
    }

    switch str := string(raw[:n]); str {
    case "quit", term.Interrupt, term.EndOfFile:
        fmt.Println("Goodbye!")
        return
    case term.CarriageReturn, term.NewLine:
        runCommand(line)
        line = ""
    default:
        line += str
    }
}

In order for the above example to work, the terminal must be in raw mode, which can be done by running your binary like so (on a unix-like operating system like linux or darwin):

stty raw; cmd; stty cooked

Index

Constants

View Source
const (
	NUL = iota
	SOH // Start of Header
	STX // Start of Text
	ETX // End of Text
	EOT // End of Transmission
	ENQ // Enquire
	ACK // Acknowledge
	BEL // Bell
	BS  // Backspace
	TAB // Horizontal tab
	LF  // Line feed
	VT  // Vertical tab
	FF  // Form feed
	CR  // Carriage return
	SO  // Shift out
	SI  // Shift in
	DLE // Data link escape
	DC1 // Device Control 1
	DC2 // Device Control 2
	DC3 // Device Control 3
	DC4 // Device Control 4
	NAK // Negative Acknowledge
	SYN // Synchronize
	ETB // End Transmission Block
	CAN // CANCEL
	EM  // End of Medium
	SUB // Substitute
	ESC // Escape
	FS  // File separator
	GS  // Group separator
	RS  // Record separator
	US  // Unit separator

	DEL = 127 // Delete
)

Terminal Control Codes

View Source
const (
	Interrupt = "\x03" // ^C
	EndOfFile = "\x04" // ^D
	Suspend   = "\x1a" // ^Z
	Quit      = "\x1c" // ^\

	CarriageReturn = "\r"
	NewLine        = "\n"
)

Control Constants

These are all emitted by themselves to easily discern them from the rest of the sequence of chunks.

View Source
const (
	ReadBufferLength       = 32
	DefaultLineBufferSize  = 32
	DefaultRawBufferSize   = 256
	DefaultFrameBufferSize = 8
)

The following constants are provided for your own edification; they are the internal defaults and cannot be changed.

View Source
const (
	Raw   ttyMode = iota // All reads are passed through
	Line                 // Basic line-editing capabilities are provided
	Frame                // Basic screen-editing capabilities are provided
)

The following constants are the modes in which the TTY can be set

Variables

View Source
var FancyBorder = borderStyle{
	196, 179,
	218, 194, 191,
	195, 197, 180,
	192, 193, 217,
}
View Source
var SimpleBorder = borderStyle{
	'-', '|',
	',', '+', '.',
	'+', '+', '+',
	'`', '+', '\'',
}

Functions

func NewFrameTTY

func NewFrameTTY(console io.ReadWriter) (*TTY, *Region)

NewFrameTTY creates a new TTY for interacting with a user via a screen-oriented interface. If the given reader is also an io.Writer, interactive echo is enabled.

A TTY created with NewFrameTTY has synchronized reads, so further input is not processed until the chunk has been read. The default read buffer size for a Frame TTY is much smaller than the others.

The default region for a new Frame is an 80x24 region with the initial cursor placed in the upper right-hand corner. This region is returned, but will not have been been drawn (e.g. its settings can be changed).

Types

type Region

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

func (*Region) Draw

func (r *Region) Draw()

func (*Region) SetBorder

func (r *Region) SetBorder(style borderStyle)

func (*Region) SetPos

func (r *Region) SetPos(x, y int)

func (*Region) SetSize

func (r *Region) SetSize(width, height int)

type TTY

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

A TTY is a simple interface for reading input from a user over a raw terminal emulation interface.

All methods on TTY are goroutine-safe (though calling Read concurrently is probably not the most deterministic thing in the world to do).

func NewRawTTY

func NewRawTTY(console io.Reader) *TTY

NewRawTTY creates a new TTY without line editing and with a larger potential input buffer size, and with no interactive echo.

func NewTTY

func NewTTY(console io.Reader) *TTY

NewTTY creates a new TTY for interacting with a user via a limited line-oriented interface. If the given reader is also an io.Writer, interactive echo is enabled.

func (*TTY) Clear

func (t *TTY) Clear()

func (*TTY) NewRegion

func (t *TTY) NewRegion(w, h, x, y int) *Region

func (*TTY) Read

func (t *TTY) Read(b []byte) (n int, err error)

Read reads the next line, chunk, control sequence, etc from the console.

func (*TTY) SetCursor

func (t *TTY) SetCursor(x, y int)

SetCursor Places the cursor at the given x,y position.

Both x and y start at 0 and increase right and down.

func (*TTY) SetEcho

func (t *TTY) SetEcho(echo io.Writer)

SetEcho enables or disables interactive echo, sending all writes on the given writer. Whether the echo writer is specified here or inferred in NewTTY, any write error will disable echo. Providing nil to SetEcho disables interactive echo.

func (*TTY) SetLineBuffer

func (t *TTY) SetLineBuffer(size int)

SetLineBuffer sets the initial line buffer size. In general, you shouldn't need to change this, as the line buffer will continue to grow if the line is really long, but if you find that you have lots of really long lines it might help reduce garbage.

func (*TTY) SetMode

func (t *TTY) SetMode(mode ttyMode)

SetMode sets the TTY mode.

Raw: No line buffering is performed, and data is written exactly as it is received, including control sequences. The input is not broken up into logical units, reads are passed through directly. In the case of an interactive session, this will often be broken up into individual characters or control sequences, not lines or words.

Line: Basic line-buffering is performed. See the package comment.

Frame: Basic screen-editing is enabled. Currently the same as Line.

Switching modes will suspend any state tracking for the old mode. Switching back will resume with the state where it was before the mode was changed, but this may result in unforseen side effects. Changing modes does not effect the line buffer size or whether reads are synchronous, as is the case for TTYs created explicitly in a certain mode. It should not usually be necessary to change modes.

func (*TTY) Write

func (t *TTY) Write(b []byte) (n int, err error)

Write writes to the same io.Writer that is handing the interactive echo. If interactive echo is disabled (either directly or because an echo write failed) Write will return EOF.

Jump to

Keyboard shortcuts

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