vt

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package vt provides a virtual terminal implementation.

Package vt is a virtual terminal emulator that can be used to emulate a modern terminal application.

Index

Constants

View Source
const (
	ModShift = uv.ModShift
	ModAlt   = uv.ModAlt
	ModCtrl  = uv.ModCtrl
	ModMeta  = uv.ModMeta
)

Modifier keys.

View Source
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.

View Source
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.

View Source
const DefaultScrollbackSize = 10000

DefaultScrollbackSize is the default number of lines to keep in the scrollback buffer.

Variables

View Source
var (
	UK = CharSet{
		'$': "£",
	}
	SpecialDrawing = CharSet{
		'`': "◆",
		'a': "▒",
		'b': "␉",
		'c': "␌",
		'd': "␍",
		'e': "␊",
		'f': "°",
		'g': "±",
		'h': "␤",
		'i': "␋",
		'j': "┘",
		'k': "┐",
		'l': "┌",
		'm': "└",
		'n': "┼",
		'o': "⎺",
		'p': "⎻",
		'q': "─",
		'r': "⎼",
		's': "⎽",
		't': "├",
		'u': "┤",
		'v': "┴",
		'w': "┬",
		'x': "│",
		'y': "⩽",
		'z': "⩾",
		'{': "π",
		'|': "≠",
		'}': "£",
		'~': "·",
	}
)

Character sets.

Functions

func BuildKittyResponse

func BuildKittyResponse(ok bool, imageID uint32, message string) []byte

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 LoadFileData

func LoadFileData(filePath string) ([]byte, error)

LoadFileData reads a kitty t=f/t=t transmit file. The path is guest controlled, so an unbounded os.ReadFile lets a hostile guest point at /dev/zero (OOM), a FIFO (hang), or an arbitrary readable file. Reject anything that is not a regular file and cap the read at the same size used for an in-band transmission.

Types

type ApcHandler

type ApcHandler func(data []byte) bool

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)

	// CursorStyle callback. When set, this function is called when the cursor
	// style changes.
	CursorStyle func(style CursorStyle, blink 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)
}

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 CharSet

type CharSet map[byte]string

CharSet represents a character set designator. This can be used to select a character set for G0 or G1 and others.

type CsiHandler

type CsiHandler func(params ansi.Params) bool

CsiHandler is a function that handles a CSI escape sequence.

type Cursor

type Cursor struct {
	Pen  uv.Style
	Link uv.Link

	uv.Position

	Style  CursorStyle
	Steady bool // Not blinking
	Hidden 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

type DcsHandler func(params ansi.Params, data []byte) bool

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

func NewEmulator(w, h int) *Emulator

NewEmulator creates a new virtual terminal emulator.

func (*Emulator) ActiveScreenIsAlt

func (e *Emulator) ActiveScreenIsAlt() bool

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) ApplicationCursorKeys

func (e *Emulator) ApplicationCursorKeys() bool

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) BackgroundColor

func (e *Emulator) BackgroundColor() color.Color

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) Bounds

func (e *Emulator) Bounds() uv.Rectangle

Bounds returns the bounds of the terminal.

func (*Emulator) BracketedPasteEnabled

func (e *Emulator) BracketedPasteEnabled() bool

BracketedPasteEnabled returns true if bracketed paste mode (?2004) is enabled. When enabled, pasted text should be wrapped with escape sequences.

func (*Emulator) CellAt

func (e *Emulator) CellAt(x, y int) *uv.Cell

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

func (e *Emulator) CellSize() (width, height int)

CellSize returns the pixel dimensions of a single character cell.

func (*Emulator) Charsets

func (e *Emulator) Charsets() (ids [4]byte, gl, gr int)

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) Close

func (e *Emulator) Close() error

Close closes the terminal.

func (*Emulator) CursorColor

func (e *Emulator) CursorColor() color.Color

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

func (e *Emulator) CursorPen() (uv.Style, uv.Link)

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) CursorPosition

func (e *Emulator) CursorPosition() uv.Position

CursorPosition returns the terminal's cursor position.

func (*Emulator) Draw

func (e *Emulator) Draw(scr uv.Screen, area uv.Rectangle)

Draw implements the uv.Drawable interface.

func (*Emulator) EncodeMouseEvent

func (e *Emulator) EncodeMouseEvent(m Mouse) string

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) 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) ForegroundColor

func (e *Emulator) ForegroundColor() color.Color

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

