Documentation
¶
Overview ¶
Package input turns the bytes a terminal sends into events.
A terminal reports input as a stream that mixes plain text with escape sequences, and it splits that stream wherever the read happens to land: half a sequence in one read and half in the next is normal, not an error. Parser is therefore incremental — it is fed whatever arrived and returns whatever is now unambiguous.
Nothing here touches a terminal. The parser is a function of its bytes, which is what lets every sequence this package claims to understand be stated as a test.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Code ¶
type Code int
Code identifies which key was pressed. Character means the key produced text, carried in Key.Rune.
type Event ¶
type Event interface {
// contains filtered or unexported methods
}
Event is one thing the terminal reported. The set is closed by the unexported method: a consumer's switch over events is exhaustive by construction.
type Handler ¶
Handler is anything that answers an event, reporting whether it consumed it.
It lives here for the same reason [grid.Drawer] lives with the view: the word belongs to the layer that owns the thing being handled. Everything further up that answers input says so by embedding this, so "consumed" means one thing across the whole repository rather than one thing per layer that happens to line up.
An unconsumed event carries on to whatever else might want it, which is how a key can mean one thing inside a text field and another outside it without either side knowing about the other.
type Key ¶
type Key struct {
Code Code
Rune rune
Mods Mods
// Transition is Press unless the terminal speaks the Kitty keyboard protocol,
// which is the only way repeats and releases are ever reported.
Transition Transition
// Text is what the key produced, when the terminal was able to say. It can
// hold more than one code point, and is empty on terminals that do not report
// it — Rune is the fallback and the common case.
Text string
}
Key is a keyboard event.
A character key arrives as Character with the rune in Rune. Ctrl held with a letter also arrives as a character — the letter, lowercased, with Ctrl in Mods — because that is what the terminal actually sends and inventing a separate representation for it would mean two ways to ask the same question.
func (Key) Down ¶
Down reports whether the key is going down — pressed or auto-repeating. Most handlers want this rather than Press alone, or holding a key stops working on terminals that report repeats.
func (Key) Is ¶
Is reports whether the key is code with exactly mods held.
Exactly, not at least: a binding on Ctrl+C that also fired for Ctrl+Shift+C would swallow a keystroke its owner never claimed.
type Mods ¶
type Mods uint8
Mods is the set of modifier keys held during an event.
type Mouse ¶
type Mouse struct {
Pos image.Point
Action MouseAction
Button Button
Mods Mods
}
Mouse is a mouse event, positioned in cells with the origin at the top left.
type MouseAction ¶
type MouseAction uint8
MouseAction is what the mouse did.
const ( MouseDown MouseAction = iota MouseUp MouseDrag MouseMove WheelUp WheelDown )
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser decodes terminal bytes into events, incrementally.
Bytes are handed to Parser.Feed exactly as they arrived, at whatever boundaries the read produced. Anything not yet unambiguous stays buffered: escape sequences and multi-byte characters routinely arrive in pieces, and a decoder that assumed otherwise would drop keys under load.
One case cannot be resolved by waiting. A lone escape byte is either the Escape key or the start of a sequence whose remainder has not arrived, and only time tells the difference. Parser.Pending reports that something is waiting, and Parser.Flush declares the wait over.
Not safe for concurrent use: it belongs to whichever goroutine reads the terminal.
func (*Parser) Flush ¶
Flush resolves what only time could resolve and returns the result.
A buffered escape becomes the Escape key, and anything after it is re-read as ordinary input. A half-arrived character is dropped, since the rest is never coming. A paste in progress is left alone: it is incomplete rather than ambiguous, and cutting it short would corrupt the text.
func (*Parser) Pending ¶
Pending reports whether anything is waiting for more input to make sense of it: bytes that might yet become a sequence, or a runaway one still being dropped. It is what tells a loop to arm the timer that will call Parser.Flush, and the runaway counts because the state has to end somewhere — otherwise the next keystroke that happened to be a parameter byte would vanish into it.
type Paste ¶
type Paste struct{ Text string }
Paste is a block of text the terminal delivered as a paste rather than as keystrokes, so it can be inserted whole instead of being interpreted a character at a time.
type Resize ¶
type Resize struct{ Width, Height int }
Resize reports the terminal's new size in cells.
type Transition ¶
type Transition uint8
Transition is what happened to a key.
const ( // Press is the zero value: an ordinary terminal only ever reports presses, // and a Key literal that says nothing about its transition means one. Press Transition = iota Repeat Release )