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
- Variables
- func NewFrameTTY(console io.ReadWriter) (*TTY, *Region)
- type Region
- type TTY
- func (t *TTY) Clear()
- func (t *TTY) NewRegion(w, h, x, y int) *Region
- func (t *TTY) Read(b []byte) (n int, err error)
- func (t *TTY) SetCursor(x, y int)
- func (t *TTY) SetEcho(echo io.Writer)
- func (t *TTY) SetLineBuffer(size int)
- func (t *TTY) SetMode(mode ttyMode)
- func (t *TTY) Write(b []byte) (n int, err error)
Constants ¶
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
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.
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.
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 ¶
var FancyBorder = borderStyle{
196, 179,
218, 194, 191,
195, 197, 180,
192, 193, 217,
}
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 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 ¶
NewRawTTY creates a new TTY without line editing and with a larger potential input buffer size, and with no interactive echo.
func NewTTY ¶
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) SetCursor ¶
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 ¶
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 ¶
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.