func (e *Emulator) GetCallbacks() Callbacks

GetCallbacks returns the terminal's current callbacks.

func (*Emulator) GetModes

func (e *Emulator) GetModes() map[int]bool

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) HasAllMotionMode

func (e *Emulator) HasAllMotionMode() bool

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

func (e *Emulator) HasCellMotionMode() bool

HasCellMotionMode returns true if the child app requested mode 1002 (button-event tracking), which reports motion while a button is pressed.

func (*Emulator) HasMouseMode

func (e *Emulator) HasMouseMode() bool

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) Height

func (e *Emulator) Height() int

Height returns the height of the terminal.

func (*Emulator) IndexedColor

func (e *Emulator) IndexedColor(i int) color.Color

IndexedColor returns a terminal's indexed color. An indexed color is a color between 0 and 255.

func (*Emulator) InputPipe

func (e *Emulator) InputPipe() io.Writer

InputPipe returns the terminal's input pipe. This can be used to send input to the terminal.

func (*Emulator) IsAltScreen

func (e *Emulator) IsAltScreen() bool

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

func (e *Emulator) IsCursorHidden() bool

IsCursorHidden returns whether the cursor is currently hidden. Applications can hide the cursor using ANSI escape sequences (DECTCEM mode).

func (*Emulator) IsSyncActive

func (e *Emulator) IsSyncActive() bool

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

func (*Emulator) KittyKeyboardFlags

func (e *Emulator) KittyKeyboardFlags() int

KittyKeyboardFlags returns the current kitty keyboard protocol flags. Thread-safe: reads from an atomic cache updated on push/pop/set/reset.

func (*Emulator) KittyKeyboardStack

func (e *Emulator) KittyKeyboardStack() []int

KittyKeyboardStack returns a copy of the kitty keyboard flag stack, 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) KittyMainState

func (e *Emulator) KittyMainState() *KittyState

func (*Emulator) KittyState

func (e *Emulator) KittyState() *KittyState

func (*Emulator) MainCellAt

func (e *Emulator) MainCellAt(x, y int) *uv.Cell

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) PaletteColor

func (e *Emulator) PaletteColor(i int) color.Color

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) Paste

func (e *Emulator) Paste(text string)

Paste pastes text into the terminal. If bracketed paste mode is enabled, the text is bracketed with the appropriate escape sequences.

func (*Emulator) Read

func (e *Emulator) Read(p []byte) (n int, err error)

Read reads data from the terminal input buffer.

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) Render

func (e *Emulator) Render() string

Render renders a snapshot of the terminal screen as a string with styles and links encoded as ANSI escape codes.

func (*Emulator) ReserveImageSpace

func (e *Emulator) ReserveImageSpace(rows, cols int)

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) Resize

func (e *Emulator) Resize(width int, height int)

Resize resizes the terminal.

func (*Emulator) RestoreAltScreenMode

func (e *Emulator) RestoreAltScreenMode(enabled bool)

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

func (e *Emulator) RestoreCharsets(ids [4]byte, gl, gr int)

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

func (e *Emulator) RestoreCursorPen(pen uv.Style, link uv.Link)

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) RestoreCursorPosition

func (e *Emulator) RestoreCursorPosition(x, y int)

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) RestoreKittyKeyboardState

func (e *Emulator) RestoreKittyKeyboardState(stack []int)

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.

func (*Emulator) RestoreModes

func (e *Emulator) RestoreModes(modes map[int]bool)

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) RestoreScrollRegion

func (e *Emulator) RestoreScrollRegion(r uv.Rectangle)

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) ScrollRegion

func (e *Emulator) ScrollRegion() uv.Rectangle

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) ScrollbackLen

func (e *Emulator) ScrollbackLen() int

ScrollbackLen returns the number of lines in the scrollback buffer.

func (*Emulator) ScrollbackLine

func (e *Emulator) ScrollbackLine(index int) uv.Line

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) SemanticMarkers

func (e *Emulator) SemanticMarkers() *SemanticMarkerList

SemanticMarkers returns the list of OSC 133 semantic zone markers.

func (*Emulator) SendKey

func (e *Emulator) SendKey(k uv.KeyEvent)

SendKey returns the default key map.

func (*Emulator) SendKeys

func (e *Emulator) SendKeys(keys ...uv.KeyEvent)

SendKeys sends multiple keys to the terminal.

func (*Emulator) SendMouse

func (e *Emulator) SendMouse(m Mouse)

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) SendText

