Documentation
¶
Overview ¶
Package vt is a terminal emulator. It reads the bytes a program writes to a terminal and keeps the screen they draw: the cells, their colours and attributes, the cursor, the scrollback and the modes.
New returns an emulator. Write feeds it what the program printed, and CellAt, String and Render read the screen. Read returns the replies the emulator sends the program, such as the answer to a cursor position query. Screen is the interface with those methods. Terminal is the full interface tuios uses, with the scrollback, the modes, key and mouse encoding, graphics and the state a snapshot carries. Callbacks reports what the program asks of the host, such as a new title.
The default build is pure Go and returns an *Emulator. With the ghostty build tag, New returns an emulator backed by libghostty-vt through cgo.
The sub-package snapshot captures an emulator's state and brings another emulator to the same state, and vtgen generates terminal input for fuzzing an emulator.
Example ¶
A program's output goes in, and the screen comes out.
package main
import (
"fmt"
"tuios.dev/vt"
)
func main() {
term := vt.New(40, 5)
defer term.Close()
_, _ = term.Write([]byte("hello \x1b[1mworld\x1b[0m\r\n$ "))
fmt.Println(term.String())
fmt.Println(term.CellAt(6, 0).Content) // "w", drawn bold
fmt.Println(term.CursorPosition()) // column 2, row 1
}
Output:
Index ¶
- Constants
- func BlankSixelCell(c *uv.Cell) bool
- func BuildKittyResponse(ok bool, imageID uint32, message string) []byte
- func CellText(content string) string
- func ClipHistoryRow(line uv.Line, width int) uv.Line
- func DecodeKittyPayload(payload []byte) ([]byte, error)
- func DeviceAttributes(sixel bool) []int
- func EncodeKeyCSIu(key KeyPressEvent, flags int) string
- func EncodeKeyReleaseCSIu(key KeyPressEvent, flags int) string
- func EncodeModifyOtherKeys(key KeyPressEvent, level int) string
- func EncodePaneKey(key KeyPressEvent, kittyFlags, modifyOtherKeys int) string
- func EncodeSixel(img *SixelImage, src image.Rectangle, dstW, dstH int) []byte
- func IsKittyAnimationAction(a KittyGraphicsAction) bool
- func IsKittyEchoedResponse(cmd *KittyCommand) bool
- func IsKittyPlaceholder(content string) bool
- func IsKittyResponsePayload(payload string) bool
- func IsSixelMarker(content string) bool
- func KittyInTempDir(path string) bool
- func KittyMediumIsFrame(cmd *KittyCommand, info os.FileInfo) bool
- func KittyPayloadErrorResponse(cmd *KittyCommand) []byte
- func KittyPlaceholderImageID(content string, fg color.Color) (uint32, bool)
- func KittySensitivePath(path string) bool
- func KittyTempDirs() []string
- func LinkParams(s string) string
- func LinkURI(s string) string
- func LinkURIDecodedLen(s string) int
- func ParseSixelMarker(content string) (id uint32, row, col int, ok bool)
- func SanitizePaste(text string) string
- func SetBuildVersion(v string)
- func SetDebugLogger(l Logger)
- func SetHostHyperlink(url, params string) string
- func SetTerminalName(name string)
- func SixelCells(cmd *SixelCommand, cellW, cellH int) (rows, cols int)
- func SixelMarker(id uint32, row, col int) string
- func StripControls(s string) string
- func StripKittyPlaceholders(s string) string
- func StripSixelMarkers(s string) string
- func XTVersionName() string
- type ApcHandler
- type Callbacks
- type CcHandler
- type CellRun
- type CharSet
- type CsiHandler
- type Cursor
- type CursorStyle
- type DcsHandler
- type Emulator
- func (e *Emulator) ANSIModes() map[int]bool
- func (e *Emulator) ActiveScreenIsAlt() bool
- func (e *Emulator) AppendScrollbackText(buf *strings.Builder)
- func (e *Emulator) ApplicationCursorKeys() bool
- func (e *Emulator) AtGround() bool
- func (e *Emulator) BackgroundColor() color.Color
- func (e *Emulator) Blur()
- func (e *Emulator) Bounds() uv.Rectangle
- func (e *Emulator) BracketedPasteEnabled() bool
- func (e *Emulator) CellAt(x, y int) *uv.Cell
- func (e *Emulator) CellSize() (width, height int)
- func (e *Emulator) Charsets() (ids [4]byte, gl, gr int)
- func (e *Emulator) ClearScrollback()
- func (e *Emulator) Close() error
- func (e *Emulator) CopyScrollback(from, end int) *ScrollbackCopy
- func (e *Emulator) CursorColor() color.Color
- func (e *Emulator) CursorPen() (uv.Style, uv.Link)
- func (e *Emulator) CursorPendingWrap() bool
- func (e *Emulator) CursorPosition() uv.Position
- func (e *Emulator) CursorProtected() bool
- func (e *Emulator) CursorStyle() (CursorStyle, bool)
- func (e *Emulator) DisableKittyKeyboardProtocol()
- func (e *Emulator) DiscardScrollback()
- func (e *Emulator) EncodeMouseEvent(m Mouse) string
- func (e *Emulator) EncodeMouseEventAt(m Mouse, at MousePixel) string
- func (e *Emulator) Focus()
- func (e *Emulator) FocusReportingEnabled() bool
- func (e *Emulator) ForegroundColor() color.Color
- func (e *Emulator) GetCallbacks() Callbacks
- func (e *Emulator) GetModes() map[int]bool
- func (e *Emulator) GuestColors() GuestColors
- func (e *Emulator) GuestCursorColor() color.Color
- func (e *Emulator) HasAllMotionMode() bool
- func (e *Emulator) HasCellMotionMode() bool
- func (e *Emulator) HasMouseMode() bool
- func (e *Emulator) HasPixelMouseMode() bool
- func (e *Emulator) Height() int
- func (e *Emulator) IndexedColor(i int) color.Color
- func (e *Emulator) InputPipe() io.Writer
- func (e *Emulator) IsAltScreen() bool
- func (e *Emulator) IsCursorHidden() bool
- func (e *Emulator) IsSyncActive() bool
- func (e *Emulator) KittyAltState() *KittyState
- func (e *Emulator) KittyGuestImagesState() *KittyGuestImagesState
- func (e *Emulator) KittyKeyboardFlags() int
- func (e *Emulator) KittyKeyboardMainStack() []int
- func (e *Emulator) KittyKeyboardStack() []int
- func (e *Emulator) KittyKeyboardUnavailable() bool
- func (e *Emulator) KittyMainState() *KittyState
- func (e *Emulator) KittyState() *KittyState
- func (e *Emulator) LastPrinted() string
- func (e *Emulator) MainCellAt(x, y int) *uv.Cell
- func (e *Emulator) MainRowTail(y int) uv.Line
- func (e *Emulator) ModifyOtherKeys() int
- func (e *Emulator) PaletteColor(i int) color.Color
- func (e *Emulator) PendingInput() []byte
- func (e *Emulator) ProtectedCells(main bool) []CellRun
- func (e *Emulator) PushScrollbackLine(line uv.Line)
- func (e *Emulator) Read(p []byte) (n int, err error)
- func (h *Emulator) RegisterApcHandler(handler ApcHandler)
- func (h *Emulator) RegisterCsiHandler(cmd int, handler CsiHandler)
- func (h *Emulator) RegisterDcsHandler(cmd int, handler DcsHandler)
- func (h *Emulator) RegisterEscHandler(cmd int, handler EscHandler)
- func (h *Emulator) RegisterOscHandler(cmd int, handler OscHandler)
- func (h *Emulator) RegisterPmHandler(handler PmHandler)
- func (h *Emulator) RegisterSosHandler(handler SosHandler)
- func (e *Emulator) ReleaseAltScreen()
- func (e *Emulator) ReleaseReflowScratch()
- func (e *Emulator) Render() string
- func (e *Emulator) ReserveImageSpace(rows, cols int)
- func (e *Emulator) ResetScrollRegion()
- func (e *Emulator) Resize(width int, height int)
- func (e *Emulator) RestoreANSIModes(modes map[int]bool)
- func (e *Emulator) RestoreAltScreenMode(enabled bool)
- func (e *Emulator) RestoreCharsets(ids [4]byte, gl, gr int)
- func (e *Emulator) RestoreCursorPen(pen uv.Style, link uv.Link)
- func (e *Emulator) RestoreCursorPendingWrap(pending bool)
- func (e *Emulator) RestoreCursorPosition(x, y int)
- func (e *Emulator) RestoreCursorProtected(on bool)
- func (e *Emulator) RestoreCursorStyle(style CursorStyle, steady bool)
- func (e *Emulator) RestoreGuestColors(c GuestColors)
- func (e *Emulator) RestoreKittyGuestImages(s *KittyGuestImagesState)
- func (e *Emulator) RestoreKittyKeyboardMainStack(stack []int)
- func (e *Emulator) RestoreKittyKeyboardState(stack []int)
- func (e *Emulator) RestoreLastPrinted(cluster string)
- func (e *Emulator) RestoreModes(modes map[int]bool)
- func (e *Emulator) RestoreModifyOtherKeys(level int)
- func (e *Emulator) RestorePads(screen, history []bool)
- func (e *Emulator) RestorePendingInput(p []byte)
- func (e *Emulator) RestoreProtectedCells(main bool, runs []CellRun)
- func (e *Emulator) RestoreSavedCursor(main bool, c SavedCursor)
- func (e *Emulator) RestoreScrollRegion(r uv.Rectangle)
- func (e *Emulator) RestoreSoftWraps(screen, history []bool)
- func (e *Emulator) RestoreTabStops(cols []int)
- func (e *Emulator) RestoreTitles(t Titles)
- func (e *Emulator) RowPadded(y int) bool
- func (e *Emulator) RowSoftWrapped(y int) (wrapped, known bool)
- func (e *Emulator) SavedCursor(main bool) SavedCursor
- func (e *Emulator) ScrollRegion() uv.Rectangle
- func (e *Emulator) Scrollback() *Scrollback
- func (e *Emulator) ScrollbackGeneration() uint64
- func (e *Emulator) ScrollbackLen() int
- func (e *Emulator) ScrollbackLine(index int) uv.Line
- func (e *Emulator) ScrollbackPadded(index int) bool
- func (e *Emulator) ScrollbackRows(from, end int, fn func(index int, line uv.Line) bool)
- func (e *Emulator) ScrollbackSoftWrapped(index int) (wrapped, known bool)
- func (e *Emulator) ScrollbackText(from, end int, fn func(index, width int, cells []TextCell) bool)
- func (e *Emulator) SemanticMarkers() *SemanticMarkerList
- func (e *Emulator) SendMouse(m Mouse)
- func (e *Emulator) SendMouseAt(m Mouse, at MousePixel)
- func (e *Emulator) SetBackgroundColor(c color.Color)
- func (e *Emulator) SetCallbacks(cb Callbacks)
- func (e *Emulator) SetCell(x, y int, c *uv.Cell)
- func (e *Emulator) SetCellSize(width, height int)
- func (e *Emulator) SetCursorColor(c color.Color)
- func (e *Emulator) SetDefaultBackgroundColor(c color.Color)
- func (e *Emulator) SetDefaultCursorColor(c color.Color)
- func (e *Emulator) SetDefaultForegroundColor(c color.Color)
- func (e *Emulator) SetForegroundColor(c color.Color)
- func (e *Emulator) SetIndexedColor(i int, c color.Color)
- func (e *Emulator) SetKittyFilesElsewhere(on bool)
- func (e *Emulator) SetKittyHeaderOnly(on bool)
- func (e *Emulator) SetKittyImageIDTranslator(fn KittyImageIDTranslator)
- func (e *Emulator) SetKittyPassthroughFunc(fn func(cmd *KittyCommand, rawData []byte))
- func (e *Emulator) SetKittyPlaceholderMode(m KittyPlaceholderMode)
- func (e *Emulator) SetKittyUploadAnswers(on bool)
- func (e *Emulator) SetLogger(l Logger)
- func (e *Emulator) SetMainCell(x, y int, c *uv.Cell)
- func (e *Emulator) SetReflowFunc(fn func(remap func(absLine int) int))
- func (e *Emulator) SetReportColors(fg, bg color.Color)
- func (e *Emulator) SetReportPalette(pal [16]color.Color)
- func (e *Emulator) SetScreenClearFunc(f func())
- func (e *Emulator) SetScrollbackMaxLines(maxLines int)
- func (e *Emulator) SetSixelAdvertised(fn func() bool)
- func (e *Emulator) SetSixelPassthroughFunc(fn SixelPassthroughFunc)
- func (e *Emulator) SetTextSizingFunc(fn func(rawOSC []byte, cursorX, cursorY, scale, textLen int))
- func (e *Emulator) SetThemeColors(fg, bg, cur color.Color, ansiPalette [16]color.Color)
- func (e *Emulator) String() string
- func (e *Emulator) SupportsMotionEvents() bool
- func (e *Emulator) SyncUpdate() (open bool, serial uint64)
- func (e *Emulator) TabStops() []int
- func (e *Emulator) TailText(n int) []string
- func (e *Emulator) TakeResponses() []byte
- func (e *Emulator) Titles() Titles
- func (e *Emulator) Width() int
- func (e *Emulator) WidthMethod() uv.WidthMethod
- func (e *Emulator) Write(p []byte) (n int, err error)
- func (e *Emulator) WriteResponse(data []byte)
- func (e *Emulator) WriteString(s string) (n int, err error)
- type EscHandler
- type GuestColors
- type KeyMod
- type KeyPressEvent
- type KittyCommand
- type KittyDeleteTarget
- type KittyGraphicsAction
- type KittyGraphicsCompression
- type KittyGraphicsFormat
- type KittyGraphicsMedium
- type KittyGuestImages
- type KittyGuestImagesState
- type KittyImageIDTranslator
- type KittyPlaceholderMode
- type KittyState
- type Logger
- type Mouse
- type MouseButton
- type MouseClick
- type MouseMotion
- type MousePixel
- type MouseRelease
- type MouseWheel
- type OscHandler
- type PmHandler
- type ProgressState
- type SavedCursor
- type Screen
- type Scrollback
- func (sb *Scrollback) Clear()
- func (sb *Scrollback) Discard()
- func (sb *Scrollback) Len() int
- func (sb *Scrollback) Line(index int) uv.Line
- func (sb *Scrollback) LineWrapped(index int) bool
- func (sb *Scrollback) Lines() []uv.Line
- func (sb *Scrollback) MaxLines() int
- func (sb *Scrollback) PushBlankLine(width int)
- func (sb *Scrollback) PushLine(line uv.Line)
- func (sb *Scrollback) SetMaxLines(maxLines int)
- func (sb *Scrollback) SetOnTrim(fn func(int))
- type ScrollbackCopy
- func (c *ScrollbackCopy) Len() int
- func (c *ScrollbackCopy) Padded(index int) bool
- func (c *ScrollbackCopy) Rows(from, end int, fn func(index int, line uv.Line) bool)
- func (c *ScrollbackCopy) Text(from, end int, fn func(index, width int, cells []TextCell) bool)
- func (c *ScrollbackCopy) Wrapped(index int) bool
- type SemanticMarker
- type SemanticMarkerList
- func (l *SemanticMarkerList) Add(m SemanticMarker)
- func (l *SemanticMarkerList) AdjustForScrollbackTrim(linesRemoved int)
- func (l *SemanticMarkerList) Clear()
- func (l *SemanticMarkerList) Last(t SemanticMarkerType) *SemanticMarker
- func (l *SemanticMarkerList) Len() int
- func (l *SemanticMarkerList) Markers() []SemanticMarker
- func (l *SemanticMarkerList) RemoveOnScreen(scrollbackLen int)
- func (l *SemanticMarkerList) Trimmed() int
- type SemanticMarkerType
- type SixelAction
- type SixelCommand
- type SixelImage
- type SixelPassthroughFunc
- type SosHandler
- type Terminal
- type TextCell
- type TitleEntry
- type Titles
Examples ¶
Constants ¶
const ( FallbackCellWidth = 10 FallbackCellHeight = 20 )
The cell size in pixels an emulator assumes until the host sets one with SetCellSize.
A program reads the pane's size in pixels from XTWINOPS 14 and 16 and from the mode 2048 resize report, and an SGR-pixel mouse report (mode 1016) is in the same pixels. A program that divides by the pixel size quits on a zero, so a pane no host has measured still gets a cell size. A host that sets the kernel's pixel size (TIOCGWINSZ) for an unmeasured pane uses the same one, so the sizes agree.
const ( ModShift = uv.ModShift ModAlt = uv.ModAlt ModCtrl = uv.ModCtrl ModMeta = uv.ModMeta ModHyper = uv.ModHyper ModSuper = uv.ModSuper ModCapsLock = uv.ModCapsLock ModNumLock = uv.ModNumLock )
Modifier keys.
const ( KeyExtended = uv.KeyExtended KeyUp = uv.KeyUp KeyDown = uv.KeyDown KeyRight = uv.KeyRight KeyLeft = uv.KeyLeft KeyBegin = uv.KeyBegin KeyFind = uv.KeyFind KeyInsert = uv.KeyInsert KeyDelete = uv.KeyDelete KeySelect = uv.KeySelect KeyPgUp = uv.KeyPgUp KeyPgDown = uv.KeyPgDown KeyHome = uv.KeyHome KeyEnd = uv.KeyEnd KeyKpEnter = uv.KeyKpEnter KeyKpEqual = uv.KeyKpEqual KeyKpMultiply = uv.KeyKpMultiply KeyKpPlus = uv.KeyKpPlus KeyKpComma = uv.KeyKpComma KeyKpMinus = uv.KeyKpMinus KeyKpDecimal = uv.KeyKpDecimal KeyKpDivide = uv.KeyKpDivide KeyKp0 = uv.KeyKp0 KeyKp1 = uv.KeyKp1 KeyKp2 = uv.KeyKp2 KeyKp3 = uv.KeyKp3 KeyKp4 = uv.KeyKp4 KeyKp5 = uv.KeyKp5 KeyKp6 = uv.KeyKp6 KeyKp7 = uv.KeyKp7 KeyKp8 = uv.KeyKp8 KeyKp9 = uv.KeyKp9 KeyKpSep = uv.KeyKpSep KeyKpUp = uv.KeyKpUp KeyKpDown = uv.KeyKpDown KeyKpLeft = uv.KeyKpLeft KeyKpRight = uv.KeyKpRight KeyKpPgUp = uv.KeyKpPgUp KeyKpPgDown = uv.KeyKpPgDown KeyKpHome = uv.KeyKpHome KeyKpEnd = uv.KeyKpEnd KeyKpInsert = uv.KeyKpInsert KeyKpDelete = uv.KeyKpDelete KeyKpBegin = uv.KeyKpBegin KeyF1 = uv.KeyF1 KeyF2 = uv.KeyF2 KeyF3 = uv.KeyF3 KeyF4 = uv.KeyF4 KeyF5 = uv.KeyF5 KeyF6 = uv.KeyF6 KeyF7 = uv.KeyF7 KeyF8 = uv.KeyF8 KeyF9 = uv.KeyF9 KeyF10 = uv.KeyF10 KeyF11 = uv.KeyF11 KeyF12 = uv.KeyF12 KeyF13 = uv.KeyF13 KeyF14 = uv.KeyF14 KeyF15 = uv.KeyF15 KeyF16 = uv.KeyF16 KeyF17 = uv.KeyF17 KeyF18 = uv.KeyF18 KeyF19 = uv.KeyF19 KeyF20 = uv.KeyF20 KeyF21 = uv.KeyF21 KeyF22 = uv.KeyF22 KeyF23 = uv.KeyF23 KeyF24 = uv.KeyF24 KeyF25 = uv.KeyF25 KeyF26 = uv.KeyF26 KeyF27 = uv.KeyF27 KeyF28 = uv.KeyF28 KeyF29 = uv.KeyF29 KeyF30 = uv.KeyF30 KeyF31 = uv.KeyF31 KeyF32 = uv.KeyF32 KeyF33 = uv.KeyF33 KeyF34 = uv.KeyF34 KeyF35 = uv.KeyF35 KeyF36 = uv.KeyF36 KeyF37 = uv.KeyF37 KeyF38 = uv.KeyF38 KeyF39 = uv.KeyF39 KeyF40 = uv.KeyF40 KeyF41 = uv.KeyF41 KeyF42 = uv.KeyF42 KeyF43 = uv.KeyF43 KeyF44 = uv.KeyF44 KeyF45 = uv.KeyF45 KeyF46 = uv.KeyF46 KeyF47 = uv.KeyF47 KeyF48 = uv.KeyF48 KeyF49 = uv.KeyF49 KeyF50 = uv.KeyF50 KeyF51 = uv.KeyF51 KeyF52 = uv.KeyF52 KeyF53 = uv.KeyF53 KeyF54 = uv.KeyF54 KeyF55 = uv.KeyF55 KeyF56 = uv.KeyF56 KeyF57 = uv.KeyF57 KeyF58 = uv.KeyF58 KeyF59 = uv.KeyF59 KeyF60 = uv.KeyF60 KeyF61 = uv.KeyF61 KeyF62 = uv.KeyF62 KeyF63 = uv.KeyF63 KeyCapsLock = uv.KeyCapsLock KeyScrollLock = uv.KeyScrollLock KeyNumLock = uv.KeyNumLock KeyPrintScreen = uv.KeyPrintScreen KeyPause = uv.KeyPause KeyMenu = uv.KeyMenu KeyMediaPlay = uv.KeyMediaPlay KeyMediaPause = uv.KeyMediaPause KeyMediaPlayPause = uv.KeyMediaPlayPause KeyMediaReverse = uv.KeyMediaReverse KeyMediaStop = uv.KeyMediaStop KeyMediaFastForward = uv.KeyMediaFastForward KeyMediaRewind = uv.KeyMediaRewind KeyMediaNext = uv.KeyMediaNext KeyMediaPrev = uv.KeyMediaPrev KeyMediaRecord = uv.KeyMediaRecord KeyLowerVol = uv.KeyLowerVol KeyRaiseVol = uv.KeyRaiseVol KeyMute = uv.KeyMute KeyLeftShift = uv.KeyLeftShift KeyLeftAlt = uv.KeyLeftAlt KeyLeftCtrl = uv.KeyLeftCtrl KeyLeftSuper = uv.KeyLeftSuper KeyLeftHyper = uv.KeyLeftHyper KeyLeftMeta = uv.KeyLeftMeta KeyRightShift = uv.KeyRightShift KeyRightAlt = uv.KeyRightAlt KeyRightCtrl = uv.KeyRightCtrl KeyRightSuper = uv.KeyRightSuper KeyRightHyper = uv.KeyRightHyper KeyRightMeta = uv.KeyRightMeta KeyIsoLevel3Shift = uv.KeyIsoLevel3Shift KeyIsoLevel5Shift = uv.KeyIsoLevel5Shift KeyBackspace = uv.KeyBackspace KeyTab = uv.KeyTab KeyEnter = uv.KeyEnter KeyReturn = uv.KeyReturn KeyEscape = uv.KeyEscape KeyEsc = uv.KeyEsc KeySpace = uv.KeySpace )
Key codes.
const ( MouseNone = uv.MouseNone MouseLeft = uv.MouseLeft MouseMiddle = uv.MouseMiddle MouseRight = uv.MouseRight MouseWheelUp = uv.MouseWheelUp MouseWheelDown = uv.MouseWheelDown MouseWheelLeft = uv.MouseWheelLeft MouseWheelRight = uv.MouseWheelRight MouseBackward = uv.MouseBackward MouseForward = uv.MouseForward MouseButton10 = uv.MouseButton10 MouseButton11 = uv.MouseButton11 )
Mouse event buttons
This is based on X11 mouse button codes.
1 = left button 2 = middle button (pressing the scroll wheel) 3 = right button 4 = turn scroll wheel up 5 = turn scroll wheel down 6 = push scroll wheel left 7 = push scroll wheel right 8 = 4th button (aka browser backward button) 9 = 5th button (aka browser forward button) 10 11
Other buttons are not supported.
const ( // SixelMaxDimension bounds either side of a decoded image in pixels. It // is larger than any screen, so a real picture is never cut by it. SixelMaxDimension = 8192 // SixelMaxPixels bounds the area, at two bytes a pixel: 32 MiB. SixelMaxPixels = 16 << 20 )
Sixel limits. A guest controls every one of these numbers, so each is bounded before anything is allocated.
const Backend = "pure-Go"
Backend names the emulator implementation compiled into this binary. Both builds install under the same `tuios` name, so the binary has to be able to say which one it is; deriving it from the build tag keeps it honest, where a string injected at link time can be forgotten or set wrong.
const DefaultScrollbackSize = 10000
DefaultScrollbackSize is the default number of lines to keep in the scrollback buffer.
const DefaultTerminalName = "vt"
DefaultTerminalName is the program name XTVERSION reports until SetTerminalName sets another.
const KittyAnimationRefusal = "ENOTSUPPORTED:host terminal does not support animation"
KittyAnimationRefusal is the answer to a frame edit the host cannot make. A guest that gets it falls back to sending whole frames.
const KittyTempMarker = "tty-graphics-protocol"
KittyTempMarker is the text the kitty spec asks for in a t=t file name. It is for a host that reads such files itself.
const MaxHostLinkURI = 2083
MaxHostLinkURI is the longest address written to the host in an OSC 8, in bytes as written. It is VTE's limit, and the one the scrollback ring keeps links to. A longer link is drawn as plain text: the frame writes the address again each time the link starts on a row, and an OSC payload can be 4 MiB.
const MaxPendingInput = maxSequenceData + 4096
MaxPendingInput bounds PendingInput: the longest payload the emulator keeps of one sequence, and room for its introducer and parameters. The parser cuts a longer payload at the same length, so input cut there replays to the same state.
const SixelMarkerLead = "\xf4\x8e\xbb\xad"
SixelMarkerLead is the UTF-8 encoding of sixelMarkerRune, for a byte compare on the hot path.
const SixelMaxCells = sixelDigits - 1
SixelMaxCells bounds an image's rows and columns: a marker states them in one mark each.
const SixelMaxID = sixelDigits*sixelDigits - 1
SixelMaxID is the largest image id a marker can carry. Id 0 names no image: the cells are reserved and the compositor draws them blank.
const SixelMaxRegisters = 256
SixelMaxRegisters is the number of colour registers a pane is told it has (XTSMGRAPHICS), and the most a decoded image may use.
const SyncMaxHold = syncMaxHold
SyncMaxHold is how long a synchronized update is honored. It is for a host that holds a program's output during an update, as the tuios kitty passthrough holds a guest's graphics, so it waits no longer than this.
Variables ¶
This section is empty.
Functions ¶
func BlankSixelCell ¶
BlankSixelCell turns an image cell into a blank that keeps its background. It reports whether the cell was one. It is for a host that keeps or copies cells without the image, such as a saved history.
func BuildKittyResponse ¶
BuildKittyResponse returns a kitty graphics reply for imageID: OK when ok is true, otherwise message, or ENOENT when message is empty. An imageID of 0 leaves the i key out.
func CellText ¶
CellText is a cell's content as text: a space for a sixel image cell, the content otherwise. Text that leaves the grid (a capture, a copy, a search, a saved history) reads cells through it, so no marker escapes as text.
func ClipHistoryRow ¶
ClipHistoryRow is a scrollback line as it may be drawn in width columns.
History keeps the width it was written at, deliberately: a resize reflows only the screen and the history lines it takes back (reflow.go), so that a resize costs what the screen holds and not what the history holds. A pane that narrowed since can then hold a double-width rune whose lead is in its last column. Drawn whole, that rune makes the row one column wider than the pane, and the compositor puts the extra column over the pane next door.
The fix belongs where the row is drawn and not in the history. Blanking the rune in the stored line, which a resize once did, lost it for good: a pane that narrowed and widened again showed a space where the character was, and so did every capture of it. So the stored line keeps the rune, and a reader that puts a history row into a grid of the pane's width passes it through here first. The screenshot grid is one, and the client's pane renderer is another. The renderer needs it too: the frame does cut an overlong row at the pane's border, but that cut drops the whole wide cell, so the last column lost its background, the copy cursor and any selection. The cut cell becomes a blank that keeps its style, so a run of coloured background does not gain a notch.
The line is returned as it is when nothing straddles the edge. Otherwise it is a copy, because the line can be the scrollback cache's own slice.
func DecodeKittyPayload ¶
DecodeKittyPayload decodes a kitty graphics payload, padded or not.
The protocol says the payload is base64 and leaves padding to the sender. kitten icat sends none: its Go encoder is RawStdEncoding, so the final chunk of a stream, and any file path whose length is not a multiple of three, has no '=' at the end. Only a chunk that is not the last has to be a multiple of four characters. Other senders (chafa, timg, mpv) pad. Both are accepted, and so is a payload built by joining padded groups, which is what a sender that pads every chunk produces if two chunks are ever sent as one.
Each run of '=' ends one group. The text before it is decoded without padding, which accepts a group with its padding stripped and rejects one that was cut short (a single character left over), and the rest of the payload is decoded the same way.
func DeviceAttributes ¶
DeviceAttributes is the DA1 attribute list both backends answer with: a VT220-class terminal (62) with ANSI colour (22), and sixel graphics (4) only when the pane's images will be shown. chafa, img2sixel's callers, lsix, timg, yazi, notcurses and matplotlib's sixel backends decide between sixel and a text fallback on that one attribute, so listing it when the picture would be dropped trades their fallback for a blank.
Every attribute listed is one a guest may act on, so only what is implemented is listed. 132 columns (1), selective erase (6), national replacement character sets (9), technical characters (15) and user windows (18) are left out, because none of them exists here: a pane cannot change its own width, no cell can be protected, and only the UK and DEC special graphics sets are designated. The class is 62, which is what kitty, ghostty and foot answer, so a program that reads the class to decide it is on a VT220 or later (vim, neovim, notcurses, tmux) finds one.
func EncodeKeyCSIu ¶
func EncodeKeyCSIu(key KeyPressEvent, flags int) string
EncodeKeyCSIu encodes a key event in the CSI u format used by the kitty keyboard protocol. Returns the encoded sequence, or empty string if the key should use legacy encoding.
func EncodeKeyReleaseCSIu ¶
func EncodeKeyReleaseCSIu(key KeyPressEvent, flags int) string
EncodeKeyReleaseCSIu encodes a key release for a pane that asked to be told about them, and returns "" for one that did not.
Only the event-type flag makes a release reportable, and it is the flag a compositor running in a pane cannot do without: a Wayland client is told a key is down and waits to be told it came up, so a dropped release leaves the key held and xkb repeating it forever. The press form is unchanged by the flag (kitty sends a bare \x1b[97u for the press and \x1b[97;1:3u for its release), so the release always carries the modifier field, even when empty, because the event type rides on it as a subparameter.
func EncodeModifyOtherKeys ¶
func EncodeModifyOtherKeys(key KeyPressEvent, level int) string
EncodeModifyOtherKeys encodes a key press the way xterm does under modifyOtherKeys, as CSI 27 ; modifier ; code ~, or returns "" when the key keeps its ordinary encoding at that level. Only the "other" keys take part: characters, Space, Tab, Enter, Backspace and Escape. Cursor, editing, keypad and function keys already carry their modifiers in their own sequences.
Level 2 encodes every modified key whose ordinary form would lose the modifier, which is every one but a shifted character, and Shift+Tab, which has CSI Z. Level 1 leaves the keys with well-known behaviour alone: a Ctrl or Shift chord that makes a control character (Ctrl+A is 0x01), Alt with a character (ESC prefix), and Backspace.
The kitty keyboard protocol is the richer of the two, so a pane with kitty flags set does not reach this encoder.
func EncodePaneKey ¶
func EncodePaneKey(key KeyPressEvent, kittyFlags, modifyOtherKeys int) string
EncodePaneKey encodes a key press in the keyboard mode a pane asked for, or returns "" when the key keeps its legacy encoding in that mode. kittyFlags is the pane's kitty keyboard flags and modifyOtherKeys its XTMODKEYS level.
The kitty flags win when a pane set both: the protocol says so, and a pane with flags set has chosen CSI u. modifyOtherKeys is xterm's older way to ask for keys the legacy encoding cannot tell apart.
Every route that writes a key press to a pane goes through here, so a key a person types and the same key sent with send-keys reach the pane as the same bytes.
func EncodeSixel ¶
func EncodeSixel(img *SixelImage, src image.Rectangle, dstW, dstH int) []byte
EncodeSixel writes the part of img inside src as a complete sixel DCS sequence (ESC P ... ST), scaled to dstW by dstH pixels by nearest neighbour.
This is how a pane's picture is clipped. Sixel has no crop and no delete: whatever is sent is painted, from the cursor down and to the right. So when only part of an image is visible, because the pane is scrolled, covered by a popup or runs off the screen, tuios sends a new image holding just that part. The scale covers a host whose cells are a different size from the ones the guest drew for, which happens when several terminals share a session.
The palette is the image's own, renumbered to the registers the crop uses, so nothing is re-quantised. Unpainted pixels stay transparent (P2=1).
func IsKittyAnimationAction ¶
func IsKittyAnimationAction(a KittyGraphicsAction) bool
IsKittyAnimationAction reports whether a is one of the frame edits: a=f, a=a and a=c. A host either makes them or refuses them.
func IsKittyEchoedResponse ¶
func IsKittyEchoedResponse(cmd *KittyCommand) bool
IsKittyEchoedResponse reports whether a parsed graphics command is a terminal's reply coming back as input rather than a command from a guest.
The payload shape alone is not enough. A chunk of real image data can be all capital letters behind a leading E: a run of dark pixels encodes to "EAAAAAAA", and the last chunk of a chunked transmission is often short enough to pass the length cap. Dropping it as an echo left the transmission without its m=0, so the image never appeared. A reply carries no key but the ids (i=, I=, p=), and every transmission carries at least one other key (a=, f=, s=, v=, t= on the first chunk, m= on every later one), so a command is an echo only when it has the reply's keys and the reply's payload.
func IsKittyPlaceholder ¶
IsKittyPlaceholder reports whether a cell's content is a placeholder cell.
This is asked of every cell the emulator prints and of every style run the dim blends, so it leaves the hot path on a byte compare: U+10EEEE is F4 8E BB AE in UTF-8, and no ordinary character starts with F4.
func IsKittyResponsePayload ¶
IsKittyResponsePayload reports whether a graphics payload looks like an echoed kitty protocol response rather than image data.
It is matched against the raw wire payload (the base64 text between ';' and the APC terminator), not the decoded bytes. A real transmit payload is a base64 string; an echoed response is a short status token: "OK", or a POSIX error name optionally followed by a ":message" (e.g. "ENOENT", "EINVAL:bad params"). Matching the decoded bytes instead let arbitrary binary chunks (a chafa or mpv direct stream) collide with the 'E'+A-Z shape about 0.04% of the time and silently drop a chunk, corrupting the image.
The shape required is ^(OK|E[A-Z]+(:.*)?)$ with a hard length cap so that a legitimate (necessarily longer, mixed-case) base64 payload cannot match.
func IsSixelMarker ¶
IsSixelMarker reports whether a cell's content is a sixel image cell. It is a byte compare, cheap enough for every cell of every frame.
func KittyInTempDir ¶
KittyInTempDir reports whether path lies in a temporary directory: /tmp, /var/tmp, /dev/shm, or the one TMPDIR names.
func KittyMediumIsFrame ¶
func KittyMediumIsFrame(cmd *KittyCommand, info os.FileInfo) bool
KittyMediumIsFrame reports whether info describes the object that cmd, a shared memory (t=s) or temp file (t=t) transmission, hands to the terminal. Only then may a reader that did not create the object delete it.
The name in a transmission is text the pane printed. Any program in the pane can print a name, including the name of an object another program still uses. So a name alone is no proof, and a delete needs all of these:
- the object is a regular file;
- this user owns it;
- its size is the size the command describes: O+S when S is given, or O+s*v*3 for f=24 and O+s*v*4 for f=32 when it is not.
A compressed (o=z) or PNG (f=100) frame without S has no size to compare, so it is never deleted.
func KittyPayloadErrorResponse ¶
func KittyPayloadErrorResponse(cmd *KittyCommand) []byte
KittyPayloadErrorResponse is the reply owed to a guest whose command carried a payload that could not be decoded, or nil when none is owed.
kitty answers an error unless the guest asked for silence with q=2, and only when the command names its image with i= or I=, because a reply without an id cannot be matched to anything. A query is the exception: it is answered with or without an id, the way tuios has always answered it, because a probing guest waits for that reply.
A payload shaped like a reply ("EINVAL:...") is a guest echoing one back, usually a shell that received it as input. Answering that would echo again, forever, so it gets nothing.
func KittyPlaceholderImageID ¶
KittyPlaceholderImageID returns the image id a placeholder cell names. Tests outside this package read cells through it.
func KittySensitivePath ¶
KittySensitivePath reports whether path lies in a place no file medium may name.
func KittyTempDirs ¶
func KittyTempDirs() []string
KittyTempDirs lists the temporary directories: the fixed ones and TMPDIR. TMPDIR is ignored when it is /, the home directory or a parent of it, since that would make every file of the user a temporary one. Inside the home directory it counts only under ~/tmp or ~/.tmp.
func LinkParams ¶
LinkParams is a link's parameters made safe the same way. A byte outside printable ASCII, and ';', which would end them, is percent-encoded rather than dropped, so id=链 and id=接 stay two ids.
func LinkURI ¶
LinkURI is a link's address as tuios keeps it in a cell and writes it to the host: without control bytes, and with every other byte outside printable ASCII percent-encoded, which a browser reads as the same address.
The OSC 8 spec allows only printable ASCII in a link's address. A raw UTF-8 address is not safe even with every control rune stripped: the continuation bytes of many runes are 0x80-0x9f, and a parser that reads 8-bit controls (charmbracelet/x/ansi, tmux, and the terminals that do the same) takes them as C1. 0x9c is ST, so the sequence ends in the middle of the address and the rest of it is printed as text. "术" is E6 9C AF. The row is then wider than the pane, and everything after it on screen is drawn in the wrong place. The cell keeps the encoded form, so every renderer that writes the cell back out, and a frame read back in, agree on the address.
func LinkURIDecodedLen ¶
LinkURIDecodedLen is the length in bytes of a LinkURI address with its percent escapes decoded: the length of the address the program wrote.
func ParseSixelMarker ¶
ParseSixelMarker reads a marker cell back. It reports false for content that is not a complete marker, which the compositor then draws blank.
func SanitizePaste ¶
SanitizePaste removes from text every character that could act as a terminal control rather than as pasted text: ESC, the other C0 controls except tab, line feed and carriage return, DEL, the C1 controls, and bytes that are not valid UTF-8.
The ESC is the one that matters. Text holding ESC[201~ ends a bracketed paste early, and whatever follows reaches the application as typed input, so a shell runs it. The text can come from anywhere a pane can reach: an OSC 52 write, a hint match, a line of scrollback. xterm and kitty strip the same characters from a paste for the same reason. The rest go too because a paste is text, and a lone BEL, NUL or C1 CSI in it is never what the person meant to type.
func SetBuildVersion ¶
func SetBuildVersion(v string)
SetBuildVersion records the version XTVERSION reports after the program name. Call it once, before the first pane starts.
func SetDebugLogger ¶
func SetDebugLogger(l Logger)
SetDebugLogger sets a process-wide logger for diagnostic lines that no single emulator owns, such as every XTWINOPS request a program sends. It is nil by default, and then nothing is formatted. Each line is one message without a trailing newline. Call it once at startup, before the first emulator exists.
func SetHostHyperlink ¶
SetHostHyperlink returns the OSC 8 that opens a link in a frame written to the host, with LinkURI and LinkParams applied, or "" for an address longer than MaxHostLinkURI. A cell the vt emulator filled is already encoded. A bare URL tuios finds in the text, and a cell from another backend, may not be. It is for a host that writes the cells to its own terminal.
func SetTerminalName ¶
func SetTerminalName(name string)
SetTerminalName sets the program name XTVERSION reports. An empty name restores DefaultTerminalName. Call it once, before the first pane starts.
func SixelCells ¶
func SixelCells(cmd *SixelCommand, cellW, cellH int) (rows, cols int)
SixelCells returns the rows and columns an image covers at the given cell size, bounded so a marker can state every one of them.
func SixelMarker ¶
SixelMarker is the cell content for row and column of image id. The sixel marker functions are the cell format of a sixel image, for a host that draws the cells.
func StripControls ¶
StripControls returns s without C0 controls, DEL, C1 controls (as raw bytes or UTF-8 encoded) and bytes that are not valid UTF-8.
A link's address and parameters are written back out to the host terminal inside its own OSC 8 when the frame is drawn. The parser already ends the sequence at ESC and BEL, but a raw 0x9c is ST to a terminal that reads 8-bit controls, and none of these belong in a link.
func StripKittyPlaceholders ¶
StripKittyPlaceholders returns s with each placeholder cell, U+10EEEE and the row, column and id marks after it, written as one space. A placeholder is a piece of a picture, and text that leaves the grid (a capture) has no use for it. s is returned as it is when it holds none.
func StripSixelMarkers ¶
StripSixelMarkers replaces every sixel marker in s with a space, for text that leaves the grid as text: a copy, a search, a capture.
func XTVersionName ¶
func XTVersionName() string
XTVersionName is the text an XTVERSION reply carries: the program name, followed by the build version when one was set. Both backends answer with it, so a guest that picks its features by terminal name sees the same name on either.
Types ¶
type ApcHandler ¶
ApcHandler is a function that handles an APC escape sequence.
type Callbacks ¶
type Callbacks struct {
// Bell callback. When set, this function is called when a bell character is
// received.
Bell func()
// Title callback. When set, this function is called when the terminal title
// changes.
Title func(string)
// IconName callback. When set, this function is called when the terminal
// icon name changes.
IconName func(string)
// AltScreen callback. When set, this function is called when the alternate
// screen is activated or deactivated.
AltScreen func(bool)
// CursorPosition callback. When set, this function is called when the cursor
// position changes.
CursorPosition func(old, new uv.Position) //nolint:predeclared,revive
// CursorVisibility callback. When set, this function is called when the
// cursor visibility changes.
CursorVisibility func(visible bool)
// CursorColor callback. When set, this function is called when the cursor
// color changes. Nil indicates the default terminal color.
CursorColor func(color color.Color)
// BackgroundColor callback. When set, this function is called when the
// background color changes. Nil indicates the default terminal color.
BackgroundColor func(color color.Color)
// ForegroundColor callback. When set, this function is called when the
// foreground color changes. Nil indicates the default terminal color.
ForegroundColor func(color color.Color)
// WorkingDirectory callback. When set, this function is called when the
// current working directory changes.
WorkingDirectory func(string)
// EnableMode callback. When set, this function is called when a mode is
// enabled.
EnableMode func(mode ansi.Mode)
// DisableMode callback. When set, this function is called when a mode is
// disabled.
DisableMode func(mode ansi.Mode)
// ScreenClear callback. When set, this function is called when the screen
// is cleared (ED 2 or ED 3).
ScreenClear func()
// ClipboardSet callback. Called when a guest app sets clipboard via OSC 52.
ClipboardSet func(selection, content string)
// ClipboardQuery callback. Called when a guest app queries clipboard via OSC 52.
// Returns the current clipboard content for the given selection.
ClipboardQuery func(selection string) string
// Notify callback. Called when a guest app requests a desktop notification
// via OSC 9, OSC 777, or OSC 99.
Notify func(title, body string)
// Progress callback. Called when a guest app reports its progress via the
// OSC 9;4 sequence. percent is 0 for the states that carry no percentage.
Progress func(state ProgressState, percent int)
// ProgramStatus callback. Called for every OSC 7501 report that passed
// every check of the Program Status Protocol, and with Reset set on a full
// reset (RIS), which removes every record. The feature detection query is
// answered by the emulator and never reaches it. Like SemanticMark it fires
// with the emulator's lock held on backends that have one, so it must only
// record.
ProgramStatus func(ev progstatus.Event)
// SemanticMark callback. Called for every OSC 133 mark a shell sends (A
// prompt start, B input start, C command executed, D command finished),
// after the mark is recorded in SemanticMarkers. A C mark carries the
// command line read off the screen and a D mark its exit code, -1 when the
// shell sent none. It fires with the emulator's lock held on backends that
// have one, so it must only record and never call back into the terminal.
SemanticMark func(mark SemanticMarker)
// PrivateOSC callback. Called for an OSC sequence whose number the
// emulator does not interpret, so a host can give meaning to a private
// number of its own. cmd is the OSC number and data the whole body,
// number included, as an [OscHandler] receives it. data is only valid for
// the call. A sequence with no valid number, such as ESC ] foo BEL, is
// not passed on. Both backends call it for the same numbers.
PrivateOSC func(cmd int, data []byte)
}
Callbacks represents a set of callbacks for a terminal.
type CcHandler ¶
type CcHandler func() bool
CcHandler is a function that handles a control character.
type CellRun ¶
type CellRun struct {
X, Y, N int // start column, row, and number of cells
}
CellRun is N cells of row Y from column X.
type CharSet ¶
CharSet represents a character set designator. This can be used to select a character set for G0 or G1 and others.
type CsiHandler ¶
CsiHandler is a function that handles a CSI escape sequence.
type Cursor ¶
type Cursor struct {
Pen uv.Style // style of the next printed character
Link uv.Link // hyperlink of the next printed character
uv.Position
Hidden bool // whether the guest hid the cursor (DECTCEM)
// Protected says DECSCA protects what is printed next from a selective
// erase. DECSC saves it with the rest of the cursor.
Protected bool
}
Cursor represents a cursor in a terminal.
type CursorStyle ¶
type CursorStyle int
CursorStyle represents a cursor style.
const ( CursorBlock CursorStyle = iota CursorUnderline CursorBar )
Cursor styles.
type DcsHandler ¶
DcsHandler is a function that handles a DCS escape sequence.
type Emulator ¶
type Emulator struct {
// contains filtered or unexported fields
}
Emulator represents a virtual terminal emulator.
func NewEmulator ¶
NewEmulator creates a new virtual terminal emulator.
func (*Emulator) ActiveScreenIsAlt ¶
ActiveScreenIsAlt reports whether the active screen pointer currently addresses the alternate buffer. This is a diagnostic accessor: it exists so the render trace can distinguish the buffer actually being read from the mode bits reported by IsAltScreen, which RestoreAltScreenMode deliberately leaves untouched. It is not part of the emulator's behavioural contract, so do not build rendering or input logic on it.
func (*Emulator) AppendScrollbackText ¶
AppendScrollbackText writes the main screen's scrollback to buf as plain text, oldest line first, each line followed by a newline. The bytes are the same as ScrollbackLine(i).String() plus "\n" for every line, but no line is decoded into cells: a cell is 112 bytes, so decoding a full 10000-line ring to read its text allocated about 100 MB at 80 columns.
It reads the ring and its intern tables and writes nothing to them, so it is safe under the same read lock ScrollbackLine is.
func (*Emulator) ApplicationCursorKeys ¶
ApplicationCursorKeys returns true if DECCKM (application cursor keys mode) is enabled. When this mode is set, cursor keys send SS3 sequences (ESC O A) instead of CSI sequences (ESC [ A).
func (*Emulator) AtGround ¶
AtGround reports whether the parser is between sequences: no escape sequence, string or character is half read.
func (*Emulator) BackgroundColor ¶
BackgroundColor returns the terminal's background color. This returns nil if the background color is not set which means the outer terminal color is used.
func (*Emulator) Blur ¶
func (e *Emulator) Blur()
Blur sends the terminal a blur event if focus events mode is enabled. This is the opposite of [Focus].
func (*Emulator) BracketedPasteEnabled ¶
BracketedPasteEnabled returns true if bracketed paste mode (?2004) is enabled. When enabled, pasted text should be wrapped with escape sequences.
func (*Emulator) CellAt ¶
CellAt returns the current focused screen cell at the given x, y position. It returns nil if the cell is out of bounds.
func (*Emulator) CellSize ¶
CellSize returns the pixel dimensions of a single character cell, or the fallback cell when none was set. It is never zero.
func (*Emulator) Charsets ¶
Charsets returns the designator byte of the character set selected into each of G0 to G3, and which of them GL and GR are pointing at.
func (*Emulator) ClearScrollback ¶
func (e *Emulator) ClearScrollback()
ClearScrollback clears the scrollback buffer of the main screen.
func (*Emulator) CopyScrollback ¶
func (e *Emulator) CopyScrollback(from, end int) *ScrollbackCopy
CopyScrollback copies the main screen history lines from index from to end-1. See Terminal.CopyScrollback.
func (*Emulator) CursorColor ¶
CursorColor returns the terminal's cursor color. This returns nil if the cursor color is not set which means the outer terminal color is used.
func (*Emulator) CursorPen ¶
CursorPen returns the graphic rendition in force: the style and hyperlink everything written next will be painted with. A guest sets it once with an SGR sequence and every character until the next one inherits it, so it is state a snapshot has to carry and not something the cells can be read back from.
func (*Emulator) CursorPendingWrap ¶
CursorPendingWrap reports whether a wrap is pending at the cursor.
func (*Emulator) CursorPosition ¶
CursorPosition returns the terminal's cursor position.
func (*Emulator) CursorProtected ¶
CursorProtected reports whether DECSCA protects what is printed next.
func (*Emulator) CursorStyle ¶
func (e *Emulator) CursorStyle() (CursorStyle, bool)
CursorStyle returns the shape DECSCUSR last asked for, and whether it is steady (not blinking). It reads the terminal-level copy rather than the active screen's, because DECSCUSR is a property of the terminal: a guest that asks for a bar and then enters the alternate screen still wants a bar. The per-screen Cursor.Style is left alone so DECSC/DECRC keep behaving as they did.
func (*Emulator) DisableKittyKeyboardProtocol ¶
func (e *Emulator) DisableKittyKeyboardProtocol()
DisableKittyKeyboardProtocol makes the emulator stop offering the kitty keyboard protocol. Pushes, pops and sets change nothing, a CSI ? u query goes unanswered, and a saved stack is not restored.
It is for a pane whose PTY is a Windows ConPTY. conhost before 1.22 drops the input CSIs it does not recognise, so the CSI u bytes for Escape, Ctrl+letters and modified Enter or Backspace never reach the guest. Per the kitty spec an unanswered query means the protocol is not supported, so a guest that queries first (pi, neovim) falls back to legacy keys on its own. Every encoder reads the flags, which stay at 0, so client key encoding, send-keys and key releases all agree.
The daemon calls it before the pane's output starts. A client calls it from a snapshot that says the pane is a ConPTY one (see snapshot.State.KittyKbdUnavailable), under the lock that guards the emulator's writes. There is no way back: a pane keeps its PTY.
func (*Emulator) DiscardScrollback ¶
func (e *Emulator) DiscardScrollback()
DiscardScrollback makes the main screen drop the lines that scroll off its top instead of keeping them. See Scrollback.Discard.
func (*Emulator) EncodeMouseEvent ¶
EncodeMouseEvent encodes a mouse event as an escape sequence string. Returns empty string if no mouse mode is enabled. This is used for daemon mode where mouse events need to be sent through the PTY.
func (*Emulator) EncodeMouseEventAt ¶
func (e *Emulator) EncodeMouseEventAt(m Mouse, at MousePixel) string
EncodeMouseEventAt is EncodeMouseEvent with the pointer's pixel position inside the pane, which a guest in SGR-pixel mode is told instead of the cell centre.
func (*Emulator) Focus ¶
func (e *Emulator) Focus()
Focus sends the terminal a focus event if focus events mode is enabled. This is the opposite of [Blur].
func (*Emulator) FocusReportingEnabled ¶
FocusReportingEnabled reports whether the guest has focus event reporting (DECSET 1004) on.
func (*Emulator) ForegroundColor ¶
ForegroundColor returns the terminal's foreground color. This returns nil if the foreground color is not set which means the outer terminal color is used.
func (*Emulator) GetCallbacks ¶
GetCallbacks returns the terminal's current callbacks.
func (*Emulator) GetModes ¶
GetModes returns a copy of the current terminal DEC private modes. This is used for session state serialization to preserve terminal modes across reconnections (mouse tracking, bracketed paste, etc.).
It captures every DEC mode the emulator tracks rather than a hand-picked list: a guest sets a sticky mode once at startup (a browser enables 1003/1006/1016 and never repeats them), and any mode missing here is silently lost on reattach once the enable sequence has scrolled out of the daemon's bounded output buffer.
func (*Emulator) GuestColors ¶
func (e *Emulator) GuestColors() GuestColors
GuestColors is what the guest set with OSC 4, 10, 11 and 12.
func (*Emulator) GuestCursorColor ¶
GuestCursorColor is the cursor colour the guest set with OSC 12, or nil when it set none or reset it with OSC 112.
func (*Emulator) HasAllMotionMode ¶
HasAllMotionMode returns true only if the child app requested mode 1003. Thread-safe: reads from an atomic cache updated on mode set/reset.
func (*Emulator) HasCellMotionMode ¶
HasCellMotionMode returns true if the child app requested mode 1002 (button-event tracking), which reports motion while a button is pressed.
func (*Emulator) HasMouseMode ¶
HasMouseMode returns true if any mouse tracking mode is enabled. HasMouseMode returns true if any mouse tracking mode is enabled. Thread-safe: reads from an atomic cache updated on mode set/reset.
func (*Emulator) HasPixelMouseMode ¶
HasPixelMouseMode reports whether the guest tracks the mouse and asked for SGR-pixel reports (DEC 1016). Thread-safe: reads the atomic cache.
func (*Emulator) IndexedColor ¶
IndexedColor returns a terminal's indexed color. An indexed color is a color between 0 and 255.
func (*Emulator) InputPipe ¶
InputPipe returns the terminal's input pipe. This can be used to send input to the terminal.
func (*Emulator) IsAltScreen ¶
IsAltScreen returns whether the terminal is currently using the alternate screen buffer. The alternate screen is used by full-screen applications like vim, less, htop, btop, etc. This is important for mouse event forwarding: mouse events should only be forwarded to applications when they are in alternate screen mode.
func (*Emulator) IsCursorHidden ¶
IsCursorHidden returns whether the cursor is currently hidden. Applications can hide the cursor using ANSI escape sequences (DECTCEM mode).
func (*Emulator) IsSyncActive ¶
IsSyncActive reports whether the guest has an open synchronized update (DEC private mode 2026): it has begun drawing a frame and does not want it presented until it resets the mode. Thread-safe: reads from atomics updated on mode set/reset. Returns false once the update has been open past syncMaxHold.
func (*Emulator) KittyAltState ¶
func (e *Emulator) KittyAltState() *KittyState
KittyAltState returns the kitty image state of the alternate screen.
func (*Emulator) KittyGuestImagesState ¶
func (e *Emulator) KittyGuestImagesState() *KittyGuestImagesState
KittyGuestImagesState returns the ids given to the guest's image numbers, for a client that attaches. Nil when there are none.
func (*Emulator) KittyKeyboardFlags ¶
KittyKeyboardFlags returns the current kitty keyboard protocol flags. Thread-safe: reads from an atomic cache updated on push/pop/set/reset.
func (*Emulator) KittyKeyboardMainStack ¶
KittyKeyboardMainStack returns a copy of the main screen's kitty keyboard flag stack while the alternate screen is in use, and nil otherwise. A snapshot carries it with KittyKeyboardStack: a client that restores only the alternate screen's stack has the main one empty when the program quits, and encodes keys in legacy form for a shell that negotiated the protocol.
func (*Emulator) KittyKeyboardStack ¶
KittyKeyboardStack returns a copy of the kitty keyboard flag stack of the screen in use, base entry first. It exists for daemon state sync: a guest negotiates the protocol once (CSI > u push or CSI = u set) and never repeats it, so a reattaching client must be handed the stack rather than rediscover it from the output buffer. Call from the goroutine that feeds the emulator, or with the same lock that serializes writes to it.
func (*Emulator) KittyKeyboardUnavailable ¶
KittyKeyboardUnavailable reports whether DisableKittyKeyboardProtocol was called.
func (*Emulator) KittyMainState ¶
func (e *Emulator) KittyMainState() *KittyState
KittyMainState returns the kitty image state of the main screen.
func (*Emulator) KittyState ¶
func (e *Emulator) KittyState() *KittyState
KittyState returns the kitty image state of the active screen.
func (*Emulator) LastPrinted ¶
LastPrinted is the cluster REP repeats.
func (*Emulator) MainCellAt ¶
MainCellAt reads a cell from the normal screen whether or not the alternate one is active. It is what the guest is not looking at while a full-screen program is running, and what quitting that program reveals.
func (*Emulator) MainRowTail ¶
MainRowTail returns the cells of main screen row y past the width that a reflow held for an open prompt (see freezePrompt), or nil. A reader that keeps a row whole, such as a saved history, appends them.
func (*Emulator) ModifyOtherKeys ¶
ModifyOtherKeys returns the modifyOtherKeys level the guest set with XTMODKEYS: 0 off, 1 or 2. Thread-safe.
func (*Emulator) PaletteColor ¶
PaletteColor resolves one of the sixteen ANSI palette slots the way handleSgr resolves SGR 30-37 and 90-97: through the user's theme when one is set, and as a plain palette entry otherwise.
A cell rebuilt from a snapshot has to be coloured by the same rule as a cell the guest writes live, or a pane comes back in one palette and carries on in another.
func (*Emulator) PendingInput ¶
PendingInput is the input since the parser last left its ground state, with the controls it carried out inside the sequence left out. Inside a CSI or an escape sequence a C0 control is carried out where it is and the sequence goes on, so a replay that sent it again would move the cursor twice. Inside a string (OSC, DCS, SOS, PM, APC) a control is ignored or is payload, and is kept.
func (*Emulator) ProtectedCells ¶
ProtectedCells lists the cells DECSCA protected, on the active screen or with main set on the main screen.
func (*Emulator) PushScrollbackLine ¶
PushScrollbackLine appends a line to the main screen's scrollback. It exists for snapshot restore, where history arrives as decoded lines rather than as a byte stream.
func (*Emulator) Read ¶
Read reads data from the terminal input buffer.
Example ¶
A sequence that asks a question gets its answer through Read. A host copies the answers back to the program, usually in a goroutine.
package main
import (
"fmt"
"tuios.dev/vt"
)
func main() {
term := vt.NewEmulator(80, 24)
defer term.Close()
_, _ = term.Write([]byte("\x1b[3;5H\x1b[6n")) // move, then ask where the cursor is
reply := make([]byte, 32)
n, _ := term.Read(reply)
fmt.Printf("%q\n", reply[:n]) // "\x1b[3;5R"
}
Output:
func (*Emulator) RegisterApcHandler ¶
func (h *Emulator) RegisterApcHandler(handler ApcHandler)
RegisterApcHandler registers an APC escape sequence handler.
func (*Emulator) RegisterCsiHandler ¶
func (h *Emulator) RegisterCsiHandler(cmd int, handler CsiHandler)
RegisterCsiHandler registers a CSI escape sequence handler.
func (*Emulator) RegisterDcsHandler ¶
func (h *Emulator) RegisterDcsHandler(cmd int, handler DcsHandler)
RegisterDcsHandler registers a DCS escape sequence handler.
func (*Emulator) RegisterEscHandler ¶
func (h *Emulator) RegisterEscHandler(cmd int, handler EscHandler)
RegisterEscHandler registers an ESC escape sequence handler.
func (*Emulator) RegisterOscHandler ¶
func (h *Emulator) RegisterOscHandler(cmd int, handler OscHandler)
RegisterOscHandler registers an OSC escape sequence handler.
func (*Emulator) RegisterPmHandler ¶
func (h *Emulator) RegisterPmHandler(handler PmHandler)
RegisterPmHandler registers a PM escape sequence handler.
func (*Emulator) RegisterSosHandler ¶
func (h *Emulator) RegisterSosHandler(handler SosHandler)
RegisterSosHandler registers an SOS escape sequence handler.
func (*Emulator) ReleaseAltScreen ¶
func (e *Emulator) ReleaseAltScreen()
ReleaseAltScreen drops the alternate screen's cells while the main screen is shown. A pane that has run one full-screen program keeps that grid otherwise, 1.7 MB at 171x83, and nothing reads it: every switch onto the alternate screen clears it first. The screen keeps its size, and a row nothing has written reads as blank, so the next switch finds what the clear would leave. Dropping the cells at the switch back to the main screen instead would make a pager launched over and over allocate its grid each time.
func (*Emulator) ReleaseReflowScratch ¶
func (e *Emulator) ReleaseReflowScratch()
ReleaseReflowScratch drops the buffers the main screen keeps from one reflow to the next. They make a drag cheap and are worth nothing to a pane that is not being resized, yet after two reflows they hold a spare block the size of the last layout and the history rows that layout decoded: 1.7 MB at 171x83. The next reflow allocates them again. The rows on screen keep the block they are in alive on their own, and a remap handed out by the last reflow keeps the tables it reads, so only what nothing reads is freed.
func (*Emulator) Render ¶
Render renders a snapshot of the terminal screen as a string with styles and links encoded as ANSI escape codes.
The frame must redraw the screen when replayed, and concatenation alone cannot: a lone regional indicator in one cell and another in the next are two characters on the grid but one flag to any parser reading them back. A cluster break separates such neighbours.
func (*Emulator) ReserveImageSpace ¶
ReserveImageSpace reserves space for an image by moving cursor and outputting placeholders. This ensures subsequent output appears below the image rather than on top of it.
func (*Emulator) ResetScrollRegion ¶
func (e *Emulator) ResetScrollRegion()
ResetScrollRegion puts scrolling back to the whole screen, which is where a pane whose guest has set no margins scrolls.
func (*Emulator) RestoreANSIModes ¶
RestoreANSIModes sets the ANSI modes given. It goes through setMode, which also sets the flags the print and line feed paths read.
func (*Emulator) RestoreAltScreenMode ¶
RestoreAltScreenMode restores the alternate screen mode state. This is used when reconnecting to a daemon session to restore the emulator state without re-sending the escape sequences that would trigger the mode change. This method ONLY switches the screen buffer pointer. It does NOT modify the modes map to avoid concurrent map access issues.
func (*Emulator) RestoreCharsets ¶
RestoreCharsets puts back a character set selection. A program that draws boxes selects the DEC line-drawing set once and then sends the box characters as plain letters, so a client that comes back with G0 at US ASCII draws qqqq where the guest drew a horizontal rule.
func (*Emulator) RestoreCursorPen ¶
RestoreCursorPen puts back the rendition a snapshot was taken under, so the output that arrives after the snapshot is painted the colour the guest set rather than whatever this emulator was left in.
func (*Emulator) RestoreCursorPendingWrap ¶
RestoreCursorPendingWrap arms or clears the pending wrap a restored snapshot had at the cursor. Call it after RestoreCursorPosition, which clears it.
The cursor is also recorded as standing on the cell it was printed into, as the print that armed the wrap left it, so a combining mark that arrives next joins that cell rather than the one after it.
func (*Emulator) RestoreCursorPosition ¶
RestoreCursorPosition puts the cursor back where a restored snapshot had it. It is the counterpart of CursorPosition and, like RestoreAltScreenMode, it exists so reconnecting does not have to re-send escape sequences whose side effects would undo the restore.
func (*Emulator) RestoreCursorProtected ¶
RestoreCursorProtected puts back the pen's DECSCA protection.
func (*Emulator) RestoreCursorStyle ¶
func (e *Emulator) RestoreCursorStyle(style CursorStyle, steady bool)
RestoreCursorStyle puts back the shape a snapshot was taken under. A pane the client is rebuilding from the daemon has emitted its DECSCUSR long ago, so without this the pane comes back as a block whatever the guest asked for.
func (*Emulator) RestoreGuestColors ¶
func (e *Emulator) RestoreGuestColors(c GuestColors)
RestoreGuestColors replaces what the guest set with OSC 4, 10, 11 and 12. A nil default colour is one the guest has not set, which the theme's default answers for.
func (*Emulator) RestoreKittyGuestImages ¶
func (e *Emulator) RestoreKittyGuestImages(s *KittyGuestImagesState)
RestoreKittyGuestImages takes the daemon's ids for the guest's image numbers. Nil leaves them as they are.
func (*Emulator) RestoreKittyKeyboardMainStack ¶
RestoreKittyKeyboardMainStack replaces the main screen's flag stack from a saved state. A nil or empty stack is a no-op.
func (*Emulator) RestoreKittyKeyboardState ¶
RestoreKittyKeyboardState replaces the kitty keyboard flag stack from a saved state and refreshes the cache KittyKeyboardFlags reads. Used when reconnecting to a daemon session; a nil or empty stack is a no-op so state from an older daemon leaves the default (empty) state untouched. The stack goes to the screen in use, so restore the alternate screen first.
func (*Emulator) RestoreLastPrinted ¶
RestoreLastPrinted puts back the cluster REP repeats. Its width is not needed: REP prints the cluster again, which measures it.
func (*Emulator) RestoreModes ¶
RestoreModes restores terminal modes from a saved state. This is used when reconnecting to a daemon session to restore mouse tracking and other terminal modes without triggering mode change side effects.
func (*Emulator) RestoreModifyOtherKeys ¶
RestoreModifyOtherKeys puts back a level saved from another emulator, for a client that reattaches after the guest set it.
func (*Emulator) RestorePads ¶
RestorePads sets the padding flags a snapshot carries. See Terminal.RestorePads.
func (*Emulator) RestorePendingInput ¶
RestorePendingInput drops the sequence the parser is in, and any character cluster left open across the last Write, and then reads p.
func (*Emulator) RestoreProtectedCells ¶
RestoreProtectedCells replaces the protection of the active screen, or with main set of the main screen, with runs.
func (*Emulator) RestoreSavedCursor ¶
func (e *Emulator) RestoreSavedCursor(main bool, c SavedCursor)
RestoreSavedCursor puts back what DECSC saved on the active screen, or with main set on the main screen.
func (*Emulator) RestoreScrollRegion ¶
RestoreScrollRegion puts back the margins a guest set with DECSTBM or DECSLRM. A guest sets them once to hold a header or a status line out of the scrolling part of the screen, so a client that comes back without them scrolls the whole screen and takes the fixed rows with it.
func (*Emulator) RestoreSoftWraps ¶
RestoreSoftWraps sets the soft-wrap flags a snapshot carries. See Terminal.RestoreSoftWraps.
func (*Emulator) RestoreTabStops ¶
RestoreTabStops replaces the tab stops with cols. A column off the screen is dropped.
func (*Emulator) RestoreTitles ¶
RestoreTitles puts back the titles and the newest entries of the stack, as many as XTWINOPS 22 keeps.
func (*Emulator) RowPadded ¶
RowPadded reports whether row y of the active screen wrapped a column early before a wide character. See Terminal.RowPadded.
func (*Emulator) RowSoftWrapped ¶
RowSoftWrapped reports whether row y of the active screen carries on to row y+1 because autowrap moved the text there, rather than because the program wrote a newline. known is always true for this backend.
func (*Emulator) SavedCursor ¶
func (e *Emulator) SavedCursor(main bool) SavedCursor
SavedCursor is what DECSC saved on the active screen, or with main set on the main screen.
func (*Emulator) ScrollRegion ¶
ScrollRegion returns the margins scrolling is confined to, as the rectangle of the active screen they cover.
func (*Emulator) Scrollback ¶
func (e *Emulator) Scrollback() *Scrollback
Scrollback returns the scrollback buffer of the main screen. Note: The alternate screen does not maintain scrollback.
func (*Emulator) ScrollbackGeneration ¶
ScrollbackGeneration is a number that changes whenever the main screen's history does: a line pushed, the ring trimmed, cleared or resized. A reader that derived something from the history can keep it for as long as the number stays the same.
func (*Emulator) ScrollbackLen ¶
ScrollbackLen returns the number of lines in the scrollback buffer.
func (*Emulator) ScrollbackLine ¶
ScrollbackLine returns a line from the scrollback buffer at the given index. Index 0 is the oldest line. Returns nil if index is out of bounds.
func (*Emulator) ScrollbackPadded ¶
ScrollbackPadded is RowPadded for a history line, oldest first.
func (*Emulator) ScrollbackRows ¶
ScrollbackRows calls fn with each main screen history line from index from to end-1, oldest first, decoded into a buffer reused from line to line. See Terminal.ScrollbackRows.
func (*Emulator) ScrollbackSoftWrapped ¶
ScrollbackSoftWrapped reports whether scrollback line index (oldest first) carries on to the next line by autowrap. The newest line carries on to the screen's first row. known is always true for this backend.
func (*Emulator) ScrollbackText ¶
ScrollbackText calls fn with each main screen history line from index from to end-1 as text cells. See Terminal.ScrollbackText.
func (*Emulator) SemanticMarkers ¶
func (e *Emulator) SemanticMarkers() *SemanticMarkerList
SemanticMarkers returns the list of OSC 133 semantic zone markers.
func (*Emulator) SendMouse ¶
SendMouse sends a mouse event to the terminal. This can be any kind of mouse events such as MouseClick, MouseRelease, MouseWheel, or MouseMotion.
func (*Emulator) SendMouseAt ¶
func (e *Emulator) SendMouseAt(m Mouse, at MousePixel)
SendMouseAt is SendMouse with the pointer's pixel position inside the pane, which a guest in SGR-pixel mode is told instead of the cell centre.
func (*Emulator) SetBackgroundColor ¶
SetBackgroundColor sets the terminal's background color.
func (*Emulator) SetCallbacks ¶
SetCallbacks sets the terminal's callbacks.
Example ¶
The emulator tells the host what the program asks of it through Callbacks.
package main
import (
"fmt"
"tuios.dev/vt"
)
func main() {
term := vt.NewEmulator(80, 24)
defer term.Close()
term.SetCallbacks(vt.Callbacks{
Title: func(title string) { fmt.Println("title:", title) },
Bell: func() { fmt.Println("bell") },
})
_, _ = term.Write([]byte("\x1b]2;build\x07\a"))
}
Output:
func (*Emulator) SetCellSize ¶
SetCellSize sets the pixel dimensions of a single character cell. Used for XTWINOPS terminal size reporting.
A guest with in-band resize reports on (mode 2048) is sent a new report when the size in pixels changes, as it is on a resize: it scales SGR-pixel mouse reports by the size it was last told.
func (*Emulator) SetCursorColor ¶
SetCursorColor sets the terminal's cursor color.
func (*Emulator) SetDefaultBackgroundColor ¶
SetDefaultBackgroundColor sets the terminal's default background color.
func (*Emulator) SetDefaultCursorColor ¶
SetDefaultCursorColor sets the terminal's default cursor color.
func (*Emulator) SetDefaultForegroundColor ¶
SetDefaultForegroundColor sets the terminal's default foreground color.
func (*Emulator) SetForegroundColor ¶
SetForegroundColor sets the terminal's foreground color.
func (*Emulator) SetIndexedColor ¶
SetIndexedColor sets a terminal's indexed color. The index must be between 0 and 255.
func (*Emulator) SetKittyFilesElsewhere ¶
SetKittyFilesElsewhere says the pane runs on another machine. See KittyGuestImages.SetFilesElsewhere.
func (*Emulator) SetKittyHeaderOnly ¶
SetKittyHeaderOnly says whether the passthrough acts on the control keys alone. When it does, commands are parsed with ParseKittyHeader and the passthrough gets a nil rawData.
func (*Emulator) SetKittyImageIDTranslator ¶
func (e *Emulator) SetKittyImageIDTranslator(fn KittyImageIDTranslator)
SetKittyImageIDTranslator installs the guest-to-host image id mapping used for kitty Unicode placeholder cells. Nil leaves every cell as the guest wrote it.
func (*Emulator) SetKittyPassthroughFunc ¶
func (e *Emulator) SetKittyPassthroughFunc(fn func(cmd *KittyCommand, rawData []byte))
SetKittyPassthroughFunc installs the reader of every graphics command. fn must not write to rawData: cmd.RawPayload shares its bytes.
func (*Emulator) SetKittyPlaceholderMode ¶
func (e *Emulator) SetKittyPlaceholderMode(m KittyPlaceholderMode)
SetKittyPlaceholderMode says whether placeholder cells are kept or dropped.
func (*Emulator) SetKittyUploadAnswers ¶
SetKittyUploadAnswers says whether this emulator answers kitty uploads and placements. See KittyGuestImages.
func (*Emulator) SetMainCell ¶
SetMainCell writes a cell into the normal screen whether or not the alternate one is active.
func (*Emulator) SetReflowFunc ¶
SetReflowFunc sets the function a reflow calls with where rows went. See Terminal.SetReflowFunc.
func (*Emulator) SetReportColors ¶
SetReportColors sets the colours an OSC 10 and OSC 11 query is answered with while the guest has not set its own. A nil colour keeps the default answer.
func (*Emulator) SetReportPalette ¶
SetReportPalette sets the colours an OSC 4 query for one of the sixteen ANSI slots is answered with while neither the guest nor a theme has set the slot. A nil entry keeps the default answer.
func (*Emulator) SetScreenClearFunc ¶
func (e *Emulator) SetScreenClearFunc(f func())
SetScreenClearFunc sets the ScreenClear callback without replacing other callbacks.
func (*Emulator) SetScrollbackMaxLines ¶
SetScrollbackMaxLines sets the maximum number of lines for the scrollback buffer.
func (*Emulator) SetSixelAdvertised ¶
SetSixelAdvertised installs the function that decides whether DA1 lists sixel and XTSMGRAPHICS answers. Nil advertises nothing.
func (*Emulator) SetSixelPassthroughFunc ¶
func (e *Emulator) SetSixelPassthroughFunc(fn SixelPassthroughFunc)
SetSixelPassthroughFunc installs the function that decodes a guest's sixel image and returns the id its marker cells carry. See sixel_marker.go.
func (*Emulator) SetTextSizingFunc ¶
SetTextSizingFunc installs the function that takes each OSC 66 text sizing sequence, rebuilt for the host terminal, with the cursor position, the scale and the length of the text in characters.
func (*Emulator) SetThemeColors ¶
SetThemeColors sets the terminal's color palette from a theme. This sets the default foreground, background, cursor colors and the first 16 ANSI colors (0-15) which are used by terminal applications.
A nil fg and bg mean no theme is active. That has to put the sixteen back the way they were, not merely stop writing them: a theme the user has turned off that stays in the color table goes on painting every pane in its own red and blue, which is the "going back to none messes up the ANSI 16" report.
func (*Emulator) SupportsMotionEvents ¶
SupportsMotionEvents returns true if the child app's mouse mode supports motion events (modes 1002 or 1003). Modes 1000/1001 only support click/release.
func (*Emulator) SyncUpdate ¶
SyncUpdate reports whether the guest has an open synchronized update, as IsSyncActive does, and a serial that names that update. Two calls that both report open with the same serial saw the same update; a different serial means the one seen before has been closed and a new one opened. Thread-safe.
func (*Emulator) TailText ¶
TailText returns the last n rows of the active screen that carry text, in reading order.
Blank rows are skipped rather than counted. An agent draws its live state in a box at the bottom of the pane and pads below it, so counting the padding would push the box out of the window a rule can see.
It reads the active screen, so a harness drawing in the alternate screen is still readable. Reading further up than a handful of rows finds transcript history, which says what the agent did rather than what it is doing.
NOT REENTRANT. The caller holds the terminal lock, the same as GetTerminalState.
func (*Emulator) TakeResponses ¶
TakeResponses removes and returns the replies queued for the program, or nil when there are none. Unlike Read it never blocks, so a host can drain the replies after each Write on the same goroutine. It returns nil after Close.
Example ¶
A host that reads the program's output on one goroutine can drain the answers right after each Write instead. TakeResponses never blocks.
package main
import (
"fmt"
"tuios.dev/vt"
)
func main() {
term := vt.NewEmulator(80, 24)
defer term.Close()
_, _ = term.Write([]byte("\x1b[3;5H\x1b[6n"))
fmt.Printf("%q\n", term.TakeResponses()) // "\x1b[3;5R"
fmt.Printf("%q\n", term.TakeResponses()) // "" (nothing is left)
}
Output:
func (*Emulator) WidthMethod ¶
func (e *Emulator) WidthMethod() uv.WidthMethod
WidthMethod returns the width method used by the terminal.
It is always grapheme width, because that is what handleGrapheme measures every printed cluster with, whatever DEC mode 2027 says. This is not a free choice: ultraviolet asks a uv.Screen which method it uses before building a cell to write into it, so answering wcwidth here while placing by grapheme width had ultraviolet build a cell one column narrower than the emulator would have written for the same text. That happens for exactly two classes, a base with an emoji presentation selector and a regional indicator pair, and one column is the whole bug: everything after the cluster shifts along the row, and in a multiplexer it shifts into the pane next door.
Reporting the method actually in use is the fix. Honouring mode 2027 would mean changing placement to match, which is a different and much larger change than making the answer true. For the same reason 2027 is permanently set: DECRQM answers 3, and a guest that resets it is ignored, so the answer stays true after the guest asks to change it. The ghostty backend does honour a reset of 2027, and its DECRQM answer says so.
func (*Emulator) WriteResponse ¶
WriteResponse writes data to the emulator's response pipe. This allows external code (e.g., daemon-side Kitty query handlers) to inject responses that will be forwarded to the PTY.
type EscHandler ¶
type EscHandler func() bool
EscHandler is a function that handles an ESC escape sequence.
type GuestColors ¶
type GuestColors struct {
Palette [256]color.Color // OSC 4 colours by slot
Fg, Bg, Cursor color.Color // OSC 10, 11 and 12 colours
}
GuestColors is what a guest set with OSC 4 (Palette, by slot) and with OSC 10, 11 and 12 (the default foreground, background and cursor colours). A nil entry is one the guest has not set, or has reset.
type KeyPressEvent ¶
type KeyPressEvent = uv.KeyPressEvent
KeyPressEvent represents a key press event.
type KittyCommand ¶
type KittyCommand struct {
Action KittyGraphicsAction // a, what the command asks for
Quiet int // q, 1 drops OK replies and 2 drops every reply
ImageID uint32 // i, the image id
ImageNumber uint32 // I, the image number the terminal maps to an id
PlacementID uint32 // p, the placement id
Format KittyGraphicsFormat // f, the pixel format
Medium KittyGraphicsMedium // t, how the image is carried
Compression KittyGraphicsCompression // o, the payload compression
Width int // s, the image width in pixels
Height int // v, the image height in pixels
Size int // S, how many bytes to read from a file
Offset int // O, where in a file to start reading
More bool // m=1, more chunks of this upload follow
Delete KittyDeleteTarget // d, what a delete takes down
XOffset int // X, pixel offset inside the first cell
YOffset int // Y, pixel offset inside the first cell
SourceX int // x, left edge of the source rectangle in pixels
SourceY int // y, top edge of the source rectangle in pixels
SourceWidth int // w, width of the source rectangle in pixels
SourceHeight int // h, height of the source rectangle in pixels
Columns int // c, columns the placement spans
Rows int // r, rows the placement spans
ZIndex int32 // z, stacking order against text and other images
CursorMove int // C=1 leaves the cursor where it is
Virtual bool // U=1, a virtual placement for Unicode placeholders
Data []byte // decoded payload when the medium is direct
RawPayload string // Original base64 payload (preserved for passthrough without re-encoding)
FilePath string // decoded payload when the medium names a file
// PayloadErr is set when the payload could not be decoded as base64. Data
// and FilePath are then empty: the undecoded text is never image data.
PayloadErr error
// BackgroundColor is the Y key read as a 32-bit RGBA colour, which is what
// a=f means by it. YOffset holds the same key read as a placement offset;
// the two never apply to the same command, and a colour overflows int on a
// 32-bit build, so it needs its own width.
BackgroundColor uint32
// contains filtered or unexported fields
}
KittyCommand is one parsed kitty graphics command (APC G). Each field holds one control key. A key the command does not carry leaves its zero value.
func ParseKittyCommand ¶
func ParseKittyCommand(data []byte) (*KittyCommand, error)
ParseKittyCommand parses the body of a kitty graphics APC, the bytes after the leading 'G'. A payload that is not valid base64 is not an error here: the command is returned with PayloadErr set and no Data or FilePath, so the caller can still answer the guest and drop the transmission it was part of.
func ParseKittyHeader ¶
func ParseKittyHeader(data []byte) (*KittyCommand, error)
ParseKittyHeader parses the body of a kitty graphics APC like ParseKittyCommand, but leaves the image data undecoded: Data stays empty, and RawPayload is kept only when it is short enough to be an echoed reply (see IsKittyResponsePayload). The payload of a shared memory (t=s) or temp file (t=t) transmission is decoded into FilePath, because it is only a name and the daemon deletes the objects no client reads.
It is for a reader that acts on the control keys alone, such as the daemon, which answers queries and refuses animation and never draws. Decoding a 1.5 MB frame there only to throw it away cost more than parsing it.
The payload is still decoded when an EINVAL reply would be owed for it (see KittyPayloadErrorResponse), so PayloadErr is set whenever it decides a reply. That is the first chunk of a transmission with an id and without q=2, or a query. The later chunks of a transmission carry no id, and a stream sent with q=2 owes no reply, so neither is decoded.
type KittyDeleteTarget ¶
type KittyDeleteTarget byte
KittyDeleteTarget is what a kitty graphics delete takes down, the d key. A lower-case value removes placements only. Its upper-case form also frees the image data.
const ( KittyDeleteAll KittyDeleteTarget = 'a' // d=a, every placement on the screen KittyDeleteAllFree KittyDeleteTarget = 'A' // d=A, as d=a and also frees the image data KittyDeleteByID KittyDeleteTarget = 'i' // d=i, the placements of image i, or placement p of it KittyDeleteByIDFree KittyDeleteTarget = 'I' // d=I, as d=i and also frees the image data KittyDeleteByNumber KittyDeleteTarget = 'n' // d=n, as d=i for the newest image with number I KittyDeleteByNumberFree KittyDeleteTarget = 'N' // d=N, as d=n and also frees the image data KittyDeleteAtCursor KittyDeleteTarget = 'c' // d=c, placements over the cursor cell KittyDeleteAtCursorFree KittyDeleteTarget = 'C' // d=C, as d=c and also frees the image data KittyDeleteAtCell KittyDeleteTarget = 'p' // d=p, placements over the cell at x, y KittyDeleteAtCellFree KittyDeleteTarget = 'P' // d=P, as d=p and also frees the image data KittyDeleteAtCellZ KittyDeleteTarget = 'q' // d=q, placements over the cell at x, y with z-index z KittyDeleteAtCellZFree KittyDeleteTarget = 'Q' // d=Q, as d=q and also frees the image data KittyDeleteAtColumn KittyDeleteTarget = 'x' // d=x, placements over column x KittyDeleteAtColumnFree KittyDeleteTarget = 'X' // d=X, as d=x and also frees the image data KittyDeleteAtRow KittyDeleteTarget = 'y' // d=y, placements over row y KittyDeleteAtRowFree KittyDeleteTarget = 'Y' // d=Y, as d=y and also frees the image data KittyDeleteAtZIndex KittyDeleteTarget = 'z' // d=z, placements at z-index z KittyDeleteAtZIndexFree KittyDeleteTarget = 'Z' // d=Z, as d=z and also frees the image data KittyDeleteIDRange KittyDeleteTarget = 'r' // d=r, the placements of images with ids from x to y KittyDeleteIDRangeFree KittyDeleteTarget = 'R' // d=R, as d=r and also frees the image data KittyDeleteFrames KittyDeleteTarget = 'f' // d=f, the animation frames of image i KittyDeleteFramesFree KittyDeleteTarget = 'F' // d=F, as d=f and also frees the image data )
type KittyGraphicsAction ¶
type KittyGraphicsAction byte
KittyGraphicsAction is what a kitty graphics command asks for, the a key.
const ( KittyActionQuery KittyGraphicsAction = 'q' // probe support without storing an image KittyActionTransmit KittyGraphicsAction = 't' // upload an image KittyActionTransmitPlace KittyGraphicsAction = 'T' // upload an image and place it KittyActionPlace KittyGraphicsAction = 'p' // place an uploaded image KittyActionDelete KittyGraphicsAction = 'd' // delete placements or images, see KittyDeleteTarget KittyActionFrame KittyGraphicsAction = 'f' // send an animation frame KittyActionAnimation KittyGraphicsAction = 'a' // control an animation KittyActionCompose KittyGraphicsAction = 'c' // compose one frame onto another )
type KittyGraphicsCompression ¶
type KittyGraphicsCompression uint8
KittyGraphicsCompression is the compression of a kitty graphics payload, the o key.
const ( KittyCompressionNone KittyGraphicsCompression = 0 // no o key KittyCompressionZlib KittyGraphicsCompression = 1 // o=z, zlib deflate )
type KittyGraphicsFormat ¶
type KittyGraphicsFormat uint8
KittyGraphicsFormat is the pixel format of a kitty graphics upload, the f key.
const ( KittyFormatRGB KittyGraphicsFormat = 24 // f=24, raw 8-bit RGB KittyFormatRGBA KittyGraphicsFormat = 32 // f=32, raw 8-bit RGBA KittyFormatPNG KittyGraphicsFormat = 100 // f=100, PNG data )
type KittyGraphicsMedium ¶
type KittyGraphicsMedium byte
KittyGraphicsMedium is how a kitty graphics upload carries its image, the t key.
const ( KittyMediumDirect KittyGraphicsMedium = 'd' // image bytes in the payload KittyMediumFile KittyGraphicsMedium = 'f' // payload names a file KittyMediumTempFile KittyGraphicsMedium = 't' // payload names a temporary file to delete after reading )
func (KittyGraphicsMedium) IsFile ¶
func (m KittyGraphicsMedium) IsFile() bool
IsFile reports whether the medium names something on the machine the terminal runs on (a file, a temporary file or a shared memory object) instead of carrying the image bytes in the payload.
type KittyGuestImages ¶
type KittyGuestImages struct {
// contains filtered or unexported fields
}
KittyGuestImages is what one pane's emulator knows about the images its guest named: which id each image number (I=) stands for, which ids hold an image, and the answer owed to an upload that is still arriving in chunks.
It lives in the emulator because every emulator of a pane sees the same commands in the same order: the daemon's, and each attached client's. The ids it gives follow from that order. A client that attaches later has not seen the commands before it attached, so it takes the daemon's record with the snapshot it restores (see KittyGuestImagesState). From there it gives the same ids as the daemon.
The answers go out through the emulator's response pipe, and only the emulator that is set to answer writes them (SetKittyUploadAnswers). A daemon's emulator answers. A client emulator of a daemon pane does not, and its pipe is drained anyway, so a guest gets one answer however many clients are attached.
The zero value answers and is ready to use.
func (*KittyGuestImages) Handle ¶
func (g *KittyGuestImages) Handle(cmd *KittyCommand, write func([]byte)) bool
Handle resolves a command's image number, keeps the record of which ids hold an image, and answers what kitty answers: the last chunk of an upload that named its image, and a placement. write sends an answer to the guest. It reports false when the command must not reach the passthrough: it names both i= and I=, or a number or an image the pane does not have.
func (*KittyGuestImages) Restore ¶
func (g *KittyGuestImages) Restore(s *KittyGuestImagesState)
Restore replaces the record with the daemon's. A nil state, from a daemon that sends none, leaves the record as it is.
func (*KittyGuestImages) SetAnswers ¶
func (g *KittyGuestImages) SetAnswers(on bool)
SetAnswers says whether this record answers the guest. Off, it still gives ids, and it opens no file.
func (*KittyGuestImages) SetFilesElsewhere ¶
func (g *KittyGuestImages) SetFilesElsewhere(on bool)
SetFilesElsewhere says the pane runs on another machine. Its file medium uploads are refused without a look at the file.
func (*KittyGuestImages) State ¶
func (g *KittyGuestImages) State() *KittyGuestImagesState
State returns a copy of what a late client needs.
type KittyGuestImagesState ¶
type KittyGuestImagesState struct {
Numbers map[uint32]uint32 `json:"numbers,omitempty"` // image number to the id it stands for
Known []uint32 `json:"known,omitempty"` // ids that hold an image
Next uint32 `json:"next,omitempty"` // next id to give an image sent by number
GuestHigh []uint32 `json:"guest_high,omitempty"` // ids at or above kittyImageNumberIDBase the guest chose itself
}
KittyGuestImagesState is the part of KittyGuestImages a client takes from the daemon when it attaches, so both give an image number the same id.
type KittyImageIDTranslator ¶
KittyImageIDTranslator turns a guest's image id into the id the host knows that image by. It reports false when the image has no host id yet, in which case the cell is left as the guest wrote it.
type KittyPlaceholderMode ¶
type KittyPlaceholderMode int
KittyPlaceholderMode says what the emulator does with placeholder cells.
const ( // KittyPlaceholdersDrop discards placeholder cells, which is what a host // that cannot draw them needs: kept, they render as missing-glyph boxes // where the picture should be, which is worse than the blank space the // application left room for. This is the default, so a caller that never // asks is never surprised. KittyPlaceholdersDrop KittyPlaceholderMode = iota // KittyPlaceholdersKeep stores them so they reach the host and it draws // the image. KittyPlaceholdersKeep )
type KittyState ¶
type KittyState struct {
// contains filtered or unexported fields
}
KittyState is the clear-notification relay between the emulator and the passthrough layer: a guest screen clear (ED, mode reset) must also clear the images the passthrough painted on the host terminal.
func NewKittyState ¶
func NewKittyState() *KittyState
NewKittyState returns a KittyState with no clear callback.
func (*KittyState) ClearPlacements ¶
func (s *KittyState) ClearPlacements()
ClearPlacements reports a guest screen clear to the passthrough layer, which owns the placements.
func (*KittyState) SetClearCallback ¶
func (s *KittyState) SetClearCallback(fn func())
SetClearCallback registers the passthrough hook fired on guest screen clears.
type Logger ¶
type Logger interface {
// Printf logs a message formatted as fmt.Printf does.
Printf(format string, v ...any)
}
Logger represents a logger interface.
type MouseButton ¶
type MouseButton = uv.MouseButton
MouseButton represents the button that was pressed during a mouse message.
type MouseMotion ¶
type MouseMotion = uv.MouseMotionEvent
MouseMotion represents a mouse motion event.
type MousePixel ¶
MousePixel is the pointer's position inside the pane in pixels, measured from the top-left pixel of the pane's first cell. A guest in SGR-pixel mode (DEC 1016) is told this position. OK is false when the host reported the pointer in cells only; the report then falls back to the cell centre.
type MouseRelease ¶
type MouseRelease = uv.MouseReleaseEvent
MouseRelease represents a mouse release event.
type OscHandler ¶
OscHandler is a function that handles an OSC escape sequence.
type ProgressState ¶
type ProgressState int
ProgressState is the state field of an OSC 9;4 progress report, the ConEmu progress sequence. It is a structured, in-band statement by the program in the pane about whether it is busy, which is why tuios reads it: a coding agent that emits it is describing its own state far more honestly than any guess made from its output.
const ( // ProgressClear removes the progress indicator: the program is no longer // busy. ProgressClear ProgressState = 0 // ProgressNormal is a determinate progress bar carrying a percentage. ProgressNormal ProgressState = 1 // ProgressError means the operation failed. ProgressError ProgressState = 2 // ProgressIndeterminate is a busy indicator with no known percentage. ProgressIndeterminate ProgressState = 3 // ProgressWarning is a determinate bar flagged as needing attention. ProgressWarning ProgressState = 4 )
type SavedCursor ¶
type SavedCursor struct {
X, Y int // cursor position, zero-based
Pen uv.Style // rendition
Link uv.Link // hyperlink the pen held
PendingWrap bool // wrap pending at the last column
Origin bool // origin mode (DECOM)
Protected bool // DECSCA protection
// Charsets names the set in G0 to G3 by its designator byte, as
// Charsets does. A zero byte reads as US ASCII.
Charsets [4]byte
GL, GR int // the G sets invoked into GL and GR, 0 to 3
}
SavedCursor is the state DECSC saves and DECRC puts back: the position, the pen, the pending-wrap flag, origin mode, DECSCA protection and the character set selection. Link is the hyperlink the pen held, which the pure emulator saves with it and libghostty does not.
type Screen ¶
type Screen interface {
// Write feeds the emulator what the program printed.
io.Writer
// Read returns the replies the emulator sends the program, such as the
// answer to a cursor position query. It blocks until there is a reply,
// and returns io.EOF after Close.
Read(p []byte) (n int, err error)
// Resize sets the screen size in cells.
Resize(width, height int)
// Width returns the width of the screen in cells.
Width() int
// Height returns the height of the screen in cells.
Height() int
// CellAt returns the cell at column x, row y, for reading only. It
// returns nil outside the screen.
CellAt(x, y int) *uv.Cell
// CursorPosition returns the cursor's column and row.
CursorPosition() uv.Position
// Render returns the screen as text, with its styles and links as escape
// sequences.
Render() string
// String returns the text of the screen without styles.
String() string
// Close stops the emulator and makes a blocked Read return io.EOF.
Close() error
}
Screen is the part of an emulator most programs need: what a program prints goes in, the screen comes out, and the emulator's replies go back to the program. Terminal has everything tuios uses, and every Terminal is a Screen.
type Scrollback ¶
type Scrollback struct {
// contains filtered or unexported fields
}
Scrollback is the ring of lines that have scrolled off the top of the screen. It is a ring so a push is O(1) once the ring is full.
Lines are stored encoded, not as uv.Line. A uv.Cell is 112 bytes: a string header, three colour interfaces, a link of two strings and an int width. A scrollback line kept in that form costs terminal width times 112 bytes no matter what is on it, so at the default 10000 lines a 207-column pane held 232 MB the moment its ring filled, and the daemon and every attached client each held their own copy. An earlier packing brought a cell down to 24 bytes, which is still 24 bytes for a plain letter: the same text as UTF-8 is one byte.
So a line is stored as the bytes of its text, with a style or a link written once where it changes rather than once per cell; see encodeLine. A plain line of a build log costs its length in bytes. A line is stored only up to its last cell that is not blank, and the ring's own slice of line headers grows as lines arrive rather than being allocated at the ring's capacity, so a pane that has printed nothing holds nothing. Reads decode back to uv.Line, padded to the width the line had, through a small cache so a render of a scrolled pane, which asks for the same line once per column, decodes each line once.
func NewScrollback ¶
func NewScrollback(maxLines int) *Scrollback
NewScrollback creates a scrollback ring of maxLines lines. Zero or less means DefaultScrollbackSize.
func (*Scrollback) Clear ¶
func (sb *Scrollback) Clear()
Clear drops every line and the storage behind it.
func (*Scrollback) Discard ¶
func (sb *Scrollback) Discard()
Discard empties the ring and makes it drop every line pushed from now on, before the line is encoded. It is for an emulator whose history nobody reads: tuios gui-bridge runs one per pane only to follow titles, folders and modes, and its renderer keeps the history. Encoding each line that scrolled off was about a third of that process's work under a flood.
func (*Scrollback) Len ¶
func (sb *Scrollback) Len() int
Len returns the number of lines in the ring.
func (*Scrollback) Line ¶
func (sb *Scrollback) Line(index int) uv.Line
Line returns the line at index, oldest first, decoded to its original width, or nil when index is out of range. The result is shared with later calls for the same index until the ring changes, so callers must not write to it.
func (*Scrollback) LineWrapped ¶
func (sb *Scrollback) LineWrapped(index int) bool
LineWrapped reports whether the line at index, oldest first, carried on to the next line by autowrap. The last line of the ring carries on to the screen's first row.
func (*Scrollback) Lines ¶
func (sb *Scrollback) Lines() []uv.Line
Lines returns every line in the ring, oldest first, each decoded fresh.
func (*Scrollback) MaxLines ¶
func (sb *Scrollback) MaxLines() int
MaxLines returns the ring's capacity.
func (*Scrollback) PushBlankLine ¶
func (sb *Scrollback) PushBlankLine(width int)
PushBlankLine stores a blank line of the given width as the newest scrollback line: what a row of the screen that nothing has written holds.
func (*Scrollback) PushLine ¶
func (sb *Scrollback) PushLine(line uv.Line)
PushLine stores a copy of line as the newest scrollback line. The caller keeps line and may go on writing to it: nothing here aliases it.
Into a full ring the push reuses the storage of the line it evicts when that is large enough, so a steady flood of similar lines allocates nothing.
func (*Scrollback) SetMaxLines ¶
func (sb *Scrollback) SetMaxLines(maxLines int)
SetMaxLines resizes the ring, keeping the newest lines that fit.
func (*Scrollback) SetOnTrim ¶
func (sb *Scrollback) SetOnTrim(fn func(int))
SetOnTrim sets a callback that fires when the ring overwrites oldest lines.
type ScrollbackCopy ¶
type ScrollbackCopy struct {
// contains filtered or unexported fields
}
ScrollbackCopy is a run of history lines copied out of a terminal in the form the pure emulator's ring keeps them, a byte or so a cell for text. A reader copies the lines while it holds the terminal's lock and decodes them after releasing it, so the terminal is held for a copy of the encoded bytes and not for the decode.
A backend that cannot copy its lines cheaply copies something else under the lock and makes the lines from it on first use: see build.
func (*ScrollbackCopy) Len ¶
func (c *ScrollbackCopy) Len() int
Len is the number of lines in the copy.
func (*ScrollbackCopy) Padded ¶
func (c *ScrollbackCopy) Padded(index int) bool
Padded reports whether line index of the copy wrapped a column early before a wide character. See Terminal.ScrollbackPadded.
func (*ScrollbackCopy) Rows ¶
Rows calls fn with the copy's lines from index from to end-1, counted from the copy's first line, each decoded to its full width into a buffer reused from line to line. fn must copy what it keeps. It stops when fn returns false.
func (*ScrollbackCopy) Text ¶
func (c *ScrollbackCopy) Text(from, end int, fn func(index, width int, cells []TextCell) bool)
Text is Rows for a reader of text: see Terminal.ScrollbackText.
func (*ScrollbackCopy) Wrapped ¶
func (c *ScrollbackCopy) Wrapped(index int) bool
Wrapped reports whether line index of the copy carried on to the next line by autowrap.
type SemanticMarker ¶
type SemanticMarker struct {
Type SemanticMarkerType // which OSC 133 marker this is
AbsLine int // scrollbackLen + cursorY at time of emission
Col int // cursor X (column) at time of emission
ExitCode int // only meaningful for 'D', -1 = unknown
CapturedText string // command text captured at C-marker time (before output)
}
SemanticMarker represents a single OSC 133 marker captured from the terminal.
type SemanticMarkerList ¶
type SemanticMarkerList struct {
// contains filtered or unexported fields
}
SemanticMarkerList is a thread-safe, bounded list of semantic markers.
A marker's line is kept relative to an origin that only moves forward: the list stores AbsLine plus trimmed, the number of lines the scrollback had dropped when the marker was added, and every reader subtracts the current trimmed again. A scrollback trim then only moves the origin. It used to rewrite every marker's line under the lock, once per line a full ring dropped, which on a flooding pane was 8% of the daemon's time and grew with the number of markers.
A marker whose line has fallen below the origin is gone. The trim drops those at the front, and readers skip any left behind later in the list (a marker can follow one on a lower line when the cursor moved up between them).
func NewSemanticMarkerList ¶
func NewSemanticMarkerList(maxItems int) *SemanticMarkerList
NewSemanticMarkerList creates a new marker list with the given capacity.
func (*SemanticMarkerList) Add ¶
func (l *SemanticMarkerList) Add(m SemanticMarker)
Add appends a marker to the list, discarding the oldest if at capacity.
func (*SemanticMarkerList) AdjustForScrollbackTrim ¶
func (l *SemanticMarkerList) AdjustForScrollbackTrim(linesRemoved int)
AdjustForScrollbackTrim moves the list's origin when scrollback lines are trimmed from the ring buffer, which lowers every marker's AbsLine by linesRemoved. Markers that fall before the new origin are removed. It costs nothing when the list is empty, and otherwise only drops what fell off the front.
func (*SemanticMarkerList) Last ¶
func (l *SemanticMarkerList) Last(t SemanticMarkerType) *SemanticMarker
Last returns a copy of the most recent marker of the given type, or nil if none.
func (*SemanticMarkerList) Len ¶
func (l *SemanticMarkerList) Len() int
Len returns the number of markers.
func (*SemanticMarkerList) Markers ¶
func (l *SemanticMarkerList) Markers() []SemanticMarker
Markers returns a copy of all markers.
func (*SemanticMarkerList) RemoveOnScreen ¶
func (l *SemanticMarkerList) RemoveOnScreen(scrollbackLen int)
RemoveOnScreen removes markers whose AbsLine >= scrollbackLen, i.e. markers that reference visible screen content. Used when the screen is cleared (CSI 2J) so that stale on-screen markers don't cause output extraction to read overwritten content after new commands run.
func (*SemanticMarkerList) Trimmed ¶
func (l *SemanticMarkerList) Trimmed() int
Trimmed is the list's origin: how many scrollback lines it has seen dropped since it was made. A row read now plus Trimmed is a row that stays the same line however much more the scrollback drops. A row stored that way is turned back into today's row by subtracting Trimmed again.
type SemanticMarkerType ¶
type SemanticMarkerType byte
SemanticMarkerType represents an OSC 133 semantic zone marker type.
const ( // MarkerPromptStart is 'A': prompt start MarkerPromptStart SemanticMarkerType = 'A' // MarkerCommandStart is 'B': command input start (after prompt) MarkerCommandStart SemanticMarkerType = 'B' // MarkerCommandExecuted is 'C': command execution start (output begins) MarkerCommandExecuted SemanticMarkerType = 'C' // MarkerCommandFinished is 'D': command finished (exit code available) MarkerCommandFinished SemanticMarkerType = 'D' )
type SixelAction ¶
type SixelAction int
SixelAction represents the type of sixel operation.
const ( SixelActionDisplay SixelAction = iota // Display sixel image at cursor SixelActionQuery // Query sixel support (rarely used) )
type SixelCommand ¶
type SixelCommand struct {
// AspectRatio specifies the pixel aspect ratio
// 0,1 = 2:1 (default), 2 = 5:1, 3,4 = 3:1, 5,6 = 2:1, 7,8,9 = 1:1
AspectRatio int
// BackgroundMode specifies how the background is handled
// 0 = device default, 1 = no change (transparent), 2 = set to color 0
BackgroundMode int
// HorizontalGrid is deprecated but may be present (ignored)
HorizontalGrid int
// Width is the calculated width of the image in pixels
Width int
// Height is the calculated height of the image in pixels
Height int
// Data contains the raw sixel raster data (after the 'q' introducer)
Data []byte
// RawSequence contains the complete DCS sequence for passthrough
RawSequence []byte
// CellWidth and CellHeight are the cell size in pixels the emulator
// measured the image against, set before the passthrough sees it. The
// image's marker cells were counted at this size, so the compositor
// maps a cell back to its pixels with it.
CellWidth, CellHeight int
}
SixelCommand represents a parsed Sixel graphics command. Sixel DCS format: ESC P <p1>;<p2>;<p3> q <sixel-data> ST
func ParseSixelCommand ¶
func ParseSixelCommand(data []byte) *SixelCommand
ParseSixelCommand parses a DCS sixel sequence. The data parameter should contain everything after the DCS introducer, including parameters, the 'q' introducer, and sixel data.
func (*SixelCommand) ColsForWidth ¶
func (cmd *SixelCommand) ColsForWidth(cellWidth int) int
ColsForWidth returns the number of terminal columns needed for a sixel image given its pixel width and the terminal's cell width.
func (*SixelCommand) RowsForHeight ¶
func (cmd *SixelCommand) RowsForHeight(cellHeight int) int
RowsForHeight returns the number of terminal rows needed for a sixel image given its pixel height and the terminal's cell height.
type SixelImage ¶
type SixelImage struct {
Width, Height int // size in pixels
// Pix holds one entry per pixel, row by row. Zero is a pixel no sixel
// painted, which is drawn transparent; n is palette register n-1.
Pix []uint16
// Palette is indexed by register. Registers the image never set keep the
// VT340 defaults, as a terminal would.
Palette []color.RGBA
// Exact says the guest's own bytes draw exactly this image on a sixel
// terminal, so they may be sent as they are. It is false when the data
// painted past the size the raster attributes declared (a terminal would
// paint those pixels over whatever is beside the image's cells), when it
// used a register past the 256 a pane is told it has, or when it asked
// for an opaque background and left pixels unpainted (terminals disagree
// on what fills them). Such an image is always re-encoded from Pix.
Exact bool
}
SixelImage is a decoded sixel picture: one palette index per pixel, and the palette.
It is kept indexed rather than expanded to RGBA for two reasons. A sixel image is already paletted, so a crop re-encoded from the indices keeps every colour exactly as the program chose it, with no quantising step. And it is half the memory of RGBA at two bytes a pixel, which matters because a pane can hold a screenful of pictures in its scrollback.
func DecodeSixel ¶
func DecodeSixel(cmd *SixelCommand) *SixelImage
DecodeSixel paints cmd's sixel data into an image of cmd.Width by cmd.Height pixels, the size the emulator already used to reserve the image's cells. Pixels drawn past that size are dropped, so the picture and the cells it owns always agree. It returns nil when the image is empty or larger than the limits above.
func (*SixelImage) At ¶
func (img *SixelImage) At(x, y int) (color.RGBA, bool)
At returns the colour of one pixel, and false for a transparent one.
func (*SixelImage) Bytes ¶
func (img *SixelImage) Bytes() int
Bytes is the memory the image holds, for the per-pane budget.
type SixelPassthroughFunc ¶
type SixelPassthroughFunc func(cmd *SixelCommand, cursorX, cursorY int) uint32
SixelPassthroughFunc receives a guest's sixel image and the cursor it was drawn at, and returns the id to mark the image's cells with, or 0 when the image will not be shown.
type SosHandler ¶
SosHandler is a function that handles an SOS escape sequence.
type Terminal ¶
type Terminal interface {
// Byte I/O and lifecycle. Write feeds raw PTY bytes; Read drains query
// responses (DA, CPR, ...) the emulator wants sent back to the guest;
// WriteResponse queues a response produced outside the emulator.
Write(p []byte) (n int, err error)
// Read drains the responses the emulator wants sent back to the guest.
// It returns io.EOF after Close.
Read(p []byte) (n int, err error)
// TakeResponses removes and returns the queued responses without
// blocking, or nil when there are none. A host that drains after each
// Write uses it instead of a goroutine blocked in Read.
TakeResponses() []byte
// WriteResponse queues data to come out of Read, for a response made outside
// the emulator.
WriteResponse(data []byte)
// Close stops the emulator and makes a blocked Read return io.EOF.
Close() error
// Resize sets the screen size in cells. A size below 1 counts as 1.
Resize(width int, height int)
// Grid reads. CellAt addresses the active screen, MainCellAt the main
// screen even while the alternate screen is active. Both hand out a
// pointer for reading only: a row nothing has printed on is served from
// one shared blank cell, and a write through the pointer would show on
// every blank cell of every pane. Writes go through SetCell.
Width() int
// Height returns the height of the screen in cells.
Height() int
// Bounds returns the screen as a rectangle at the origin.
Bounds() uv.Rectangle
// CellAt returns the cell at x, y of the active screen, for reading only.
CellAt(x, y int) *uv.Cell
// MainCellAt returns the cell at x, y of the main screen, for reading only.
MainCellAt(x, y int) *uv.Cell
// Render returns the active screen as text with its styles and links
// encoded as escape sequences.
Render() string
// String returns the text of the active screen without styles.
String() string
// TailText returns the last n rows of the active screen that carry text,
// in reading order. Blank rows are skipped.
TailText(n int) []string
// Grid writes, used only to prime an emulator from a wire snapshot.
SetCell(x, y int, c *uv.Cell)
// SetMainCell writes c at x, y of the main screen.
SetMainCell(x, y int, c *uv.Cell)
// Cursor.
CursorPosition() uv.Position
// IsCursorHidden reports whether the guest has hidden the cursor.
IsCursorHidden() bool
// CursorPen returns the style and hyperlink the next printed character
// gets.
CursorPen() (uv.Style, uv.Link)
// CursorStyle returns the cursor shape DECSCUSR last set, and whether it
// is steady rather than blinking.
CursorStyle() (style CursorStyle, steady bool)
// GuestCursorColor is the cursor colour the guest set with OSC 12 and
// has not reset with OSC 112, or nil when it set none. Unlike
// GuestColors it copies no palette, so a renderer can read it per frame.
GuestCursorColor() color.Color
// RestoreCursorPosition moves the cursor to x, y without side effects, to
// prime an emulator from a snapshot.
RestoreCursorPosition(x, y int)
// CursorPendingWrap reports whether the cursor stands on the last column
// with a wrap pending: the next printed character goes to the start of
// the next row, not over the cell the cursor is on. The cursor position
// alone cannot say this.
CursorPendingWrap() bool
// RestoreCursorPendingWrap arms or clears the pending wrap, after
// RestoreCursorPosition has put the cursor back.
RestoreCursorPendingWrap(pending bool)
// RestoreCursorPen puts back the pen CursorPen returned, to prime an
// emulator from a snapshot.
RestoreCursorPen(pen uv.Style, link uv.Link)
// RestoreCursorStyle puts back the shape CursorStyle returned, to prime an
// emulator from a snapshot.
RestoreCursorStyle(style CursorStyle, steady bool)
// CursorProtected reports whether DECSCA protects what the guest prints
// next. RestoreCursorProtected puts it back.
CursorProtected() bool
// RestoreCursorProtected sets the protection CursorProtected reports.
RestoreCursorProtected(on bool)
// SavedCursor is what DECSC last saved on the active screen, or with main
// set on the main screen under an active alternate one. A screen that
// never saved a cursor reports the zero SavedCursor, which is where a
// DECRC with nothing saved goes. RestoreSavedCursor puts one back.
SavedCursor(main bool) SavedCursor
// RestoreSavedCursor puts back the cursor SavedCursor returned.
RestoreSavedCursor(main bool, c SavedCursor)
// LastPrinted is the character REP repeats, as the guest sent it, before
// any character set maps it. It is empty when nothing has been printed
// since the last reset. RestoreLastPrinted puts it back.
LastPrinted() string
// RestoreLastPrinted puts back the character LastPrinted returned.
RestoreLastPrinted(cluster string)
// Tab stops. TabStops lists the columns that hold a stop, in order.
// RestoreTabStops replaces the table with the columns given, after any
// resize, since a resize to a new width resets the table. A column off
// the screen is dropped.
TabStops() []int
// RestoreTabStops sets a tab stop at each column in cols and clears the
// others.
RestoreTabStops(cols []int)
// Titles is the window title, the icon name and what XTWINOPS 22 saved.
// RestoreTitles puts all three back, keeping the newest entries of a
// stack longer than XTWINOPS keeps. It does not tell the host through
// the Title callback, except on the libghostty backend, whose library
// takes a title only as OSC 2 and reports each one it takes.
Titles() Titles
// RestoreTitles puts back the titles Titles returned.
RestoreTitles(t Titles)
// GuestColors is what the guest set with OSC 4, 10, 11 and 12 and has
// not reset. RestoreGuestColors replaces all of it.
GuestColors() GuestColors
// RestoreGuestColors replaces the colours the guest set with c.
RestoreGuestColors(c GuestColors)
// ANSIModes reports the ANSI (not DEC private) modes the emulator
// implements, by number: insert mode (4) and newline mode (20) on both
// backends. GetModes cannot carry them, because the two kinds share a
// number space there. RestoreANSIModes sets them without side effects
// and ignores a mode the emulator does not implement.
ANSIModes() map[int]bool
// RestoreANSIModes sets the ANSI modes ANSIModes returned.
RestoreANSIModes(modes map[int]bool)
// PendingInput is the input since the parser last left its ground
// state: the start of an escape sequence or of a UTF-8 character that
// has not ended yet, without a control the parser has already carried
// out inside it. It is empty at ground and at most MaxPendingInput
// bytes. A snapshot carries it, because the rest of the sequence
// arrives after the snapshot and an emulator at ground prints it as
// text. RestorePendingInput drops whatever unfinished input the
// emulator holds and then reads p, so the next byte continues p.
PendingInput() []byte
// RestorePendingInput replaces the unfinished input with p.
RestorePendingInput(p []byte)
// Protected cells. ProtectedCells lists the cells DECSCA protected on
// the active screen, or with main set on the main screen under an active
// alternate one, as runs along a row. RestoreProtectedCells replaces the
// protection on that screen with the runs given, after the cells are
// written: SetCell leaves a cell unprotected.
ProtectedCells(main bool) []CellRun
// RestoreProtectedCells replaces the DECSCA protection of a screen with
// runs.
RestoreProtectedCells(main bool, runs []CellRun)
// Screen and mode state. The Restore* half of each pair exists for the
// same snapshot priming as SetCell.
IsAltScreen() bool
// ActiveScreenIsAlt reports whether the emulator reads and writes the
// alternate screen. It is for diagnostics: IsAltScreen reports the mode.
ActiveScreenIsAlt() bool
// RestoreAltScreenMode makes the alternate or the main screen active
// without clearing it and without changing the modes.
RestoreAltScreenMode(enabled bool)
// IsSyncActive reports whether the guest has a synchronized update (mode
// 2026) open. An update held open too long reads as closed.
IsSyncActive() bool
// SyncUpdate reports what IsSyncActive does, and a serial that changes
// each time the guest opens a new synchronized update.
SyncUpdate() (open bool, serial uint64)
// GetModes returns a copy of the DEC private modes the guest has set or
// reset, by number.
GetModes() map[int]bool
// RestoreModes sets the DEC private modes GetModes returned, without the
// side effects of a mode change.
RestoreModes(modes map[int]bool)
// ScrollRegion returns the margins the guest set with DECSTBM and DECSLRM,
// or the whole screen.
ScrollRegion() uv.Rectangle
// RestoreScrollRegion puts back the margins ScrollRegion returned. An empty
// r changes nothing.
RestoreScrollRegion(r uv.Rectangle)
// ResetScrollRegion makes the whole screen scroll.
ResetScrollRegion()
// Charsets returns the designator byte of the character set in each of G0
// to G3, and which of them GL and GR select.
Charsets() (ids [4]byte, gl, gr int)
// RestoreCharsets puts back the selection Charsets returned.
RestoreCharsets(ids [4]byte, gl, gr int)
// ApplicationCursorKeys reports whether DECCKM is set, so cursor keys send
// SS3 sequences.
ApplicationCursorKeys() bool
// BracketedPasteEnabled reports whether bracketed paste (mode 2004) is on.
BracketedPasteEnabled() bool
// FocusReportingEnabled reports whether focus reporting (mode 1004) is on.
FocusReportingEnabled() bool
// Soft wraps. RowSoftWrapped reports whether a row of the active screen
// carries on to the next row because autowrap moved the text there, as
// opposed to a line that happens to fill the row and then ends.
// ScrollbackSoftWrapped is the same for a history line, oldest first.
// known is false where the backend cannot tell, and a caller must then
// treat the row as ending.
RowSoftWrapped(y int) (wrapped, known bool)
// ScrollbackSoftWrapped is RowSoftWrapped for history line index, oldest
// first.
ScrollbackSoftWrapped(index int) (wrapped, known bool)
// RestoreSoftWraps sets the soft-wrap flags a snapshot carries, after
// its cells are written: screen is one flag per row of the active screen,
// and history one per row of the newest history rows, oldest first,
// aligned to the end of the history. A row with no flag given reads as
// ending, so a nil screen clears every screen row, and a nil history
// clears the newest history row, the one that could carry on into a
// screen the snapshot replaced. The screen under an active alternate
// screen is cleared too: its flags do not travel.
RestoreSoftWraps(screen, history []bool)
// RowPadded and ScrollbackPadded report whether a wrapped row ended a
// column early because a wide character did not fit in its last column,
// so that column is padding and not text. RestorePads sets the flags a
// snapshot carries, after RestoreSoftWraps, aligned the same way; it
// only marks rows that are wrapped. A backend that does not track it
// reports false and ignores the restore.
RowPadded(y int) bool
// ScrollbackPadded is RowPadded for history line index, oldest first.
ScrollbackPadded(index int) bool
// RestorePads sets the padding flags RowPadded and ScrollbackPadded report.
RestorePads(screen, history []bool)
// Scrollback.
ScrollbackLen() int
// ScrollbackGeneration changes whenever the main screen's history does:
// a line pushed, the ring trimmed, cleared or resized. A reader that
// derived something from the history can keep it while the number
// stays the same.
ScrollbackGeneration() uint64
// ScrollbackLine returns history line index, oldest first, or nil when
// index is out of range.
ScrollbackLine(index int) uv.Line
// ScrollbackRows, ScrollbackText and CopyScrollback are for a reader of
// many history lines at once. ScrollbackLine decodes each line into a
// fresh line of 112-byte cells and keeps the newest in a cache for the
// renderer, which a walk of the whole history churns and then pins.
// These go round the cache.
//
// ScrollbackRows calls fn with each history line from index from to
// end-1, oldest first, decoded to its full width into a buffer reused
// from line to line: fn must copy what it keeps. It stops when fn
// returns false. fn must not call the terminal, which may hold its own
// lock while fn runs.
ScrollbackRows(from, end int, fn func(index int, line uv.Line) bool)
// ScrollbackText is ScrollbackRows for a reader that wants only the
// text: each line is its cells' content and width, with no style and no
// cell built. cells runs up to the line's last stored cell, and the
// columns from len(cells) to width are spaces.
ScrollbackText(from, end int, fn func(index, width int, cells []TextCell) bool)
// CopyScrollback copies history lines from index from to end-1, with
// their wrap and padding flags, into a form a reader decodes after it
// releases the terminal.
CopyScrollback(from, end int) *ScrollbackCopy
// PushScrollbackLine appends line to the main screen's history, to prime
// an emulator from a snapshot.
PushScrollbackLine(line uv.Line)
// ClearScrollback empties the main screen's history.
ClearScrollback()
// SetScrollbackMaxLines sets how many lines the history keeps.
SetScrollbackMaxLines(maxLines int)
// Input encoding toward the guest.
SendMouse(m Mouse)
// EncodeMouseEvent returns the report the guest's mouse mode gives for m,
// or "" when the guest does not want it.
EncodeMouseEvent(m Mouse) string
// SendMouseAt and EncodeMouseEventAt also take the pointer's pixel
// position inside the pane, which a guest in SGR-pixel mode (1016) is
// told instead of the cell centre.
SendMouseAt(m Mouse, at MousePixel)
// EncodeMouseEventAt is EncodeMouseEvent with the pixel position at.
EncodeMouseEventAt(m Mouse, at MousePixel) string
// HasMouseMode reports whether the guest has any mouse tracking mode on.
HasMouseMode() bool
// HasPixelMouseMode reports whether the guest tracks the mouse in
// SGR-pixel mode (1016).
HasPixelMouseMode() bool
// HasAllMotionMode reports whether the guest tracks all mouse motion
// (mode 1003).
HasAllMotionMode() bool
// HasCellMotionMode reports whether the guest tracks motion while a button
// is pressed (mode 1002).
HasCellMotionMode() bool
// KittyKeyboardFlags returns the kitty keyboard protocol flags in effect.
KittyKeyboardFlags() int
// KittyKeyboardStack returns a copy of the active screen's kitty keyboard
// flag stack, base entry first.
KittyKeyboardStack() []int
// RestoreKittyKeyboardState puts back the stack KittyKeyboardStack
// returned, on the active screen. An empty stack changes nothing.
RestoreKittyKeyboardState(stack []int)
// KittyKeyboardMainStack is the main screen's flag stack while the
// alternate screen is in use, nil otherwise. RestoreKittyKeyboardMainStack
// puts it back.
KittyKeyboardMainStack() []int
// RestoreKittyKeyboardMainStack puts back the stack KittyKeyboardMainStack
// returned. An empty stack changes nothing.
RestoreKittyKeyboardMainStack(stack []int)
// DisableKittyKeyboardProtocol stops the emulator offering the kitty
// keyboard protocol, for a pane whose PTY cannot carry it. See
// Emulator.DisableKittyKeyboardProtocol.
DisableKittyKeyboardProtocol()
// was called.
KittyKeyboardUnavailable() bool
// ModifyOtherKeys is the xterm modifyOtherKeys level the guest set with
// XTMODKEYS (CSI > 4 ; n m): 0 off, 1 or 2. See EncodeModifyOtherKeys.
ModifyOtherKeys() int
// RestoreModifyOtherKeys puts back the level ModifyOtherKeys returned.
// A level outside 0 to 2 changes nothing.
RestoreModifyOtherKeys(level int)
// Colors.
SetThemeColors(fg, bg, cur color.Color, ansiPalette [16]color.Color)
// SetReportColors sets the colours an OSC 10 and OSC 11 query is answered
// with while the guest has not set its own: the ground the pane is really
// drawn on, when that is not the default. A nil colour keeps the default
// answer. Nothing is drawn differently; it only changes the answer.
SetReportColors(fg, bg color.Color)
// SetReportPalette sets what an OSC 4 query for one of the sixteen ANSI
// slots is answered with while neither the guest nor a theme has set that
// slot: the host terminal's own colour, when tuios knows it. A nil entry
// keeps the default answer. Like SetReportColors it changes only the
// answer; the slot is still drawn by the host.
SetReportPalette(pal [16]color.Color)
// PaletteColor returns the colour of ANSI slot i (0 to 15) as it is drawn,
// or nil for a slot out of range.
PaletteColor(i int) color.Color
// IndexedColor returns the colour of palette index i (0 to 255), or nil
// for an index out of range.
IndexedColor(i int) color.Color
// Host hooks and graphics state.
SetCallbacks(cb Callbacks)
// GetCallbacks returns the callbacks SetCallbacks installed.
GetCallbacks() Callbacks
// SetScreenClearFunc sets the ScreenClear callback and keeps the others.
SetScreenClearFunc(f func())
// SetKittyPassthroughFunc installs the reader of every graphics
// command. fn must not write to rawData: cmd.RawPayload shares its bytes.
SetKittyPassthroughFunc(fn func(cmd *KittyCommand, rawData []byte))
// SetKittyHeaderOnly says whether the passthrough acts on the control
// keys alone, so the payload is not decoded. See ParseKittyHeader.
SetKittyHeaderOnly(on bool)
// SetKittyUploadAnswers says whether this emulator answers the guest's
// kitty uploads and placements. A client emulator of a daemon pane does
// not: the daemon's does. See KittyGuestImages.
SetKittyUploadAnswers(on bool)
// SetKittyFilesElsewhere says the pane runs on another machine, so a file
// it names for an upload is refused without a look at it.
SetKittyFilesElsewhere(on bool)
// KittyGuestImagesState and RestoreKittyGuestImages carry the ids given
// to kitty image numbers from the daemon to a client that attaches.
KittyGuestImagesState() *KittyGuestImagesState
// RestoreKittyGuestImages puts back the state KittyGuestImagesState
// returned.
RestoreKittyGuestImages(s *KittyGuestImagesState)
// SetKittyImageIDTranslator installs the guest-to-host image id mapping
// used for kitty Unicode placeholder cells. See kitty_placeholder.go.
SetKittyImageIDTranslator(fn KittyImageIDTranslator)
// SetKittyPlaceholderMode says whether placeholder cells are kept or
// dropped. See kitty_placeholder.go.
SetKittyPlaceholderMode(m KittyPlaceholderMode)
// SetSixelPassthroughFunc installs the function that takes a guest's
// sixel image and returns the id its cells are marked with. See
// sixel_marker.go.
SetSixelPassthroughFunc(fn SixelPassthroughFunc)
// SetSixelAdvertised installs the function that decides whether the
// pane is told it can draw sixel: attribute 4 in the DA1 reply, and an
// answer to XTSMGRAPHICS. Nil tells it nothing.
SetSixelAdvertised(fn func() bool)
// SetTextSizingFunc installs the function that takes each OSC 66 text
// sizing sequence, with the cursor position, the scale and the length of
// the text in characters.
SetTextSizingFunc(fn func(rawOSC []byte, cursorX, cursorY, scale, textLen int))
// SetReflowFunc sets a function a resize calls after it reflowed rows.
// remap takes a row counted from the oldest history row, as an image
// placement records it, and returns where that row's text is now. A
// backend that cannot say never calls fn.
SetReflowFunc(fn func(remap func(absLine int) int))
// SetCellSize sets the size of one cell in pixels, for size reports and
// SGR-pixel mouse reports. A size below 1 is ignored.
SetCellSize(width, height int)
// KittyMainState returns the kitty image state of the main screen.
KittyMainState() *KittyState
// KittyAltState returns the kitty image state of the alternate screen.
KittyAltState() *KittyState
// ReserveImageSpace moves the cursor below an image rows high, scrolling
// as needed, so the next output does not cover the image.
ReserveImageSpace(rows, cols int)
// SemanticMarkers returns the OSC 133 prompt and command markers.
SemanticMarkers() *SemanticMarkerList
}
Terminal is the emulator surface the rest of tuios consumes. It exists so the implementation can be swapped at build time (see New): the pure-Go Emulator is the default, a libghostty-vt backed implementation is available behind the ghostty build tag. Exactly one implementation is compiled into a binary; differential comparison between the two lives in tests only.
The method set is the complete external surface of Emulator as of the extraction: every method here has at least one caller outside this package. Grow it only when a caller needs more, and implement additions on both backends in the same change.
Only package vt implements Terminal, and it may gain methods in any release. Use it, and do not implement it: a type outside this package that implements it can stop compiling on an update. A program that needs its own implementation should depend on Screen, which stays small.
func New ¶
New returns the emulator implementation selected at build time. The default build is pure Go so that go install works with no toolchain and CGO_ENABLED=0 cross-compilation keeps working; the ghostty build tag swaps in the libghostty-vt backed implementation.
func NewWithScrollback ¶
NewWithScrollback is New with the scrollback depth fixed at construction. Every pane is built through here because the libghostty backend can only take the depth when its terminal is made; see the ghostty variant.
type TextCell ¶
TextCell is one history cell without its style or link: what it shows and how many columns it takes. Content is the cell's text, empty for the spacer a wide character leaves in the column after it. It aliases the history's own storage, so it is valid only until the callback it was passed to returns.
type TitleEntry ¶
type TitleEntry struct {
Title, Icon string // saved title and icon name
HasTitle, HasIcon bool // whether the entry holds each
}
TitleEntry is one entry of the title stack. A push can save the title, the icon name or both, and a pop puts back only what the entry holds.
type Titles ¶
type Titles struct {
Title, Icon string // window title and icon name
Stack []TitleEntry // saved titles, oldest first
}
Titles is the window title, the icon name and the title stack XTWINOPS 22 and 23 push to and pop from, oldest entry first.
Source Files
¶
- backend_name.go
- bufpipe.go
- callbacks.go
- cc.go
- cellsize.go
- charset.go
- color_scheme.go
- csi.go
- csi_cursor.go
- csi_mode.go
- csi_screen.go
- csi_sgr.go
- cursor.go
- dcs.go
- debug_logger.go
- emulator.go
- esc.go
- focus.go
- ghostty_scan.go
- grid.go
- handlers.go
- key.go
- kitty_file_check.go
- kitty_file_check_unix.go
- kitty_guest_images.go
- kitty_keyboard.go
- kitty_medium_release.go
- kitty_owner_unix.go
- kitty_parser.go
- kitty_placeholder.go
- kitty_state.go
- kitty_temp_dirs.go
- kitty_types.go
- mode.go
- modify_other_keys.go
- mouse.go
- mouse_encode.go
- new_pure.go
- osc.go
- pane_key.go
- parser.go
- paste.go
- private_osc.go
- progress.go
- progstatus.go
- reflow.go
- reports.go
- restore_cursor.go
- screen.go
- screen_interface.go
- scrollback.go
- scrollback_iter.go
- scrollback_text.go
- semantic_markers.go
- sixel_encode.go
- sixel_image.go
- sixel_marker.go
- sixel_parser.go
- sixel_report.go
- snapshot_state.go
- tailtext.go
- terminal.go
- title_stack.go
- utf8.go
- utils.go
- vt.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package snapshot captures what an emulator holds, packs it for a wire or a file, and brings another emulator to the same state.
|
Package snapshot captures what an emulator holds, packs it for a wire or a file, and brings another emulator to the same state. |
|
Package vtgen generates terminal input that looks like something a program would actually emit.
|
Package vtgen generates terminal input that looks like something a program would actually emit. |