Documentation
¶
Overview ¶
Package hotty speaks hotty, HTML over the TTY (https://github.com/neuroplastio/hotty), from a Go program.
A hotty host is a terminal that shows surfaces: small HTML documents placed on rectangles of cells. A program sends documents, placements and deltas as escape sequences in its ordinary output, and hears replies and the user's events on its input.
This package is the wire, and does no I/O:
- The command functions (Doc, Place, Delta, …) return escape sequences as strings. Write them to the terminal like any other output; in a Bubble Tea program, through tea.Raw, so they stay in order with its frames.
- A Decoder turns the OSC sequences the program reads back into Messages: replies (ReplyOf) and events (EventOf), their msgpack bodies read by the types in wire.go.
The packages beside it do the I/O: term for a command that prints and exits or asks a question, hottytea for a full-screen Bubble Tea program, and hottytest for testing either against a host that runs in the test.
Replies ¶
Every command asks for the replies that are usually wanted: Doc and Place are answered on error (EQUOTA, ENOENT), everything else never. The options change that: Q sets the quiet level, and N numbers a command and asks for its reply. Replies arrive on the program's input, mixed with keys. A program that exits leaves unread replies to whatever reads the terminal next, a shell for instance, which reads them as typing.
Names and ids ¶
A surface name is 1 to 64 of A–Z, a–z, 0–9, '_' and '-' (SurfaceName makes one). Other control values, such as element ids, may be any printable ASCII but ':', ';' and '='. Encode replaces each character outside those with '_', as the specification has hosts do (SPEC §3.2), so a value can never end a command early or add a key to it.
Index ¶
- Constants
- func Blur(surface string, opts ...ReplyOption) string
- func CursorBelow(rows int) string
- func DecodeKeys(input []byte) []string
- func DefaultEdit(mod string) map[string][]string
- func Del(surface string, opts ...ReplyOption) string
- func DelAll(opts ...ReplyOption) string
- func DelRes(id string, opts ...ReplyOption) string
- func Delta(surface string, ops []Op, opts ...ReplyOption) string
- func Detach(surface string, opts ...ReplyOption) string
- func Doc(surface, html string, opts ...DocOption) string
- func Edit(names []string, opts ...ReplyOption) string
- func Encode(ctl Control, payload []byte) string
- func EncodeEvent(e Event) string
- func EncodePlain(ctl Control, payload []byte) string
- func Err(r Reply) error
- func Focus(surface, target string, opts ...ReplyOption) string
- func Get(c Control, k string) string
- func Has(c Control, k string) bool
- func HasFeature(c Caps, feature string) bool
- func Hide(surface string, opts ...ReplyOption) string
- func KeyText(key string) (text string, ok bool)
- func Light(c Caps) bool
- func Lookup(c Control, k string) (string, bool)
- func Menu(tree *MenuTree, opts ...ReplyOption) string
- func MenuHide(opts ...ReplyOption) string
- func MenuShow(seq []string, opts ...ReplyOption) string
- func MenuShowOf(m Message) ([]string, error)
- func MorphTo(surface, target, html string, opts ...ReplyOption) string
- func ParseKey(name string) (canonical string, ok bool)
- func Place(surface string, p Placement, opts ...ReplyOption) string
- func PlaceAt(surface string, x, y int, p Placement, opts ...ReplyOption) string
- func Query(n int, opts ...QueryOption) string
- func RemoveAttr(surface, target, name string, opts ...ReplyOption) string
- func ReplyCaps(n string, caps Caps) string
- func ReplyDeltaErr(n, surface string, op int, code, detail string) string
- func ReplyErr(n, surface, re, code, detail string) string
- func ReplyOK(n, surface, re string, extra Control, body []byte) string
- func ReplyQuery(query Control, caps Caps) string
- func Res(id, mime string, data []byte, opts ...ReplyOption) string
- func Reveal(surface, target, where string, opts ...ReplyOption) string
- func Sanitize(v string) string
- func SetAttr(surface, target, name, value string, opts ...ReplyOption) string
- func SetText(surface, target, text string, opts ...ReplyOption) string
- func SetVar(surface, target, name, value string, opts ...ReplyOption) string
- func Speaks(query Control) bool
- func SurfaceName(s string) string
- func Sync(cmds ...string) string
- func Touch(areas []TouchArea, opts ...ReplyOption) string
- func ValidName(s string) bool
- func WithdrawLate() string
- type Action
- type Area
- type Axes
- type Caps
- type Command
- type Control
- type Decoder
- type DetectState
- type Detector
- type DocOption
- type Drag
- type Error
- type Event
- type Flag
- type FormField
- type Hover
- type KV
- type Keymap
- func (m *Keymap) Bind(name string, a Action) bool
- func (m *Keymap) Binds(name string) bool
- func (m *Keymap) Format() string
- func (m *Keymap) Lookup(name string) Action
- func (m *Keymap) Prefix(name string) bool
- func (m *Keymap) Program(name string) bool
- func (m *Keymap) Scroll(name string) Action
- func (m *Keymap) Selects(name string) bool
- type Link
- type MenuItem
- type MenuKeys
- type MenuTree
- type Message
- type Op
- func DeltaOf(m Message) ([]Op, error)
- func OpAfter(target, html string) Op
- func OpAppend(target, html string) Op
- func OpAttr(target, name, value string) Op
- func OpBefore(target, html string) Op
- func OpInner(target, html string) Op
- func OpMorph(target, html string) Op
- func OpPrepend(target, html string) Op
- func OpRemove(target string) Op
- func OpReplace(target, html string) Op
- func OpReveal(target, where string) Op
- func OpText(target, text string) Op
- func OpUnattr(target, name string) Op
- func OpVar(target, name, value string) Op
- type Placement
- type Platform
- type QueryOption
- type Quiet
- type Reply
- type ReplyOption
- type Result
- type Scanner
- type Segment
- type SegmentKind
- type Size
- type TouchArea
- type View
- type Window
Constants ¶
const ( RevealNearest = "" // as little as brings it into view RevealStart = "start" // its top at the top of each box that holds it RevealEnd = "end" // its bottom at the bottom )
Where Reveal brings an element (SPEC §6.1).
const ( DetectTimeout = 1500 * time.Millisecond DetectAfterDA1 = 150 * time.Millisecond DetectAfterReply = 300 * time.Millisecond )
The Detector's times (SPEC §4): how long to wait for any answer at all; after a DA1 answer that came before any reply, for a reply that may still be on its way, since the DA1 may answer a question asked before the query; and after the host's reply, for the DA1 answer behind it, which would otherwise be left for whoever reads the terminal next.
const ( // Number is hotty's OSC number: the ASCII codes of H and O. Number = "7279" // Chunk is the most payload bytes one OSC carries (SPEC §3.4). Chunk = 4096 // MaxSize is the most columns or rows a surface has (SPEC §5.2). MaxSize = 1000 // MaxName is the longest a surface name is (SPEC §3.5). MaxName = 64 // Version is the protocol version this package speaks: what its query // lists, and what a host's capabilities must name (SPEC §4). Version = "0.4" )
const ( ModShift = 1 ModAlt = 2 ModCtrl = 4 ModSuper = 8 )
The modifier keys held during a click, a press or a drag, as the bits of Event.Mods (SPEC §9).
const ( FeaturePassthrough = "passthrough" // the pointer passes through the parts of a surface that take none (SPEC §9.3) FeatureHover = "hover" // it says where the pointer is, with hover events (SPEC §9.4) FeatureCount = "count" // it says that a click repeats one before it (SPEC §9) FeatureMenu = "menu" // it keeps a program's menu, shows its levels and lets the user pick from it (SPEC §10.7) )
The optional features a host may have (SPEC §4), as its capabilities list them (HasFeature).
const ( EventClick = "click" // a button, link, summary or data-on~=click element was activated EventChange = "change" // a control's value was committed, or a box toggled EventInput = "input" // an edit of a control with data-on~=input EventSubmit = "submit" // a form was submitted; the detail is its fields EventPress = "press" // a press anywhere in a placement made with Press EventFocus = "focus" // the user focused an element; Target names it (SPEC §10.1) EventBlur = "blur" // the surface gave the keyboard back EventFit = "fit" // the rows the document needs changed, on a placement made with Fit EventHover = "hover" // the element under the pointer changed, or the pointer left, on a placement made with Hover EventView = "view" // which elements with data-on~=view are in view, or where, changed (SPEC §9.5) // The terminal's events, which belong to no surface: Surface and // Target are empty. EventCommand = "command" // an edit command the program takes, by its key or a menu, or a pick from its own menu (SPEC §10.6, §10.7) EventCaps = "caps" // a capability changed (SPEC §4) // A drag (SPEC §9.1), on an element with data-on~=drag. In the host's // events (Drags), EventDrag stands for all three. EventDragStart = "dragstart" // the primary button pressed on the element EventDrag = "drag" // the element under the pointer changed EventDragEnd = "dragend" // the button released, or the drag cut short )
Event kinds (SPEC §9). A program ignores kinds it does not know: later versions add some.
const ( EINVAL = "EINVAL" // an unknown action or op, a bad name, a missing key, a value out of range ENOENT = "ENOENT" // no surface of that name ENOTARGET = "ENOTARGET" // no element with that id; the detail is the id, or ids comma-separated EDETACHED = "EDETACHED" // the surface is detached (SPEC §5.5) EQUOTA = "EQUOTA" // over one of the host's limits (SPEC §13) EBUDGET = "EBUDGET" // the host gave up on work over its time budget EVERSION = "EVERSION" // a query lists no version the host speaks; the detail is those it speaks (SPEC §4) )
Error codes, in a reply's Code (SPEC §3.6).
const DefaultMax = 16 << 20
DefaultMax is a Decoder's Max when it sets none: 16 MiB, enough for a document with its images inline, and a bound on what a peer can make a Decoder hold.
const MaxDepth = 32
MaxDepth is how deep a body may nest, its map being the first level (SDK.md §3.9). A body nested deeper does not decode, so that no body can exhaust a stack: TinyGo's is 64 KB.
const MenuDepth = 8
MenuDepth is how deep a menu's items nest, the top level's being one deep (SPEC §10.7). A menu nested deeper is EINVAL.
const TerminalKeys = "arrow_left=char-backward ctrl+b=char-backward arrow_right=char-forward ctrl+f=char-forward " +
"alt+arrow_left=word-backward ctrl+arrow_left=word-backward alt+b=word-backward " +
"alt+arrow_right=word-forward ctrl+arrow_right=word-forward alt+f=word-forward " +
"home=line-start end=line-end ctrl+e=line-end " +
"backspace=delete-char-backward ctrl+h=delete-char-backward " +
"delete=delete-char-forward ctrl+d=delete-char-forward " +
"alt+backspace=delete-word-backward ctrl+w=delete-word-backward ctrl+backspace=delete-word-backward " +
"alt+delete=delete-word-forward alt+d=delete-word-forward ctrl+delete=delete-word-forward " +
"ctrl+u=delete-to-line-start ctrl+k=delete-to-line-end " +
"arrow_up=line-previous ctrl+p=line-previous arrow_down=line-next ctrl+n=line-next " +
"page_up=page-up page_down=page-down " +
"alt+<=input-start ctrl+home=input-start alt+>=input-end ctrl+end=input-end " +
"mod+a=select-all " +
"ctrl+m=newline"
TerminalKeys is the SDK's keymap (SDK.md §3.10), as a data-keys value: the keys of Bubble Tea's text input and text area (bubbles), but for mod+a, which selects all, as in a GUI field and SPEC §10.2's default keymap: ctrl+a on Linux, while on macOS ctrl+a stays the line's start. A program puts it in the data-keys of an element that holds its fields, and edits its fields in cells with Resolve(platform, multiline, TerminalKeys), so that they edit the same on a surface and in cells. It leaves enter to SPEC §10.2's default.
const TouchMax = 256
TouchMax is as many areas as an a=touch may name (SPEC §9.6). A body with more is EINVAL.
Variables ¶
This section is empty.
Functions ¶
func Blur ¶
func Blur(surface string, opts ...ReplyOption) string
Blur takes the keyboard back from a surface. Its focused control commits its value first, so a change event may come before the blur event.
func CursorBelow ¶
CursorBelow is the cursor's move a placement without KeepCursor makes (SPEC §5.2): rows index operations (IND) and a carriage return, to the start of the line below the placement. A relay that keeps a placement from the screen it emulates feeds it this instead.
func DecodeKeys ¶
DecodeKeys reads input from the terminal, the bytes a program reads, as SPEC §10.4 names the keys in it: one entry for each key, its name, or "" for input that is no key it names (a mouse report, a sequence it does not know, a key's release). It reads the input whole: an ESC at its end is escape.
func DefaultEdit ¶
DefaultEdit is the default edit shortcuts for a mod (SPEC §10.2), "ctrl" or "super", each key read: ctrl+shift+z and ctrl+y for redo where it is ctrl.
func Del ¶
func Del(surface string, opts ...ReplyOption) string
Del deletes a surface and its placement (SPEC §5.4).
func Delta ¶
func Delta(surface string, ops []Op, opts ...ReplyOption) string
Delta changes one surface's document (SPEC §6.1): the ops, in the order they apply, which the host shows as one. A program that changes a surface in one frame sends one Delta (SDK.md §2.9). A Delta of no ops is sent, and the host refuses it (EINVAL). It is never answered, unless an option asks; a reply to an op that failed names it, by its index.
func Detach ¶
func Detach(surface string, opts ...ReplyOption) string
Detach gives a surface up (SPEC §5.5): it stays on the screen as text does, placed, changed by deltas and deleted as before, but sends no more events and never has the keyboard; if it has it, the keyboard goes back to the terminal with no blur. A program that leaves surfaces on the screen when it exits detaches them first, unless it sent them Detached. The next Doc sent without Detached makes the surface the program's again.
It is never answered, unless an option asks: a reply nobody reads would reach the shell as typing.
func Doc ¶
Doc creates a surface, or replaces its document (SPEC §5.1). The surface is the program's, even one it had detached: it reports what the user does in it, and takes the keyboard on the program's behalf (SPEC §5.5), unless the document is sent Detached. It is answered on error: EQUOTA when the host holds no more surfaces.
func Edit ¶
func Edit(names []string, opts ...ReplyOption) string
Edit takes the edit commands named (SPEC §10.6): "select-all", "copy", "cut", "paste", "undo", "redo". Their keys, the host's edit shortcuts (Caps.Edit), then reach the program as EventCommand in place of their bytes, and the terminal's menus send them with no key. Each Edit replaces the last; none takes nothing. It holds for the screen it is sent on: a full-screen program sends it after switching to the alternate screen, and leaving it drops it.
func Encode ¶
Encode returns one command: the control and the payload, compressed when that makes it smaller, base64-encoded, and split into chunks of at most Chunk bytes (SPEC §3.3, §3.4). Keys are sent as they are; values are cleaned (Sanitize). The keys o and m are Encode's to set: a control given with them goes out without them.
func EncodeEvent ¶
EncodeEvent is the event as a host sends it (SPEC §9): what a relay writes to a program, the surface named as the program knows it, or a host's own. The detail is e.Detail when it has one, as it came, and otherwise what e carries for its kind, each field as its type. Never compressed (SPEC §3.3).
func EncodePlain ¶
EncodePlain is Encode without compression: what a host, or a relay speaking as one, writes to a program, since hosts never compress (SPEC §3.3).
func Focus ¶
func Focus(surface, target string, opts ...ReplyOption) string
Focus gives a surface the keyboard (SPEC §10.1), at an element if target is not empty; else its focused element keeps focus, or its first focusable element takes it.
func HasFeature ¶
HasFeature reports whether the host has an optional feature (SPEC §4): FeaturePassthrough, FeatureHover, FeatureCount or FeatureMenu. Everything else a 0.4 host does, it does.
func Hide ¶
func Hide(surface string, opts ...ReplyOption) string
Hide removes a surface's placement and keeps its document, to place it again without sending it (SPEC §5.4). Deltas still apply to it.
func KeyText ¶
KeyText is the text a key types in a field (SPEC §10.2): a character's, a letter with shift as its capital, a space for space. ok is false for any other key, a key with ctrl, alt or super, and a name that does not parse.
func Menu ¶
func Menu(tree *MenuTree, opts ...ReplyOption) string
Menu tells the host what the program can do now (SPEC §10.7): its menu, a tree of actions with the keys that reach them and the names a pick sends. It lasts until the program sends another, and with nil the program has none. A host shows and picks from it when its capabilities have the feature menu (HasFeature(caps, FeatureMenu)); on one that does not, the program shows its menu itself. The tree is kept within MenuDepth levels.
func MenuHide ¶
func MenuHide(opts ...ReplyOption) string
MenuHide hides the level shown (SPEC §10.7). The menu stays.
func MenuShow ¶
func MenuShow(seq []string, opts ...ReplyOption) string
MenuShow shows the level of the program's menu that the keys typed reach (SPEC §10.7): seq names them as SPEC §10.4 does, "Space" and "f" for a leader and a group. With none it shows the top level. A level shows until the program shows another, or MenuHide.
func MenuShowOf ¶
MenuShowOf reads an a=menu command's show body (SPEC §10.7), as a host or a relay does: the keys typed, as the program names them, whose level to show. No body, or none in it, is the top level: nil, and no error. A command with show=0 has none to read. A body that is no map, or whose seq is not an array of str, is an *Error with Code EINVAL.
func MorphTo ¶
func MorphTo(surface, target, html string, opts ...ReplyOption) string
MorphTo morphs an element into html, or with no target, each top-level element of html into the document's element with its id. Morphing keeps what the user is doing in what stays: focus, the text being typed, an open <details> (SPEC §6.2).
func ParseKey ¶
ParseKey reads a key's name as SPEC §10.4 has hosts read one, with myelin key names' default reading ("Shift+Ctrl+A", "PageDown", "esc"), and returns its canonical name ("ctrl+shift+a", "page_down", "escape"). ok is false for a name the reading refuses (empty, "meta+a", "ctrl+", a modifier given twice), and for one with "mod", which only a Platform reads (ReadKey).
func Place ¶
func Place(surface string, p Placement, opts ...ReplyOption) string
Place places a surface at the cursor (SPEC §5.2). Placing a surface that is placed moves it. It is answered on error: ENOENT when the host has no such surface (it may have dropped it), EINVAL for a size or window out of range. A reply to a placement with Rows 0 carries the rows chosen.
func PlaceAt ¶
func PlaceAt(surface string, x, y int, p Placement, opts ...ReplyOption) string
PlaceAt places a surface with its window's top-left corner at cell (x, y), counted from 0 at the screen's top-left, and leaves the cursor where it was: the way a full-screen program lays surfaces out without disturbing its own drawing. It saves the cursor (DECSC), moves it, places with C=1, and restores it (DECRC).
func Query ¶
func Query(n int, opts ...QueryOption) string
Query asks whether the terminal is a hotty host that speaks Version, fenced by Primary Device Attributes (SPEC §4): a host replies to the query, numbered n, before the DA1 answer every terminal sends, in Version or with EVERSION. A DA1 answer with no reply before it means there is no host. Late asks for a late answer as well.
func RemoveAttr ¶
func RemoveAttr(surface, target, name string, opts ...ReplyOption) string
RemoveAttr removes an attribute from an element.
func ReplyCaps ¶
ReplyCaps is a host's answer to a query numbered n (SPEC §4): caps.Raw as it is when caps has one, so that a relay passes on the fields it does not know, and caps written otherwise.
func ReplyDeltaErr ¶
ReplyDeltaErr is a host's error reply to a delta (SPEC §6.1): as ReplyErr, with i, the index of the first op at fault.
func ReplyOK ¶
ReplyOK is a host's success reply (SPEC §3.6), as a host or a relay answering for one writes it to a program: n and surface echo the command's, each left out when "", re names the action answered, extra keys follow it (a placement's c and r), and body is its msgpack, if any. Never compressed (SPEC §3.3).
func ReplyQuery ¶
ReplyQuery is a host's answer to a query (SPEC §4), for a host that speaks only Version: caps, as ReplyCaps writes them, when the query lists Version, and an EVERSION error naming Version when it does not. caps.V is Version.
func Res ¶
func Res(id, mime string, data []byte, opts ...ReplyOption) string
Res stores a resource that documents refer to as cid:<id> (SPEC §7.1): a stylesheet shared by several surfaces, an image, a font. Sending it again replaces it, and redraws every surface that refers to it.
func Reveal ¶
func Reveal(surface, target, where string, opts ...ReplyOption) string
Reveal scrolls an element into view (SPEC §6.1): each box that holds it, the innermost first, along the axes the document scrolls (Scroll). where is RevealStart, RevealEnd or RevealNearest. It moves no focus, so a list beside the document keeps the keyboard: a table of contents that jumps to a section. Elements that report whether they are in view report it after (EventView).
func Sanitize ¶
Sanitize makes v a control value (SPEC §3.2): each character a value may not hold becomes '_', one for each character, not each byte, and one for each byte that is not UTF-8. Above 0x7e is not merely untidy: UTF-8 can hold 0x9c, which a terminal that reads C1 controls takes for ST, ending the sequence early.
func SetAttr ¶
func SetAttr(surface, target, name, value string, opts ...ReplyOption) string
SetAttr sets an attribute on an element.
func SetText ¶
func SetText(surface, target, text string, opts ...ReplyOption) string
SetText replaces an element's children with one text node: a clock, a count.
func SetVar ¶
func SetVar(surface, target, name, value string, opts ...ReplyOption) string
SetVar sets the custom property --name on an element.
func Speaks ¶
Speaks reports whether a query lists Version among the versions the program speaks (v, SPEC §4). A host that speaks only Version answers it with its capabilities, and any other query with EVERSION: ReplyQuery.
func SurfaceName ¶
SurfaceName makes s a valid surface name: each character a name may not hold becomes '_', and the name is cut to 64 bytes. An empty s is "_".
func Sync ¶
Sync wraps commands in synchronized output (DEC mode 2026, SPEC §6.3): the host shows the state after all of them, never one in between.
func Touch ¶
func Touch(areas []TouchArea, opts ...ReplyOption) string
Touch names the cells where a finger drags as the mouse does (SPEC §9.6), so that what the program drags with the mouse in its cells, a slider, a finger drags too. While the program has the terminal report the mouse's buttons, a touch that begins in an area and first moves the way it drags is the primary button: pressed where it began, moved with the finger, released where it lifts. A tap there presses and releases. Elsewhere, and the other way, a finger scrolls as it did.
The areas last until the program sends others, and with none it leaves none. They are cells of the screen it is sent on: the main and the alternate screen keep their own, leaving the alternate screen drops its, and a full reset drops both. So the program sends them again when what it drew moves, the terminal's size changes, or it switches screens, and sends Touch(nil) when it ends. It keeps to TouchMax areas, W and H at least 1. A host that takes no touch accepts it, and nothing comes of it.
func ValidName ¶
ValidName reports whether s is a surface name a host accepts: 1 to 64 of A–Z, a–z, 0–9, '_' and '-' (SPEC §3.5).
func WithdrawLate ¶
func WithdrawLate() string
WithdrawLate withdraws a query that asked for a late answer (SPEC §4): a query that wants no answer (a=q:q=2), which takes the held one's place. It has no fence, and nothing answers it.
Types ¶
type Action ¶
type Action string
Action is what a text field does with a key (SPEC §10.2): a keymap binds keys to actions, and Lookup says which one a key does.
const ( CharBackward Action = "char-backward" CharForward Action = "char-forward" WordBackward Action = "word-backward" WordForward Action = "word-forward" LineStart Action = "line-start" LineEnd Action = "line-end" DeleteCharBackward Action = "delete-char-backward" DeleteCharForward Action = "delete-char-forward" DeleteWordBackward Action = "delete-word-backward" DeleteWordForward Action = "delete-word-forward" DeleteToLineStart Action = "delete-to-line-start" DeleteToLineEnd Action = "delete-to-line-end" LinePrevious Action = "line-previous" LineNext Action = "line-next" PageUp Action = "page-up" PageDown Action = "page-down" InputStart Action = "input-start" InputEnd Action = "input-end" SelectAll Action = "select-all" Newline Action = "newline" Submit Action = "submit" // Program binds a key to nothing: it reaches the program. Program Action = "program" // Prefix binds a key to the program as Program does, and every key // after it reaches the program too, until it sends a=focus or a=blur // (SPEC §10.5). Prefix Action = "prefix" // Copy, Cut, Paste, Undo and Redo are the field's clipboard and // history (SPEC §10.2). A hottyedit.Field keeps neither, and does // nothing with them. Copy Action = "copy" Cut Action = "cut" Paste Action = "paste" Undo Action = "undo" Redo Action = "redo" // The scroll actions (SPEC §10.2, scrolling keys): outside a text field, // a key bound to one, which the element does not use, scrolls the // nearest element that scrolls, from the focused one outward; a text // field's keymap leaves them out. ScrollUp Action = "scroll-up" ScrollDown Action = "scroll-down" ScrollLeft Action = "scroll-left" ScrollRight Action = "scroll-right" ScrollPageUp Action = "scroll-page-up" ScrollPageDown Action = "scroll-page-down" ScrollHalfPageUp Action = "scroll-half-page-up" ScrollHalfPageDown Action = "scroll-half-page-down" ScrollStart Action = "scroll-start" ScrollEnd Action = "scroll-end" // Insert is what Lookup returns for a character the field types. A // keymap does not bind it. Insert Action = "insert" )
The actions a keymap binds (SPEC §10.2).
func (Action) Moves ¶
Moves reports whether the action is a move, which selects when done with Shift (SPEC §10.2, Shift selects; Keymap.Selects).
type Area ¶
Area is the cells an element covers (SPEC §9), counted as a drag's are: Col and Row are the first column and row it touches, from 0 at the surface's top left (not its window's), and W and H the columns and rows it spans. An element partly clipped or scrolled away has its whole area, so Col and Row may be negative or past the surface.
type Axes ¶
type Axes int
Axes are the directions a document scrolls in (SPEC §5.1): a bitmask of ScrollVertical and ScrollHorizontal.
type Caps ¶
type Caps struct {
// V is the protocol version the host implements: "0.4".
V string `msg:"v"`
// CellCSS is a cell's size in CSS pixels (SPEC §5.3); the zero Size
// when the host did not say.
CellCSS Size `msg:"cellcss,omitempty"`
// Scale is device pixels per CSS pixel: a hint for the resolution of
// images.
Scale float64 `msg:"scale,omitempty"`
// Scheme is the terminal's colour scheme: "dark" or "light".
Scheme string `msg:"scheme,omitempty"`
// Mod is the modifier mod stands for in bindings, "ctrl" or "super"
// (SPEC §10.4); "" when the host did not say, which is ctrl.
Mod string `msg:"mod,omitempty"`
// Features are the optional features the host has (SPEC §4): see
// HasFeature.
Features []string `msg:"features,omitempty"`
// Limits are the host's limits, such as "surfaces" (a count) and
// "resources" (bytes) (SPEC §13).
Limits map[string]int `msg:"limits,omitempty"`
// Net is the host's network policy, from directive to the sources it
// allows (SPEC §7.2): empty when it fetches nothing.
Net map[string][]string `msg:"net,omitempty"`
// Edit is the host's edit shortcuts, from each action to its keys
// (SPEC §10.2); a host that reports them takes edit commands (Edit,
// SPEC §10.6).
Edit map[string][]string `msg:"edit,omitempty"`
// Host names the implementation, if it says.
Host string `msg:"host,omitempty"`
// Version is the implementation's version, with Host: dot-separated
// numbers, compared one by one ("0.0.10" is after "0.0.9").
Version string `msg:"version,omitempty"`
// Raw is the body the capabilities were read from, fields this package
// does not know included: what a relay announces to the programs
// behind it (SPEC §2.7). Writing Caps writes the fields above, not Raw.
Raw []byte `msg:"-"`
}
Caps is what a host says about itself in its reply to a query (SPEC §4), and, with only the fields that changed, in a caps event (SPEC §9).
func CapsOf ¶
CapsOf reads capabilities from the body of a reply to a query (SPEC §4), and reports whether it decoded: what a relay that stored or was handed them reads them with. Raw is a copy of body.
func Merge ¶
Merge is c with the fields a caps event changed (Event.Changed) in place of its own (SPEC §4): those whose keys changed's Raw has. A field the event empties ({}, [] or "") became absent (SPEC §9), and Merge drops it. Its Raw is c's with those fields replaced, so a relay announces the capabilities as they are now.
type Command ¶
type Command struct {
// Name is the command: "copy", "cut", "paste", "undo", "redo",
// "select-all".
Name string
// Key is the key that sent it, named as SPEC §10.4 names it; empty for
// a command from the terminal's menu or a pick from the program's.
Key string
// Text is a paste's text, and HasText whether there is one: a paste
// with nothing on the clipboard, or from a host that cannot read it,
// has none.
Text string
HasText bool
}
Command is an edit command (SPEC §10.6): the program decides what it means, and with nothing to do takes it as its Key, as a text field does.
type Control ¶
type Control []KV
Control is a command's or a message's keys, in the order they are sent.
type Decoder ¶
type Decoder struct {
// Max is the most bytes a message's payload may decode to, after
// base64 and zlib; one that would decode to more is Invalid, and its
// chunks are not kept (SPEC §3.4 lets a host limit a message). Zero is
// DefaultMax. A host sets it to what it accepts from a program, at
// least 1 MiB.
Max int
// Invalid counts the malformed messages dropped so far, aborted
// chunked messages included.
Invalid int
// contains filtered or unexported fields
}
Decoder turns OSC sequences into messages, joining chunked ones (SPEC §3.4). Its zero value is ready to use. It is not safe for concurrent use.
func (*Decoder) Feed ¶
Feed takes one complete OSC sequence, as a terminal-input parser delivers it: ESC ] … terminated by ST or BEL. When the result is Complete, m is the message.
A malformed message (a control that does not parse, a payload that is not base64 or zlib) is Invalid. So is a chunked message that another message interrupts; the interrupting one is then decoded as usual, and its own result returned.
type DetectState ¶
type DetectState uint8
DetectState is what a Detector has found.
const ( // Detecting: nothing is known yet. Detecting DetectState = iota // Native: the terminal is a hotty host. Native // Text: it is not; the program draws in cells. Text )
The states of a Detector.
func (DetectState) String ¶
func (s DetectState) String() string
String names the state: "detecting", "native" or "text".
type Detector ¶
type Detector struct {
// N numbers the query: a reply that does not echo it answers someone
// else's. 0 is 1.
N int
// Late asks for a late answer (Late, SPEC §4).
Late bool
// State is what the Detector has found, and Caps the host's
// capabilities, when Native.
State DetectState
Caps Caps
// Decided is whether State is final; Done, whether detection is over.
Decided, Done bool
// Deadline is when to call Tick next; zero before Start and once Done.
Deadline time.Time
// contains filtered or unexported fields
}
Detector decides whether the terminal is a hotty host (SDK.md §3.8). It is a state machine with the time passed in, so it behaves the same however the program reads the terminal: the program sends what Start returns, gives it each DA1 answer and each reply it reads, calls Tick at Deadline, and End when the input ends or it gives up.
The terminal is a host when it answers the query with capabilities that decode and name Version. Any other answer, an error (EVERSION, from a host that speaks other versions) or capabilities this package cannot read (a 0.1 host's JSON), makes the State Text at once: a host, but not one this program can use (SPEC §4).
Every DA1 answer from the start until Done is detection's, and the program swallows it: it answers the query's fence, or a question asked before, and is no key. A reply that answers the query, ok or an error, is detection's whenever it comes.
With Late, the query asks for a late answer (SPEC §4): the first reply that answers it once the State is Text, and makes the terminal a host, makes the State Native, with the host's capabilities, Decided and Done as it was. The program then starts using hotty.
Decided and Done differ only when the terminal answers the query: what it is is known when its reply arrives, and detection is over when the DA1 answer behind it does. A program that must not wait acts when Decided; one that hands the terminal on, when Done.
Its zero value is ready to use. It is not safe for concurrent use.
func (*Detector) DA1 ¶
DA1 takes a DA1 answer that arrived at now, and reports whether it was detection's.
func (*Detector) End ¶
End ends detection at now: the input ended, or the program gave up. A terminal that has not answered is not a host.
func (*Detector) Reply ¶
Reply takes a reply that arrived at now, and reports whether it answers the query: re=q and the query's n, ok or an error. One that comes after the Detector decided changes nothing, unless the query asked for a late answer (Late): then the first one that comes once the State is Text and makes the terminal a host makes it Native.
type DocOption ¶
type DocOption interface {
// contains filtered or unexported methods
}
DocOption is an option of Doc: a ReplyOption, Detached, or Scroll.
func Detached ¶
func Detached() DocOption
Detached sends a document the program only shows (d=1, SPEC §5.5): the surface is created detached, or its document replaced and the surface detached, in the one command. It reports nothing, never takes the keyboard, and its controls act disabled; hover, selection, <details> and hyperlinks still work, and it is placed, changed by deltas, hidden and deleted as before.
It is what a command prints among its output, which outlives it: whatever reads the terminal next, a shell, would read the surface's events as typing.
func Scroll ¶
Scroll lets the document scroll along the axes given (scroll=<axes>, SPEC §5.1, §5.3), as a page does in a browser: its overflow scrolls, with scrollbars in its pixels, never its cells, and a gesture it cannot take further goes on to the terminal unless the document's CSS overscroll-behavior stops it. Scrolling is local: the program hears nothing of it, and a delta keeps the offsets.
Like Detached, it belongs to the document: one sent without it does not scroll. 0, the default, sends no key; any other value goes out as given, for the host to judge.
type Drag ¶
type Drag struct {
// Col and Row are the surface's cell under the pointer, from 0 at its
// top left (not its window's). They go on past its edges: negative
// above it and to its left, its size or more below and to its right.
Col, Row int
// X and Y are where in the dragged element the pointer is, for an
// element with data-steps (SPEC §9.1): a step from 0 to its count,
// along its width and down its height, measured against the element
// the drag started on wherever the pointer is. HasX and HasY say
// whether the detail has them: an element with no steps along an axis
// has none, and 0 is a step like any other.
X, Y int
HasX, HasY bool
// TX and TY are where in t the pointer is, for a t with drop in its
// data-on and data-steps (SPEC §9.1), in drag and dragend: measured as X and Y are, against
// t's box. HasTX and HasTY say whether the detail has them.
TX, TY int
HasTX, HasTY bool
}
Drag is where a drag's pointer is (SPEC §9.1); the modifier keys held are the event's Mods.
type Error ¶
type Error struct {
Code string // EINVAL, ENOENT, …
Detail string
Re string // the action answered
Surface string
// Op is the index of the op at fault, in an error answering a delta,
// and HasOp whether it names one (Reply.Op).
Op int
HasOp bool
}
Error is an error reply (SPEC §3.6).
type Event ¶
type Event struct {
Surface string
// Kind is one of the Event kinds, or one this package does not know.
Kind string
// Target is the id of the element that reported; empty where the host
// sends no t (SPEC §9): for blur, fit and view, for a link without an
// id (its href is in the detail), and for a press on nothing with an
// id.
Target string
// Value is a control's value (change, input), or the value attribute
// of what was clicked (click).
Value string
// Checked is a checkbox's or a radio button's state, in a change.
Checked *bool
// Fields are a submitted form's fields in tree order, each its name
// and its value: two fields of one name are two pairs.
Fields []FormField
// Mods are the modifier keys held (ModShift, …), as bits: in a click,
// a press and a drag's events. 0 when none is, and for any other
// kind.
Mods int
// Link is a clicked link's.
Link *Link
// FitRows is the rows a fit says the document needs now.
FitRows int
// Drag is a dragstart's, a drag's or a dragend's.
Drag *Drag
// Hover is a hover's (SPEC §9.4).
Hover *Hover
// View is a view's (SPEC §9.5).
View *View
// Area is the cells of the element a click or a press reports, a
// keyboard click's too: what a program places something next to the
// element by, as a browser places a select's list or a menu by its
// control.
Area *Area
// Count is a click's place in its run of clicks on its element, as
// the user's platform counts them (SPEC §9): 2 for the second click of
// a double click, 1 for a single click or the keyboard's. It is 0 for
// any other kind.
Count int
// Command is a command's (SPEC §10.6).
Command *Command
// Changed is a caps's: the capabilities that changed, with only the
// fields the detail has (its Raw), for Merge. A field that became
// absent is in it empty.
Changed *Caps
// Detail is the detail as it came, msgpack: nil when the event has
// none. It is what a relay passes on (EncodeEvent).
Detail []byte
}
Event is what the user did in a surface (SPEC §9).
type Flag ¶
type Flag int
Flag is a surface's p, f or v (SPEC §5.2): absent, On or Off. The zero value is absent, which a placement does not send, and which leaves the flag as it was.
type FormField ¶
type FormField struct{ Name, Value string }
FormField is one field of a submitted form: its name and its value (SPEC §9). On the wire it is the array [name, value].
type Hover ¶
type Hover struct {
// Out is true when the pointer left the window: onto the cells or
// another surface, through a part that lets it through, out of the
// terminal, or pressed with Alt. Col and Row are then 0.
Out bool
// Col and Row are the surface's cell under the pointer when the
// element changed, from 0 at its top left (not its window's).
Col, Row int
}
Hover is where a hover event says the pointer is (SPEC §9.4); the element is the event's Target, empty over nothing with an id and when Out.
type Keymap ¶
type Keymap struct {
// contains filtered or unexported fields
}
Keymap binds keys to actions (SPEC §10.2), read on a Platform. ParseKeymap reads one from a data-keys value; Resolve makes the one a field uses, whose Lookup says what the field does with a key, and Selects whether it selects as it moves. Binds says whether it binds a key, Program whether any focused element's keymap gives a key to the program, and Scroll which scroll action it binds a key to.
func ParseKeymap ¶
ParseKeymap reads a data-keys value as SPEC §10.2 has hosts read it: bindings separated by ASCII white space, each key=action, split at its last '='. It drops the bindings a host ignores: a key that does not parse, an action it does not know, and tab, shift+tab and escape. Mod reads as the Platform's: on ctrl, mod+a and ctrl+a are one key.
func Resolve ¶
Resolve makes a field's keymap (SPEC §10.2): the default keymap for the Platform's Mod, with its edit shortcuts, for an input or for a multi-line field, then each data-keys value in turn, the root's first, each overriding the bindings before it key by key. It leaves out each binding to a scroll action where it stands, in its own value too: one neither acts nor overrides an earlier binding of its key.
func (*Keymap) Bind ¶
Bind binds a key to an action, and reports whether it did: a host ignores the bindings ParseKeymap drops, and so does Bind.
func (*Keymap) Binds ¶
Binds reports whether the keymap binds a key: its own binding, or, for a key with shift that is not a character and that no binding names, the binding without shift (SPEC §10.2). A host that has two names for a press (SPEC §10.4) asks of the physical one first, and of the other only where the keymap does not bind it.
func (*Keymap) Format ¶
Format writes the keymap as a data-keys value: each key once, where it was first bound, as its last binding wrote it (mod kept), with its last action.
func (*Keymap) Lookup ¶
Lookup says what a field with this keymap does with a key (SPEC §10.2): an action; Insert for a key it types (KeyText); or "" when the key is not the field's, and reaches the program (or, for tab, moves focus). A key with shift that is not a character and that no binding names is looked up without shift.
func (*Keymap) Prefix ¶
Prefix reports whether the keymap binds a key to prefix, or, for a key with shift that is not a character and that no binding names, binds it without shift. A host asks it of a key Program gives the program, and from then on gives the program every key, tab, shift+tab and escape too, until the program sends a=focus or a=blur, the surface loses the keyboard, or the user focuses an element of it with a press (SPEC §10.5).
func (*Keymap) Program ¶
Program reports whether the keymap gives a key to the program: binds it to program or prefix, or, for a key with shift that is not a character and that no binding names, binds it without shift (SPEC §10.2, keys for the program).
Every focused element has a keymap, and outside a text field program and the scroll actions are the only actions it gives. A host reads the element's as a field's, from the data-keys values of the elements from the root down to it, but with its scroll actions and no default keymap: ParseKeymap(platform, strings.Join(values, " ")). It gives a key the keymap binds to program or prefix to the program before the element uses it, and before the surface scrolls with it; a nearer binding of the key to another action takes it back. In a field, Lookup says as much.
func (*Keymap) Scroll ¶
Scroll is the scroll action the keymap binds a key to, or "" for none: the key's own binding, or, for a key with shift that is not a character and that no binding names, the binding without shift (SPEC §10.2, scrolling keys).
A host asks it of the keymap it asks Program of, for a key the focused element does not use (space on a button, a character on a select are the element's). A key bound to one scrolls the nearest element that scrolls, from the focused one outward, never the terminal; along an axis the document does not scroll (Scroll, SPEC §5.1), it goes on as if the keymap did not bind it.
func (*Keymap) Selects ¶
Selects reports whether a field with this keymap selects with a key (SPEC §10.2, Shift selects): Lookup returns a move for it, and its name has shift, bound so or looked up without it ("shift+arrow_left", "ctrl+shift+end", not "alt+<"). The field then keeps its anchor and moves the caret (hottyedit.Field.Extend).
type Link ¶
type Link struct{ Href, URL string }
Link is a clicked link: its href, as the document has it, and its URL resolved against the document's base (SPEC §7.3), "" when the href resolves to nothing outside the document.
type MenuItem ¶
type MenuItem struct {
// Key is the key that reaches it after its group's, named as SPEC §10.4
// names it; empty for an item no key reaches.
Key string `msg:"key,omitempty"`
// Label is what it does.
Label string `msg:"label,omitempty"`
// Name is the command a pick sends; empty for an item only its keys
// reach.
Name string `msg:"name,omitempty"`
// Enabled is set when it does anything now.
Enabled bool `msg:"enabled"`
// Items are the items after it, which make it a group.
Items []MenuItem `msg:"items,omitempty"`
}
MenuItem is an action of a menu, or a group of them (SPEC §10.7). Items nest at most MenuDepth deep, the top level's being one deep.
func MenuFind ¶
MenuFind is the first item of tree named name, depth first (SPEC §10.7), or nil: a pick of name is for it. An item with no name, as name "" asks for, is never found.
func MenuLevelOf ¶
MenuLevelOf is the level of tree that the keys seq reach (SPEC §10.7): its items, a group's, for a host to show those that have a key. From the top level, each key of seq enters the first group (an item with Items) at the level whose Key is that key, compared as ReadKey compares: with Mod read as p reads it. With no keys it is the top level. ok is false when the keys reach no group, or tree is nil.
type MenuKeys ¶
type MenuKeys struct {
Seq []string `msg:"seq"`
}
MenuKeys is the body of an a=menu with show=1: the keys typed so far, named as SPEC §10.4 names them, whose level of the menu to show (SPEC §10.7). MenuShow writes it; MenuShowOf reads it.
type MenuTree ¶
type MenuTree struct {
// Label is what the menu is for: "Files". Empty leaves it to the host.
Label string `msg:"label,omitempty"`
// Items are the menu's top level, in the order to show them.
Items []MenuItem `msg:"items"`
}
MenuTree is what a program can do (Menu, SPEC §10.7): a myelin Tree, each binding given a Name, its groups' items nested in them.
func MenuOf ¶
MenuOf reads an a=menu command's menu (SPEC §10.7), as a host or a relay does: nil, and no error, for a command with no body, which leaves the program no menu. A body that is no menu, holds a field of another type, or nests its items deeper than MenuDepth is an *Error with Code EINVAL. A command with show is not a menu: MenuShowOf reads it.
type Message ¶
Message is one hotty message: a reply or an event from the host, or a command from the program (what a host, a relay or a test decodes). Its control is in the order the keys came, so a relay that forwards it sends the same bytes.
type Op ¶
type Op struct {
// Op names what it does: "morph", "text", ….
Op string `msg:"op"`
// Target is the id of the element, as the document has it; empty for
// a morph of the whole tree, and sent only when not.
Target string `msg:"t,omitempty"`
// Key is the name of the attribute or the custom property, for attr,
// unattr and var.
Key string `msg:"k,omitempty"`
// Value is the HTML, the text or the value; nil when the op has none.
Value *string `msg:"v,omitempty"`
}
Op is one change of a delta (SPEC §6.1): what to do, to which element, with which name, and with which value. The builders OpMorph, OpAttr and the rest make them. Value has presence, not just content: it is absent for an op that takes none, and present, even empty, for one that does (SDK.md §3.4.3).
func DeltaOf ¶
DeltaOf reads a delta command's ops (SPEC §6.1), as a host or a relay does, checking the whole body first: it is an *Error with Code EINVAL, and with HasOp the index of the first op at fault, when the body does not decode (SPEC §3.3) or has no ops, an op is not a map, holds op, t, k or v as anything but a str, or names an op there is none of, an op lacks the t or k it needs (an empty one is none), or a reveal has a value other than start or end. A value an op does not take is ignored, and so is a key this package does not know.
func OpMorph ¶
OpMorph morphs an element into html, or with no target, each top-level element of html into the document's element with its id (SPEC §6.2).
func OpReveal ¶
OpReveal scrolls an element into view (SPEC §6.1): where is RevealStart, RevealEnd or RevealNearest, which has the op no value.
func OpText ¶
OpText replaces an element's children with one text node: a clock, a count. Hosts make it cheap (SPEC §6.1).
func OpVar ¶
OpVar sets the custom property --name on an element: the cheap way to move a bar or a needle every frame, with CSS that reads it.
type Placement ¶
type Placement struct {
// Cols and Rows are the surface's size in cells, 1 to 1000. Rows 0 is
// auto: the host lays the document out Cols wide and takes the rows
// its content needs, and says how many in the reply.
Cols, Rows int
// Window, if not zero, is the part of the surface shown: a full-screen
// program scrolling a surface out of view shows what is still in it.
Window Window
// Z stacks overlapping placements, from -1000 to 1000: greater is
// above, and 0 is the usual.
Z int
// Press, Fit and Hover belong to the surface, not to the placement
// (SPEC §5.2): On turns the event on (1), Off turns it off (0), and
// the zero value, absent, sends nothing and leaves it as it was.
//
// Press asks for a press event wherever the user presses in the
// placement, on text and empty space too (p).
Press Flag
// Fit asks for a fit event whenever the rows the document needs at
// this width change from the rows last heard, starting from this
// placement's (f): an image or font arrived, a resource was
// replaced, a delta landed. The placement keeps its size; placing the
// surface again is the program's to do.
Fit Flag
// Hover asks for a hover event each time the element with an id under
// the pointer changes, and when the pointer leaves the window (v):
// for a hint of the program's own, or to clear what it lit outside
// the surface when the pointer goes onto it (SPEC §9.4).
Hover Flag
// KeepCursor leaves the cursor where it was (C=1). Otherwise the host
// moves it to the start of the line below the placement, as text would.
KeepCursor bool
}
Placement is where and how a surface is shown (SPEC §5.2).
func PlacementOf ¶
Placement reads a place command (SPEC §5.2), as a host or a relay does: Rows 0 for r=auto or none, and the window as the command gives it, its defaults filled in: w reaches the surface's right edge, and h its bottom, which with Rows 0 is the host's to find (H 0). A command out of range is an *Error with Code EINVAL, as a host answers it.
type Platform ¶
type Platform struct {
// Mod is "ctrl" or "super" (SPEC §10.4); "" is ctrl.
Mod string
// Edit is the host's edit shortcuts, from each action to its keys
// (SPEC §10.2); nil is DefaultEdit(Mod).
Edit map[string][]string
}
Platform is how a host reads bindings (SDK.md §3.10): the modifier mod stands for, and its edit shortcuts. The zero Platform is ctrl with the default edit shortcuts.
func PlatformOf ¶
PlatformOf is the Platform of a host's capabilities: its Mod and Edit, the zero Platform's where it reports none.
func (Platform) ReadKey ¶
ReadKey reads a key's name as the Platform reads it (SPEC §10.4): as ParseKey does, with mod standing for the Platform's, so that where Mod is ctrl "mod+a" and "ctrl+a" read alike, and where it is super they are two keys. A menu's items (MenuItem.Key, MenuLevelOf) compare with the keys typed this way. ok is false for a name that does not parse, "mod+ctrl+a" among them.
type QueryOption ¶
type QueryOption interface {
// contains filtered or unexported methods
}
QueryOption is an option of Query: Late.
func Late ¶
func Late() QueryOption
Late asks for a late answer (late=1, SPEC §4). What stands between the program and the terminal and has no host yet, such as a multiplexer running the program's pane with no terminal attached, may hold the query, and answer it once there is a host, whenever that is. A program that asks takes that answer as detection finding a host: it can start using hotty after it fell back to cells. A host answers at once, as it answers any query.
A program that asked, and will no longer take the answer, such as one about to exit, sends WithdrawLate, or the answer would reach whatever reads the terminal after it.
type Reply ¶
type Reply struct {
OK bool
// Re is the action answered: "doc", "place", "q", ….
Re string
// N is the request number, if the command had one (option N).
N int
// Surface is the surface the command named, if any.
Surface string
// Cols and Rows are a placement's size, in a reply to place: with
// Placement.Rows 0, the rows the host chose.
Cols, Rows int
// Op is the index of the op at fault, from 0, in an error answering a
// delta (the control key i, SPEC §6.1); HasOp says whether the reply
// has one, since 0 is an index like any other.
Op int
HasOp bool
// Code and Detail say what went wrong, when not OK: empty when the
// error's body does not decode.
Code, Detail string
// Caps are the capabilities an ok reply to a query carries: nil when
// it carries none, or they do not decode.
Caps *Caps
// Message is the reply as it came.
Message Message
}
Reply is the host's answer to a command (SPEC §3.6).
type ReplyOption ¶
type ReplyOption struct {
// contains filtered or unexported fields
}
ReplyOption sets the reply a command asks for (SPEC §3.5): every command takes one, Doc as a DocOption. N and Q make them, in either order.
func N ¶
func N(n int) ReplyOption
N numbers the command and asks for its reply whatever the outcome (ReplyAlways): the reply echoes n, so the program can tell which command it answers. A Q given with it asks for less.
func Q ¶
func Q(q Quiet) ReplyOption
Q sets the command's quiet level. It wins over the level N implies, whichever comes first.
type Result ¶
type Result int
Result is what a Decoder made of one sequence.
const ( // NotHotty: the sequence is not hotty's, and the caller handles it. NotHotty Result = iota // Partial: a chunk of a message that is not complete yet (SPEC §3.4). Partial // Complete: the message is complete. Complete // Invalid: the sequence was malformed, or aborted a chunked message, // and is dropped (SPEC §3.7). Invalid )
The results of Decoder.Feed.
type Scanner ¶
type Scanner struct {
// DA1 makes the Scanner cut out answers to Primary Device Attributes
// as SegmentDA1, for a program that reads them itself (SDK.md §4.1).
// Without it they pass.
DA1 bool
// Invalid counts the hotty sequences dropped so far.
Invalid int
// contains filtered or unexported fields
}
Scanner cuts hotty sequences out of a byte stream, however the reads split it (SDK.md §3.7): a terminal's input, read raw, or a program's output, for a relay. Everything else goes out as it came, in order, in the Feed that brought it; the Scanner holds only what may still become a segment of its own, the start of ESC ] 7279 ; (or of a DA1 answer, with DA1) and a hotty sequence in progress. So the segments do not depend on how the stream was split, and a key is never kept waiting.
An ESC inside a hotty sequence that does not begin its ST ends the sequence unfinished: it is dropped as malformed, and the ESC begins what comes next. A sequence longer than 64 KiB is dropped up to its terminator.
Its zero value is ready to use. It is not safe for concurrent use.
func (*Scanner) Feed ¶
Feed takes the next bytes of the stream and returns its segments, in order. Adjacent SegmentPass segments are one.
func (*Scanner) Flush ¶
Flush ends the stream: what is held goes out as SegmentPass, except a hotty sequence in progress, which is dropped as malformed.
A program reading keys flushes a lone ESC that a read ended with, as the Escape key (SDK.md §4.1), at once or when no more bytes follow soon:
segs := s.Feed(buf[:n])
if h := s.Holding(); len(h) == 1 && !s.InSequence() {
segs = append(segs, s.Flush()...) // a lone ESC
}
func (*Scanner) Holding ¶
Holding returns the bytes the Scanner holds for the next Feed: the start of a segment, or a hotty sequence in progress. They are good until the next Feed or Flush.
func (*Scanner) InSequence ¶
InSequence reports whether a hotty sequence is in progress, or one too long is being dropped: the next Feed goes on with it, and Flush would drop it. Otherwise what Holding returns is the start of a segment, which a program reading keys may flush after a moment, as typing (an ESC, then ], is Alt+]).
type Segment ¶
type Segment struct {
Kind SegmentKind
// Data is the segment's bytes. It may share memory with the bytes
// given to Feed, so it is good until the caller changes those: a
// caller that reuses its read buffer copies what it keeps.
Data []byte
}
Segment is a piece of a scanned stream.
type SegmentKind ¶
type SegmentKind uint8
SegmentKind is what a Segment holds.
const ( // SegmentPass: bytes that are not hotty's, unchanged: keys, mouse // reports, text, other escape sequences, other OSCs. SegmentPass SegmentKind = iota // SegmentOSC: one complete hotty sequence, from ESC ] 7279 ; to its // terminator (ST or BEL), ready for a Decoder. SegmentOSC // SegmentDA1: an answer to Primary Device Attributes, CSI ? <digits // and ;> c, from a Scanner made to look for them (Scanner.DA1). SegmentDA1 )
The kinds of Segment.
func (SegmentKind) String ¶
func (k SegmentKind) String() string
String names the kind: "pass", "osc" or "da1".
type Size ¶
Size is a size in CSS pixels: a cell's, in the capabilities (SPEC §4).
type TouchArea ¶
type TouchArea struct {
C int `msg:"c"`
R int `msg:"r"`
W int `msg:"w"`
H int `msg:"h"`
Drag string `msg:"drag"`
}
TouchArea is cells of the screen where a finger drags as the mouse does (Touch, SPEC §9.6). C and R are the first column and row it covers, counted from 0 at the screen's top left (a mouse report counts from 1), and W and H the columns and rows it spans, at least 1 each. Drag is the way a finger drags in it: "x" across, "y" up and down, "xy" either. A horizontal slider's is "x".
func TouchOf ¶
TouchOf reads an a=touch command's areas (SPEC §9.6), as a host or a relay does: nil, and no error, for a command with no body or no areas, which leaves none. A body that is no map of areas, an area without a field or with one of another type, C or R under 0, W or H under 1, a Drag other than "x", "y" and "xy", or more than TouchMax areas, is an *Error with Code EINVAL.
type View ¶
type View struct {
// Areas are the elements in view by id, each with its whole area,
// however little of it is shown. One whose area lacks a field is left
// out.
Areas map[string]Area
// AtEnd is true when the document's root is scrolled as far down as it
// goes, as a root that does not scroll down always is.
AtEnd bool
}
View is what a view event reports (SPEC §9.5): every element with data-on~=view and an id that is in view, not only what changed.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package blocks draws bars in terminal cells with the block elements (U+2581–U+2588): a column's height in eighths of a row, as a bar chart or a histogram in text has it.
|
Package blocks draws bars in terminal cells with the block elements (U+2581–U+2588): a column's height in eighths of a row, as a bar chart or a histogram in text has it. |
|
Package braille draws in terminal cells with the Unicode braille patterns (U+2800–U+28FF): each cell is two dots across and four down, so a line chart in text has four times the rows and twice the columns of its cells.
|
Package braille draws in terminal cells with the Unicode braille patterns (U+2800–U+28FF): each cell is two dots across and four down, so a line chart in text has four times the rows and twice the columns of its cells. |
|
Package chart draws line charts for hotty surfaces, as inline SVG that a program changes with deltas as values arrive, and in cells for a terminal that is not a host (Spark).
|
Package chart draws line charts for hotty surfaces, as inline SVG that a program changes with deltas as values arrive, and in cells for a terminal that is not a host (Spark). |
|
Package form is a form for a hotty surface: a spec, the document it makes (real HTML controls, with ids a program can focus and change with deltas), and what a submit event brings back, read into typed answers.
|
Package form is a form for a hotty surface: a spec, the document it makes (real HTML controls, with ids a program can focus and change with deltas), and what a submit event brings back, read into typed answers. |
|
hottyedit
module
|
|
|
hottytea
module
|
|
|
hottyterm
module
|
|
|
hottytest
module
|
|
|
hottyvt
module
|
|
|
internal
|
|
|
docgen
command
Command docgen writes hotty-go's API reference from the code: a page per public package in docs/api, an index of them, and the tables of packages and examples in README.md, between its docgen markers.
|
Command docgen writes hotty-go's API reference from the code: a page per public package in docs/api, an index of them, and the tables of packages and examples in README.md, between its docgen markers. |
|
Package series reads numbers from a stream of text, as plotting tools such as youplot and asciigraph do: lines of numbers separated by spaces, tabs or commas, a column a series, and a first line with no numbers naming them.
|
Package series reads numbers from a stream of text, as plotting tools such as youplot and asciigraph do: lines of numbers separated by spaces, tabs or commas, a column a series, and a first line with no numbers naming them. |