func (e *Emulator) SendText(text string)

SendText sends arbitrary text to the terminal.

func (*Emulator) SetBackgroundColor

func (e *Emulator) SetBackgroundColor(c color.Color)

SetBackgroundColor sets the terminal's background color.

func (*Emulator) SetCallbacks

func (e *Emulator) SetCallbacks(cb Callbacks)

SetCallbacks sets the terminal's callbacks.

func (*Emulator) SetCell

func (e *Emulator) SetCell(x, y int, c *uv.Cell)

SetCell sets the current focused screen cell at the given x, y position.

func (*Emulator) SetCellSize

func (e *Emulator) SetCellSize(width, height int)

SetCellSize sets the pixel dimensions of a single character cell. Used for XTWINOPS terminal size reporting.

func (*Emulator) SetCursorColor

func (e *Emulator) SetCursorColor(c color.Color)

SetCursorColor sets the terminal's cursor color.

func (*Emulator) SetDefaultBackgroundColor

func (e *Emulator) SetDefaultBackgroundColor(c color.Color)

SetDefaultBackgroundColor sets the terminal's default background color.

func (*Emulator) SetDefaultCursorColor

func (e *Emulator) SetDefaultCursorColor(c color.Color)

SetDefaultCursorColor sets the terminal's default cursor color.

func (*Emulator) SetDefaultForegroundColor

func (e *Emulator) SetDefaultForegroundColor(c color.Color)

SetDefaultForegroundColor sets the terminal's default foreground color.

func (*Emulator) SetForegroundColor

func (e *Emulator) SetForegroundColor(c color.Color)

SetForegroundColor sets the terminal's foreground color.

func (*Emulator) SetIndexedColor

func (e *Emulator) SetIndexedColor(i int, c color.Color)

SetIndexedColor sets a terminal's indexed color. The index must be between 0 and 255.

func (*Emulator) SetKittyPassthroughFunc

func (e *Emulator) SetKittyPassthroughFunc(fn func(cmd *KittyCommand, rawData []byte))

func (*Emulator) SetLogger

func (e *Emulator) SetLogger(l Logger)

SetLogger sets the terminal's logger.

func (*Emulator) SetMainCell

func (e *Emulator) SetMainCell(x, y int, c *uv.Cell)

SetMainCell writes a cell into the normal screen whether or not the alternate one is active.

func (*Emulator) SetScreenClearFunc

func (e *Emulator) SetScreenClearFunc(f func())

SetScreenClearFunc sets the ScreenClear callback without replacing other callbacks.

func (*Emulator) SetScrollbackMaxLines

func (e *Emulator) SetScrollbackMaxLines(maxLines int)

SetScrollbackMaxLines sets the maximum number of lines for the scrollback buffer.

func (*Emulator) SetSixelPassthroughFunc

func (e *Emulator) SetSixelPassthroughFunc(fn func(cmd *SixelCommand, cursorX, cursorY, absLine int))

func (*Emulator) SetTextSizingFunc

func (e *Emulator) SetTextSizingFunc(fn func(rawOSC []byte, cursorX, cursorY, scale, textLen int))

func (*Emulator) SetThemeColors

func (e *Emulator) SetThemeColors(fg, bg, cur color.Color, ansiPalette [16]color.Color)

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. If fg, bg, and cur are all nil, theming is disabled and only default colors are set.

func (*Emulator) SixelState

func (e *Emulator) SixelState() *SixelState

func (*Emulator) String

func (e *Emulator) String() string

String returns a string representation of the underlying screen buffer.

func (*Emulator) SupportsMotionEvents

func (e *Emulator) SupportsMotionEvents() bool

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) TailText

func (e *Emulator) TailText(n int) []string

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) Touched

func (e *Emulator) Touched() []*uv.LineData

Touched returns the touched lines in the current screen buffer.

func (*Emulator) Width

func (e *Emulator) Width() int

Width returns the width of the terminal.

func (*Emulator) WidthMethod

func (e *Emulator) WidthMethod() uv.WidthMethod

WidthMethod returns the width method used by the terminal.

func (*Emulator) Write

func (e *Emulator) Write(p []byte) (n int, err error)

Write writes data to the terminal output buffer.

func (*Emulator) WriteResponse

func (e *Emulator) WriteResponse(data []byte)

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.

func (*Emulator) WriteString

func (e *Emulator) WriteString(s string) (n int, err error)

WriteString writes a string to the terminal output buffer.

type EscHandler

type EscHandler func() bool

EscHandler is a function that handles an ESC escape sequence.

type KeyMod

type KeyMod = uv.KeyMod

KeyMod represents a key modifier.

type KeyPressEvent

type KeyPressEvent = uv.KeyPressEvent

KeyPressEvent represents a key press event.

type KittyCommand

type KittyCommand struct {
	Action       KittyGraphicsAction
	Quiet        int
	ImageID      uint32
	ImageNumber  uint32
	PlacementID  uint32
	Format       KittyGraphicsFormat
	Medium       KittyGraphicsMedium
	Compression  KittyGraphicsCompression
	Width        int
	Height       int
	Size         int
	Offset       int
	More         bool
	Delete       KittyDeleteTarget
	XOffset      int
	YOffset      int
	SourceX      int
	SourceY      int
	SourceWidth  int
	SourceHeight int
	Columns      int
	Rows         int
	ZIndex       int32
	CursorMove   int
	Virtual      bool
	Data         []byte
	RawPayload   string // Original base64 payload (preserved for passthrough without re-encoding)
	FilePath     string
}

func ParseKittyCommand

func ParseKittyCommand(data []byte) (*KittyCommand, error)

type KittyDeleteTarget

type KittyDeleteTarget byte
const (
	KittyDeleteAll               KittyDeleteTarget = 'a'
	KittyDeleteByID              KittyDeleteTarget = 'i'
	KittyDeleteByIDAndPlacement  KittyDeleteTarget = 'I'
	KittyDeleteByNumber          KittyDeleteTarget = 'n'
	KittyDeleteByNumberPlacement KittyDeleteTarget = 'N'
	KittyDeleteAtCursor          KittyDeleteTarget = 'c'
	KittyDeleteAtCursorCell      KittyDeleteTarget = 'C'
	KittyDeleteAtColumn          KittyDeleteTarget = 'x'
	KittyDeleteAtRow             KittyDeleteTarget = 'y'
	KittyDeleteAtZIndex          KittyDeleteTarget = 'z'
	KittyDeleteOnScreen          KittyDeleteTarget = 'p'
	KittyDeleteByPlacementID     KittyDeleteTarget = 'P'
	KittyDeleteIntersectCursor   KittyDeleteTarget = 'q'
	KittyDeleteIntersectColumn   KittyDeleteTarget = 'X'
	KittyDeleteIntersectRow      KittyDeleteTarget = 'Y'
	KittyDeleteIntersectCell     KittyDeleteTarget = 'Q'
)

type KittyGraphicsAction

type KittyGraphicsAction byte
const (
	KittyActionQuery         KittyGraphicsAction = 'q'
	KittyActionTransmit      KittyGraphicsAction = 't'
	KittyActionTransmitPlace KittyGraphicsAction = 'T'
	KittyActionPlace         KittyGraphicsAction = 'p'
	KittyActionDelete        KittyGraphicsAction = 'd'
	KittyActionFrame         KittyGraphicsAction = 'f'
	KittyActionAnimation     KittyGraphicsAction = 'a'
	KittyActionCompose       KittyGraphicsAction = 'c'
)

type KittyGraphicsCompression

type KittyGraphicsCompression uint8
const (
	KittyCompressionNone KittyGraphicsCompression = 0
	KittyCompressionZlib KittyGraphicsCompression = 1
)

type KittyGraphicsFormat

type KittyGraphicsFormat uint8
const (
	KittyFormatRGB  KittyGraphicsFormat = 24
	KittyFormatRGBA KittyGraphicsFormat = 32
	KittyFormatPNG  KittyGraphicsFormat = 100
)

type KittyGraphicsHandler

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

KittyGraphicsHandler handles Kitty graphics protocol commands for a screen.

func NewKittyGraphicsHandler

func NewKittyGraphicsHandler(screen *Screen, state *KittyState, input io.Writer) *KittyGraphicsHandler

NewKittyGraphicsHandler creates a new handler for a screen.

func (*KittyGraphicsHandler) HandleCommand

func (h *KittyGraphicsHandler) HandleCommand(cmd *KittyCommand) bool

type KittyGraphicsMedium

type KittyGraphicsMedium byte
const (
	KittyMediumDirect       KittyGraphicsMedium = 'd'
	KittyMediumFile         KittyGraphicsMedium = 'f'
	KittyMediumTempFile     KittyGraphicsMedium = 't'
	KittyMediumSharedMemory KittyGraphicsMedium = 's'
)

type KittyImage

type KittyImage struct {
	ID           uint32
	Number       uint32
	Width        int
	Height       int
	Format       KittyGraphicsFormat
	Compression  KittyGraphicsCompression
	Data         []byte
	TransmitTime time.Time
}

type KittyPendingChunk

type KittyPendingChunk struct {
	ImageID     uint32
	ImageNumber uint32
	Format      KittyGraphicsFormat
	Medium      KittyGraphicsMedium
	Compression KittyGraphicsCompression
	Width       int
	Height      int
	DataBuffer  []byte
}

type KittyPlacement

type KittyPlacement struct {
	ImageID      uint32
	PlacementID  uint32
	ScreenX      int
	ScreenY      int
	AbsoluteLine int
	XOffset      int
	YOffset      int
	SourceX      int
	SourceY      int
	SourceWidth  int
	SourceHeight int
	Columns      int
	Rows         int
	ZIndex       int32
	CursorMove   int
	Virtual      bool
}

type KittyState

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

func NewKittyState

func NewKittyState() *KittyState

func (*KittyState) AddImage

func (s *KittyState) AddImage(img *KittyImage)

func (*KittyState) AddPlacement

func (s *KittyState) AddPlacement(p *KittyPlacement)

func (*KittyState) AllocateID

func (s *KittyState) AllocateID() uint32

func (*KittyState) AppendToPending

func (s *KittyState) AppendToPending(data []byte) bool

AppendToPending appends a chunk to the in-progress transmission. It returns false when there is no pending transmission, or when the cumulative size would exceed maxKittyTransmitBytes, in which case the runaway transmission is aborted (pending is discarded) so later chunks start fresh.

func (*KittyState) Clear

func (s *KittyState) Clear()

func (*KittyState) ClearPending

func (s *KittyState) ClearPending()

func (*KittyState) ClearPlacements

func (s *KittyState) ClearPlacements()

func (*KittyState) DeleteImage

func (s *KittyState) DeleteImage(id uint32)

func (*KittyState) DeleteImageByNumber

func (s *KittyState) DeleteImageByNumber(num uint32)

func (*KittyState) DeletePlacement

func (s *KittyState) DeletePlacement(imageID, placementID uint32)

func (*KittyState) DeletePlacementsAtCursor

func (s *KittyState) DeletePlacementsAtCursor(x, y int)

func (*KittyState) DeletePlacementsByZIndex

func (s *KittyState) DeletePlacementsByZIndex(z int32)

func (*KittyState) DeletePlacementsInColumn

func (s *KittyState) DeletePlacementsInColumn(x int)

func (*KittyState) DeletePlacementsInRow

func (s *KittyState) DeletePlacementsInRow(y int)

func (*KittyState) FinalizePending

func (s *KittyState) FinalizePending() *KittyImage

func (*KittyState) GetImage

func (s *KittyState) GetImage(id uint32) *KittyImage

func (*KittyState) GetImageByNumber

func (s *KittyState) GetImageByNumber(num uint32) *KittyImage

func (*KittyState) GetImages

func (s *KittyState) GetImages() []*KittyImage

func (*KittyState) GetPending

func (s *KittyState) GetPending() *KittyPendingChunk

func (*KittyState) GetPlacements

func (s *KittyState) GetPlacements() []*KittyPlacement

func (*KittyState) SetClearCallback

func (s *KittyState) SetClearCallback(fn func())

SetClearCallback sets a callback that will be called when placements are cleared. This is used by passthrough mode to clear images on the host terminal.

func (*KittyState) SetPending

func (s *KittyState) SetPending(chunk *KittyPendingChunk)

type Logger

type Logger interface {
	Printf(format string, v ...any)
}

Logger represents a logger interface.

type Mouse

type Mouse = uv.MouseEvent

Mouse represents a mouse event.

type MouseButton

type MouseButton = uv.MouseButton

MouseButton represents the button that was pressed during a mouse message.

type MouseClick

type MouseClick = uv.MouseClickEvent

MouseClick represents a mouse click event.

type MouseMotion

type MouseMotion = uv.MouseMotionEvent

MouseMotion represents a mouse motion event.

type MouseRelease

type MouseRelease = uv.MouseReleaseEvent

MouseRelease represents a mouse release event.

type MouseWheel

type MouseWheel = uv.MouseWheelEvent

MouseWheel represents a mouse wheel event.

type OscHandler

type OscHandler func(data []byte) bool

OscHandler is a function that handles an OSC escape sequence.

type PmHandler

type PmHandler func(data []byte) bool

PmHandler is a function that handles a PM 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 tergo 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 Screen

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

Screen represents a virtual terminal screen.

func NewScreen

func NewScreen(w, h int) *Screen

NewScreen creates a new screen.

func (*Screen) Bounds

func (s *Screen) Bounds() uv.Rectangle

Bounds returns the bounds of the screen.

func (*Screen) CellAt

func (s *Screen) CellAt(x int, y int) *uv.Cell

CellAt returns the cell at the given x, y position.

func (*Screen) Clear

func (s *Screen) Clear()

Clear clears the screen with blank cells.

func (*Screen) ClearArea

func (s *Screen) ClearArea(area uv.Rectangle)

ClearArea clears the given area.

func (*Screen) ClearScrollback

func (s *Screen) ClearScrollback()

ClearScrollback clears all lines from the scrollback buffer.

func (*Screen) Cursor

func (s *Screen) Cursor() Cursor

Cursor returns the cursor.

func (*Screen) CursorPosition

func (s *Screen) CursorPosition() (x, y int)

CursorPosition returns the cursor position.

func (*Screen) DeleteCell

func (s *Screen) DeleteCell(n int)

DeleteCell deletes n cells at the cursor position moving cells to the left. This has no effect if the cursor is outside the scroll region.

func (*Screen) DeleteLine

func (s *Screen) DeleteLine(n int) bool

DeleteLine deletes n lines at the cursor position Y coordinate. Only operates if cursor is within scroll region. Lines below cursor Y are moved up, with blank lines inserted at the bottom of scroll region. It returns true if the operation was successful.

func (*Screen) DisableScrollback

func (s *Screen) DisableScrollback()

DisableScrollback drops this screen's scrollback ring, so lines scrolled off the top are discarded instead of retained. Every other scrollback method here already tolerates the nil, and ScrollUp checks it before pushing.

func (*Screen) Fill

func (s *Screen) Fill(c *uv.Cell)

Fill fills the screen or part of it.

func (*Screen) FillArea

func (s *Screen) FillArea(c *uv.Cell, area uv.Rectangle)

FillArea fills the given area with the given cell.

func (*Screen) Height

func (s *Screen) Height() int

Height returns the height of the screen.

func (*Screen) HideCursor

func (s *Screen) HideCursor()

HideCursor hides the cursor.

func (*Screen) InsertCell

func (s *Screen) InsertCell(n int)

InsertCell inserts n blank characters at the cursor position pushing out cells to the right and out of the screen.

func (*Screen) InsertLine

func (s *Screen) InsertLine(n int) bool

InsertLine inserts n blank lines at the cursor position Y coordinate. Only operates if cursor is within scroll region. Lines below cursor Y are moved down, with those past bottom margin being discarded. It returns true if the operation was successful.

func (*Screen) Reset

func (s *Screen) Reset()

Reset resets the screen. It clears the screen, sets the cursor to the top left corner, reset the cursor styles, and resets the scroll region.

func (*Screen) Resize

func (s *Screen) Resize(width int, height int)

Resize resizes the screen.

func (*Screen) RestoreCursor

func (s *Screen) RestoreCursor()

RestoreCursor restores the cursor.

func (*Screen) SaveCursor

func (s *Screen) SaveCursor()

SaveCursor saves the cursor.

func (*Screen) ScrollDown

func (s *Screen) ScrollDown(n int)

ScrollDown scrolls the content down n lines within the given region. Lines scrolled past the bottom margin are lost. This is equivalent to ansi.SD which moves the cursor to top margin and performs a ansi.IL operation.

func (*Screen) ScrollRegion

func (s *Screen) ScrollRegion() uv.Rectangle

ScrollRegion returns the scroll region.

func (*Screen) ScrollUp

func (s *Screen) ScrollUp(n int)

ScrollUp scrolls the content up n lines within the given region. Lines scrolled past the top margin are saved to the scrollback buffer if the scroll region encompasses the full screen width and starts at the top. This is equivalent to ansi.SU which moves the cursor to the top margin and performs a ansi.DL operation.

func (*Screen) Scrollback

func (s *Screen) Scrollback() *Scrollback

Scrollback returns the scrollback buffer for this screen.

func (*Screen) ScrollbackLen

func (s *Screen) ScrollbackLen() int

ScrollbackLen returns the number of lines currently in the scrollback buffer.

func (*Screen) ScrollbackLine

func (s *Screen) ScrollbackLine(index int) uv.Line

ScrollbackLine returns the line at the specified index in the scrollback buffer. Index 0 is the oldest line. Returns nil if the index is out of bounds.

func (*Screen) SetCell

func (s *Screen) SetCell(x, y int, c *uv.Cell)

SetCell sets the cell at the given x, y position.

func (*Screen) SetScrollbackMaxLines

func (s *Screen) SetScrollbackMaxLines(maxLines int)

SetScrollbackMaxLines sets the maximum number of lines for the scrollback buffer.

func (*Screen) ShowCursor

func (s *Screen) ShowCursor()

ShowCursor shows the cursor.

func (*Screen) Touched

func (s *Screen) Touched() []*uv.LineData

Touched returns touched lines in the screen buffer.

func (*Screen) Width

func (s *Screen) Width() int

Width returns the width of the screen.

type Scrollback

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

Scrollback represents a scrollback buffer that stores lines that have scrolled off the top of the visible screen. Uses a ring buffer for O(1) insertions instead of O(n) slice reallocations. Supports soft-wrapping to handle terminal resizes gracefully.

func NewScrollback

func NewScrollback(maxLines int) *Scrollback

NewScrollback creates a new scrollback buffer with the specified maximum number of lines. If maxLines is 0, DefaultScrollbackSize is used.

func (*Scrollback) CaptureWidth

func (sb *Scrollback) CaptureWidth() int

CaptureWidth returns the terminal width at which scrollback was captured.

func (*Scrollback) Clear

func (sb *Scrollback) Clear()

Clear removes all lines from the scrollback buffer.

func (*Scrollback) Len

func (sb *Scrollback) Len() int

Len returns the number of lines currently in the scrollback buffer.

func (*Scrollback) Line

func (sb *Scrollback) Line(index int) uv.Line

Line returns the line at the specified index in the scrollback buffer. Index 0 is the oldest line, and Len()-1 is the newest (most recently scrolled). Returns nil if the index is out of bounds.

func (*Scrollback) Lines

func (sb *Scrollback) Lines() []uv.Line

Lines returns a slice of all lines in the scrollback buffer, from oldest to newest. The returned slice should not be modified.

func (*Scrollback) MaxLines

func (sb *Scrollback) MaxLines() int

MaxLines returns the maximum number of lines this scrollback can hold.

func (*Scrollback) PushLine

func (sb *Scrollback) PushLine(line uv.Line)

PushLine adds a line to the scrollback buffer. If the buffer is full, the oldest line is removed (by overwriting it in the ring buffer). This is now an O(1) operation instead of O(n). The isSoftWrapped parameter indicates if this line is a soft-wrap (can be reflowed to a different width) or a hard break (actual newline from output).

func (*Scrollback) PushLineOwned

func (sb *Scrollback) PushLineOwned(line uv.Line, isSoftWrapped bool)

PushLineOwned is PushLineWithWrap for a line the caller has just allocated and will not touch again, so the ring takes it as is.

The defensive copy in PushLineWithWrap exists because most callers hand over a row of the live screen buffer, which keeps being written. The scroll path does not: extractLine allocates a fresh line per scrolled row and drops its only reference here, so copying it again doubled the cost of retaining a line, and at 112 bytes per cell and terminal width per line that was the bulk of everything the write path allocated.

func (*Scrollback) PushLineOwnedRecycle

func (sb *Scrollback) PushLineOwnedRecycle(line uv.Line, isSoftWrapped bool) uv.Line

PushLineOwnedRecycle is PushLineOwned that also hands back the line the ring just evicted, so the caller can reuse its storage instead of allocating.

It returns nil while the ring still has room, because nothing has been evicted yet. The returned slice is unreachable through the scrollback once this call returns: head has already moved past it. Callers must treat it as uninitialised storage, since it still holds the evicted line's cells.

func (*Scrollback) PushLineWithWrap

func (sb *Scrollback) PushLineWithWrap(line uv.Line, isSoftWrapped bool)

PushLineWithWrap adds a line with wrap information for soft-wrap support.

func (*Scrollback) Reflow

func (sb *Scrollback) Reflow(newWidth int)

Reflow reconstructs scrollback lines for a different terminal width. This handles the case where the terminal was resized and scrollback lines need to be re-wrapped to match the new width. This is a complex operation that should be called sparingly (only on resize).

func (*Scrollback) SetCaptureWidth

func (sb *Scrollback) SetCaptureWidth(width int)

SetCaptureWidth sets the terminal width at which scrollback lines are being captured. Should be called from the emulator when processing output.

func (*Scrollback) SetMaxLines

func (sb *Scrollback) SetMaxLines(maxLines int)

SetMaxLines sets the maximum number of lines for the scrollback buffer. If the new limit is smaller than the current number of lines, older lines are discarded to fit the new limit.

func (*Scrollback) SetOnTrim

func (sb *Scrollback) SetOnTrim(fn func(int))

SetOnTrim sets a callback that fires when the ring buffer overwrites oldest lines.

type SemanticMarker

type SemanticMarker struct {
	Type         SemanticMarkerType
	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.

func NewSemanticMarkerList

func NewSemanticMarkerList(maxItems int) *SemanticMarkerList

NewSemanticMarkerList creates a new marker list with the given capacity.

func (*SemanticMarkerList) Add

Add appends a marker to the list, discarding the oldest if at capacity.

func (*SemanticMarkerList) AdjustForScrollbackTrim

func (l *SemanticMarkerList) AdjustForScrollbackTrim(linesRemoved int)

AdjustForScrollbackTrim adjusts all marker AbsLine values when scrollback lines are trimmed from the ring buffer. Markers that fall before the new origin are removed.

func (*SemanticMarkerList) Clear

func (l *SemanticMarkerList) Clear()

Clear removes all markers.

func (*SemanticMarkerList) Last

Last returns 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.

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
}

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 SixelPlacement

type SixelPlacement struct {
	// AbsoluteLine is the line in scrollback where the image starts
	// (0 = first line ever written to terminal)
	AbsoluteLine int

	// ScreenX is the column position where the image was placed
	ScreenX int

	// Width is the image width in pixels
	Width int

	// Height is the image height in pixels
	Height int

	// Rows is the number of terminal rows the image occupies
	Rows int

	// Cols is the number of terminal columns the image occupies
	Cols int

	// Data contains the raw sixel data for passthrough/re-rendering
	Data []byte

	// RawSequence contains the complete DCS sequence
	RawSequence []byte

	// AspectRatio from the original command
	AspectRatio int

	// BackgroundMode from the original command
	BackgroundMode int
}

SixelPlacement represents a sixel image placed in the terminal.

type SixelState

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

SixelState manages sixel image placements for a terminal screen. Unlike Kitty graphics, sixel images don't have IDs - they're placed inline at the cursor position and scroll with text.

func NewSixelState

func NewSixelState() *SixelState

NewSixelState creates a new SixelState.

func (*SixelState) AddPlacement

func (s *SixelState) AddPlacement(p *SixelPlacement)

AddPlacement adds a new sixel placement.

func (*SixelState) Clear

func (s *SixelState) Clear()

Clear removes all placements.

func (*SixelState) ClearScrolledOut

func (s *SixelState) ClearScrolledOut(minLine int)

ClearScrolledOut removes placements that have scrolled past a certain line. This helps prevent memory buildup for long-running sessions.

func (*SixelState) Count

func (s *SixelState) Count() int

Count returns the number of placements.

func (*SixelState) GetPlacements

func (s *SixelState) GetPlacements() []*SixelPlacement

GetPlacements returns a copy of all placements.

func (*SixelState) GetVisiblePlacements

func (s *SixelState) GetVisiblePlacements(scrollbackLen, scrollOffset, viewportHeight int) []*SixelPlacement

GetVisiblePlacements returns placements that are visible in the current viewport. scrollbackLen is the total number of lines in scrollback. scrollOffset is how many lines the user has scrolled back (0 = at bottom). viewportHeight is the number of visible rows.

func (*SixelState) RemovePlacementsInRange

func (s *SixelState) RemovePlacementsInRange(startLine, endLine int)

RemovePlacementsInRange removes placements that start within the given line range. Used when text is erased or overwritten.

func (*SixelState) SetChangeCallback

func (s *SixelState) SetChangeCallback(cb func())

SetChangeCallback sets a callback to be called when placements change.

type SosHandler

type SosHandler func(data []byte) bool

SosHandler is a function that handles an SOS escape sequence.

Jump to

Keyboard shortcuts

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