Documentation
¶
Overview ¶
Package vterm is a terminal emulator: it parses a stream of ANSI/VT escape sequences into a cell grid plus scrollback and renders that state back to ANSI. It is the source of truth for what a hosted agent's terminal looks like, feeding the compositor and the center/sidebar UI models.
Index ¶
- Constants
- func ContainsSGRParam(s string, target int) bool
- func NormalizeSelectionRange(startX, startY, endX, endY int) (int, int, int, int)
- func RenderableRune(r rune) rune
- func SelectionContains(startX, startY, endX, endY, x, y int) bool
- func VTermHasScrollback(v *VTerm) bool
- type Cell
- type Color
- type ColorType
- type CursorRenderState
- type PaneModeState
- type Parser
- type ParserCarryMode
- type ParserCarryState
- type ResponseWriter
- type Style
- type TerminalSnapshot
- type VTerm
- func (v *VTerm) AbsoluteLineToScreenY(absLine int) int
- func (v *VTerm) AppendDelta(snap TerminalSnapshot, visibleHistoryRows int)
- func (v *VTerm) AppendScrollbackDelta(data []byte)
- func (v *VTerm) AppendScrollbackDeltaWithSize(data []byte, width, height, visibleHistoryRows int)
- func (v *VTerm) ClearDirty()
- func (v *VTerm) ClearDirtyWithCursor(showCursor bool)
- func (v *VTerm) ClearSelection()
- func (v *VTerm) CursorHiddenForRender() bool
- func (v *VTerm) DirtyLines() ([]bool, bool)
- func (v *VTerm) GetScrollInfo() (int, int)
- func (v *VTerm) GetSelectedText(startX, startLine, endX, endLine int) string
- func (v *VTerm) GetTextRange(startX, startLine, endX, endLine int) string
- func (v *VTerm) HasSelection() bool
- func (v *VTerm) IsInSelection(x, screenY int) bool
- func (v *VTerm) IsScrolled() bool
- func (v *VTerm) LastCursorState() CursorRenderState
- func (v *VTerm) LineCells(line int) []Cell
- func (v *VTerm) LoadPaneCapture(data []byte)
- func (v *VTerm) LoadPaneCaptureWithCursorAndModes(data []byte, cursorX, cursorY int, hasCursor bool, modeState PaneModeState)
- func (v *VTerm) LoadSnapshot(snap TerminalSnapshot)
- func (v *VTerm) MaxViewOffset() int
- func (v *VTerm) MouseReportingEnabled() bool
- func (v *VTerm) MouseSGRMode() bool
- func (v *VTerm) NoteSyncViewportInteraction()
- func (v *VTerm) ParserCarryState() ParserCarryState
- func (v *VTerm) PrependHistory(snap TerminalSnapshot)
- func (v *VTerm) PrependScrollback(data []byte)
- func (v *VTerm) PrependScrollbackWithSize(data []byte, width, height int)
- func (v *VTerm) Render() string
- func (v *VTerm) RenderAndClear() string
- func (v *VTerm) RenderBuffers() ([][]Cell, int)
- func (v *VTerm) ResetParserState()
- func (v *VTerm) Resize(width, height int)
- func (v *VTerm) ResizeWithoutHistoryReveal(width, height int)
- func (v *VTerm) ScreenYToAbsoluteLine(screenY int) int
- func (v *VTerm) ScrollView(delta int)
- func (v *VTerm) ScrollViewAndNote(delta int)
- func (v *VTerm) ScrollViewTo(offset int)
- func (v *VTerm) ScrollViewToBottom()
- func (v *VTerm) ScrollViewToTop()
- func (v *VTerm) SelActive() bool
- func (v *VTerm) SelEndLine() int
- func (v *VTerm) SelEndX() int
- func (v *VTerm) SelEndY() int
- func (v *VTerm) SelStartLine() int
- func (v *VTerm) SelStartX() int
- func (v *VTerm) SelStartY() int
- func (v *VTerm) SelectedText() string
- func (v *VTerm) SetResponseWriter(w ResponseWriter)
- func (v *VTerm) SetSelection(startX, startLine, endX, endLine int, active, rect bool)
- func (v *VTerm) SyncActive() bool
- func (v *VTerm) TakePendingClipboard() []byte
- func (v *VTerm) Title() string
- func (v *VTerm) Version() uint64
- func (v *VTerm) VisibleScreen() [][]Cell
- func (v *VTerm) VisibleScreenInto(dst [][]Cell) [][]Cell
- func (v *VTerm) VisibleScreenWithSelection() [][]Cell
- func (v *VTerm) WorkingDir() string
- func (v *VTerm) Write(data []byte)
Constants ¶
const MaxScrollback = 10000
const SyncStallTimeout = 2 * time.Second
SyncStallTimeout bounds how long a DEC 2026 sync-begin may freeze rendering without its matching sync-end. A well-behaved writer closes a sync region within one frame; if the end marker never arrives (writer died mid-frame, output trimmed under overflow), the frozen snapshot must not persist forever. Write, RenderBuffers, and Version check the deadline, so the terminal recovers on the next output, rendered frame, or snapshot-cache key check, whichever comes first.
Variables ¶
This section is empty.
Functions ¶
func ContainsSGRParam ¶ added in v0.0.20
ContainsSGRParam reports whether s contains an SGR escape sequence (CSI ... m) carrying the given numeric parameter. vterm owns ANSI/SGR scanning, so tests in any package that renders via vterm can share this instead of re-deriving it.
func NormalizeSelectionRange ¶ added in v0.0.20
NormalizeSelectionRange orders the two endpoints so that (startX, startY) comes before (endX, endY) in reading order (top-to-bottom, left-to-right on the same row) and returns them. Coordinates may be in any consistent space (screen-relative or absolute lines) as long as both endpoints use the same.
func RenderableRune ¶ added in v0.0.20
RenderableRune substitutes a NUL rune (an unwritten cell) with a space so it renders as blank rather than a control character. Other runes pass through unchanged. Shared by the live renderer and the compositor render paths.
func SelectionContains ¶ added in v0.0.20
SelectionContains reports whether cell (x, y) falls inside the linear selection bounded by (startX, startY)..(endX, endY). The bounds MUST already be normalized (see NormalizeSelectionRange) so start precedes end. The first row of the range starts at startX, the last row ends at endX, and any rows in between are fully selected. This is the rectangular-selection-free contains test shared by the live renderer and the compositor snapshot paths.
func VTermHasScrollback ¶ added in v0.0.20
VTermHasScrollback reports whether v is non-nil and currently has scrollback the viewport can move into. It is the shared leaf used by the per-pane CanConsumeWheel checks to avoid hover-wheel focus steals from panes with no scrollable history.
Types ¶
type Cell ¶
type Cell struct {
Rune rune
Style Style
Width int // 1 normal, 2 wide, 0 continuation
// GraphemeCluster, when non-empty, is the full grapheme (base rune plus
// combining marks) for this cell. Empty means "use Rune". Readers that emit
// text should prefer it; width/layout logic still uses Rune + Width.
GraphemeCluster string
}
Cell represents a single character cell
type CursorRenderState ¶ added in v0.0.20
CursorRenderState is the cached cursor state from the previous render frame, used to detect cursor-only changes and mark the affected lines dirty.
type PaneModeState ¶ added in v0.0.19
type PaneModeState struct {
HasState bool
// PreserveExistingState keeps the current terminal mode state when a pane
// snapshot did not include authoritative tmux mode fields.
PreserveExistingState bool
AltScreen bool
OriginMode bool
CursorHidden bool
ScrollTop int
ScrollBottom int
HasAltSavedCursor bool
AltSavedCursorX int
AltSavedCursorY int
}
PaneModeState describes the VT mode state that should accompany an authoritative tmux pane snapshot.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser handles ANSI escape sequence parsing
func (*Parser) CarryState ¶ added in v0.0.17
func (p *Parser) CarryState() ParserCarryState
type ParserCarryMode ¶ added in v0.0.17
type ParserCarryMode uint8
const ( ParserCarryText ParserCarryMode = iota ParserCarryEscape ParserCarryCSI ParserCarryCSIParam ParserCarryOSC ParserCarryDCS ParserCarryCharset ParserCarryOSCEscape ParserCarryDCSEscape )
type ParserCarryState ¶ added in v0.0.17
type ParserCarryState struct {
Mode ParserCarryMode
UTF8Remaining int
}
func AdvanceParserCarryState ¶ added in v0.0.17
func AdvanceParserCarryState(seed ParserCarryState, data []byte) ParserCarryState
AdvanceParserCarryState models parser continuity across chunk boundaries. It is the single shared state machine for this: PTY overflow trimming (internal/ui/ptyio) and speculative actor carry previews both consume it directly rather than maintaining copies.
type ResponseWriter ¶
type ResponseWriter func([]byte)
ResponseWriter is called when the terminal needs to send a response back to the PTY
type Style ¶
type Style struct {
Fg Color
Bg Color
Bold bool
Dim bool
Italic bool
Underline bool
Blink bool
Reverse bool
Hidden bool
Strike bool
}
Style holds text styling attributes
func SuppressBlankUnderline ¶ added in v0.0.20
SuppressBlankUnderline drops the underline attribute when rune r is blank (NUL or space). Some TUIs leave underline enabled while clearing rows; underline on spaces renders as scanlines, so it is removed for blank cells at render time. The rule is shared by the live renderer and both compositor render paths so they stay pixel-identical.
func (Style) ANSI ¶ added in v0.0.20
ANSI converts a Style to a full ANSI escape sequence, leading with a reset. Optimized to avoid allocations using strings.Builder.
func (Style) DeltaANSI ¶ added in v0.0.20
DeltaANSI returns the minimal SGR escape sequence to transition from the receiver (the previous style) to next. It avoids the overhead of always emitting a full reset, and returns "" when nothing changed. Optimized to avoid allocations using strings.Builder.
type TerminalSnapshot ¶ added in v0.0.20
type TerminalSnapshot struct {
// Data is the raw ANSI capture (e.g. tmux capture-pane output).
Data []byte
// Cols/Rows are the dimensions the capture was taken at; zero values fall
// back to the terminal's current size.
Cols, Rows int
// CursorX/CursorY position the cursor after a full load when HasCursor is
// set.
CursorX, CursorY int
HasCursor bool
// ModeState carries alt-screen/origin/cursor-visibility/scroll-region
// state, with the explicit missing-state policy described above.
ModeState PaneModeState
}
TerminalSnapshot is a captured pane image plus the metadata needed to replay it into a VTerm: the raw capture bytes, the geometry the capture was taken at, the cursor, and the pane mode state.
It is the unified entry point for the capture-load paths. The historical per-shape variants (PrependScrollbackWithSize, LoadPaneCaptureWithCursorAndModes, AppendScrollbackDeltaWithSize) remain as the implementation, but new callers should construct a TerminalSnapshot and use LoadSnapshot / AppendDelta / PrependHistory.
Missing mode state is an explicit decision, never a silent default: when ModeState.HasState is false, ModeState.PreserveExistingState selects between keeping the terminal's current modes (partial captures) and resetting them to defaults (authoritative captures). Builders of a TerminalSnapshot must set it deliberately.
type VTerm ¶
type VTerm struct {
// Screen buffer (visible area)
Screen [][]Cell
// Scrollback buffer (oldest at index 0)
Scrollback [][]Cell
// Cursor position (0-indexed)
CursorX, CursorY int
// Dimensions
Width, Height int
// Scroll viewing position (0 = live, >0 = lines scrolled up)
ViewOffset int
// Alt screen mode (full-screen TUI applications).
AltScreen bool
// AllowAltScreenScrollback keeps scrollback active even in alt screen.
// Useful for tmux-backed sessions where scrollback should remain available.
AllowAltScreenScrollback bool
// Scrolling region (for DECSTBM)
ScrollTop int
ScrollBottom int
// Origin mode (DECOM) - cursor positions are relative to scroll region.
OriginMode bool
// Current style for new characters
CurrentStyle Style
// Saved cursor state (for DECSC/DECRC)
SavedCursorX int
SavedCursorY int
SavedStyle Style
// Cursor visibility (controlled externally when pane is focused)
ShowCursor bool
// CursorHidden tracks if terminal app hid cursor via DECTCEM (mode 25)
CursorHidden bool
// IgnoreCursorVisibilityControls ignores DECTCEM mode 25 hide/show toggles.
// Used by chat-style tabs that render a steady cursor independent of app output.
IgnoreCursorVisibilityControls bool
// TreatLFAsCRLF makes bare LF advance to the next line and return to column 0.
// This is useful for some chat agents that emit LF-only streams.
TreatLFAsCRLF bool
// CaptureNormalScreenOnClear preserves chat-style full-screen redraw frames
// that use normal-screen CSI 2J/3J instead of the alternate screen.
CaptureNormalScreenOnClear bool
// contains filtered or unexported fields
}
VTerm is a virtual terminal emulator with scrollback support.
Synchronization contract: VTerm has no internal mutex. All callers must provide external synchronization. In practice, every call site (WriteToTerminal, SidebarPTYFlush, and TerminalLayer snapshot creation) holds TerminalState.mu for the duration of the operation. Snapshot-based rendering (TerminalLayer) copies data under the lock and then renders the immutable snapshot without locks.
func (*VTerm) AbsoluteLineToScreenY ¶ added in v0.0.4
AbsoluteLineToScreenY converts an absolute line number to a screen Y coordinate. Returns -1 if the line is not currently visible.
func (*VTerm) AppendDelta ¶ added in v0.0.20
func (v *VTerm) AppendDelta(snap TerminalSnapshot, visibleHistoryRows int)
AppendDelta appends the snapshot rows that are missing from the current buffers (post-attach growth). visibleHistoryRows is the number of history rows that a preceding resize folded back into the visible screen, so they are not appended twice.
func (*VTerm) AppendScrollbackDelta ¶ added in v0.0.19
AppendScrollbackDelta appends only the missing suffix from a newer tmux history capture. This is used after a pre-attach full-pane snapshot so rows that scrolled into history during the snapshot->attach gap are preserved without replacing the restored visible frame.
func (*VTerm) AppendScrollbackDeltaWithSize ¶ added in v0.0.19
AppendScrollbackDeltaWithSize appends the missing suffix from a newer tmux history capture parsed at the tmux geometry that produced it. When the local viewport has changed since capture time, visibleHistoryRows indicates how many of the newest captured rows are already visible after the restore/resize and should not be appended back into scrollback.
func (*VTerm) ClearDirty ¶
func (v *VTerm) ClearDirty()
ClearDirty resets dirty tracking state after a render.
func (*VTerm) ClearDirtyWithCursor ¶
ClearDirtyWithCursor resets dirty tracking state and updates cursor tracking. This should be called after snapshotting to track cursor position changes.
func (*VTerm) ClearSelection ¶
func (v *VTerm) ClearSelection()
ClearSelection clears the current selection
func (*VTerm) CursorHiddenForRender ¶ added in v0.0.14
CursorHiddenForRender returns the effective cursor-hidden state for rendering.
func (*VTerm) DirtyLines ¶
DirtyLines returns the dirty line flags and whether all lines are dirty. This is used by VTermLayer for optimized rendering. The returned slice is reused between calls; callers must not retain it across mutations.
func (*VTerm) GetScrollInfo ¶
GetScrollInfo returns (current offset, max offset)
func (*VTerm) GetSelectedText ¶
GetSelectedText extracts text from the current selection. Returns empty string if no selection is active.
func (*VTerm) GetTextRange ¶
GetTextRange extracts text from a range in the combined scrollback+screen buffer. Coordinates are absolute line indices (0-based) and columns.
func (*VTerm) HasSelection ¶ added in v0.0.4
HasSelection returns true if there is an active selection.
func (*VTerm) IsInSelection ¶
IsInSelection checks if coordinate (x, screenY) is within the selection. screenY is a screen-relative coordinate (0 to Height-1).
func (*VTerm) IsScrolled ¶
IsScrolled returns true if viewing scrollback
func (*VTerm) LastCursorState ¶ added in v0.0.20
func (v *VTerm) LastCursorState() CursorRenderState
LastCursorState returns the cursor position and visibility from the previous render frame.
func (*VTerm) LineCells ¶
LineCells returns the cell slice for an absolute line index in scrollback+screen.
func (*VTerm) LoadPaneCapture ¶ added in v0.0.19
LoadPaneCapture replaces the terminal screen + scrollback with a full tmux pane capture (scrollback plus the current visible screen). This seeds a reattached client with the latest frame before live PTY output resumes.
func (*VTerm) LoadPaneCaptureWithCursorAndModes ¶ added in v0.0.19
func (v *VTerm) LoadPaneCaptureWithCursorAndModes( data []byte, cursorX, cursorY int, hasCursor bool, modeState PaneModeState, )
LoadPaneCaptureWithCursorAndModes replaces the terminal screen + scrollback with a full tmux pane capture and applies the accompanying tmux VT mode state when one is available.
func (*VTerm) LoadSnapshot ¶ added in v0.0.20
func (v *VTerm) LoadSnapshot(snap TerminalSnapshot)
LoadSnapshot replaces the terminal's screen and scrollback with the snapshot content, applying cursor and mode state.
func (*VTerm) MaxViewOffset ¶
MaxViewOffset returns the maximum scrollback offset for the current buffers. Used by the sidebar/center wheel handlers to decide whether scrollback exists.
func (*VTerm) MouseReportingEnabled ¶ added in v0.0.20
MouseReportingEnabled reports whether the hosted terminal application has requested mouse event reporting.
func (*VTerm) MouseSGRMode ¶ added in v0.0.20
MouseSGRMode reports whether SGR extended mouse coordinates are enabled.
func (*VTerm) NoteSyncViewportInteraction ¶ added in v0.0.20
func (v *VTerm) NoteSyncViewportInteraction()
NoteSyncViewportInteraction records a viewport interaction during synchronized output. Scrolled into history, the frozen viewport stays anchored when the sync ends; back at the live view, the anchor is released and recorded hidden growth is discarded. This is an explicit API called by the UI scroll paths (mousewheel/keys) rather than a hidden side effect of the viewport math: programmatic ViewOffset changes do not touch the anchor unless their call site opts in.
func (*VTerm) ParserCarryState ¶ added in v0.0.17
func (v *VTerm) ParserCarryState() ParserCarryState
ParserCarryState reports any in-flight parser state from previously flushed PTY bytes. Callers must provide external synchronization.
func (*VTerm) PrependHistory ¶ added in v0.0.20
func (v *VTerm) PrependHistory(snap TerminalSnapshot)
PrependHistory inserts the snapshot rows above the existing scrollback (older captured history fetched after the live view was already populated).
func (*VTerm) PrependScrollback ¶ added in v0.0.9
PrependScrollback parses captured scrollback content (with ANSI escapes) and prepends the resulting lines to the scrollback buffer. This is used to populate scrollback history when attaching to an existing tmux session. It is a no-op if data is empty.
func (*VTerm) PrependScrollbackWithSize ¶ added in v0.0.19
PrependScrollbackWithSize parses captured scrollback content using the cell geometry that tmux had when it produced the capture, then prepends the resulting lines to the scrollback buffer.
func (*VTerm) RenderAndClear ¶ added in v0.0.20
RenderAndClear renders the terminal and marks the rendered state clean in one step, so callers cannot forget the clear that keeps the cache coherent.
func (*VTerm) RenderBuffers ¶
RenderBuffers returns the current screen buffer and scrollback length. During synchronized output, it returns the frozen snapshot. As a failsafe it force-releases a sync region whose end marker is overdue (SyncStallTimeout) so a writer that died mid-frame cannot freeze the terminal forever.
func (*VTerm) ResetParserState ¶ added in v0.0.17
func (v *VTerm) ResetParserState()
ResetParserState clears any carried parser state after buffered PTY bytes are forcibly discarded. Callers must provide external synchronization.
func (*VTerm) ResizeWithoutHistoryReveal ¶ added in v0.0.19
ResizeWithoutHistoryReveal resizes the terminal without pulling rows out of scrollback to fill newly revealed viewport space.
func (*VTerm) ScreenYToAbsoluteLine ¶ added in v0.0.4
ScreenYToAbsoluteLine converts a screen Y coordinate (0 to Height-1) to an absolute line number. Absolute line 0 is the first line in scrollback.
func (*VTerm) ScrollView ¶
ScrollView scrolls the view by delta lines (positive = up into history)
func (*VTerm) ScrollViewAndNote ¶ added in v0.0.20
ScrollViewAndNote scrolls the view by delta lines and then records the resulting viewport interaction, exactly as if the caller had written ScrollView followed by NoteSyncViewportInteraction. UI scroll paths that move the viewport in response to user input (mousewheel, drag-select edge scroll, PgUp/PgDown) pair these two calls; this helper keeps that pairing in one place so the anchor bookkeeping cannot drift between call sites.
func (*VTerm) ScrollViewTo ¶
ScrollViewTo sets absolute scroll position
func (*VTerm) ScrollViewToBottom ¶
func (v *VTerm) ScrollViewToBottom()
ScrollViewToBottom returns to live view
func (*VTerm) ScrollViewToTop ¶
func (v *VTerm) ScrollViewToTop()
ScrollViewToTop scrolls to oldest content
func (*VTerm) SelEndLine ¶ added in v0.0.4
SelEndLine returns the selection end line (absolute line number).
func (*VTerm) SelEndY ¶
SelEndY returns the selection end Y in screen coordinates. Returns -1 if the end line is not visible.
func (*VTerm) SelStartLine ¶ added in v0.0.4
SelStartLine returns the selection start line (absolute line number).
func (*VTerm) SelStartY ¶
SelStartY returns the selection start Y in screen coordinates. Returns -1 if the start line is not visible.
func (*VTerm) SelectedText ¶ added in v0.0.18
SelectedText returns text from the stored selection coordinates. It does not check selActive so callers that hold their own Active flag (e.g. common.SelectionState) can still copy after a concurrent ClearSelection.
func (*VTerm) SetResponseWriter ¶
func (v *VTerm) SetResponseWriter(w ResponseWriter)
SetResponseWriter sets the callback for terminal query responses
func (*VTerm) SetSelection ¶
SetSelection stores selection coordinates for rendering with highlight. startLine and endLine are absolute line numbers (0 = first scrollback line).
func (*VTerm) SyncActive ¶
SyncActive reports whether synchronized output is currently active.
func (*VTerm) TakePendingClipboard ¶ added in v0.0.20
TakePendingClipboard returns and clears any clipboard payload captured from an OSC 52 write. Returns nil when none is pending.
func (*VTerm) Title ¶ added in v0.0.20
Title returns the most recent window/tab title reported via OSC 0/1/2.
func (*VTerm) Version ¶
Version returns the current version counter. This increments whenever visible content changes.
func (*VTerm) VisibleScreen ¶
VisibleScreen returns the currently visible screen buffer as a copy.
func (*VTerm) VisibleScreenInto ¶ added in v0.0.12
VisibleScreenInto returns the currently visible screen buffer, reusing dst when possible. dst is resized as needed and its lines are reused to reduce allocations.
func (*VTerm) VisibleScreenWithSelection ¶
VisibleScreenWithSelection returns the visible screen with selection highlighting applied.
func (*VTerm) WorkingDir ¶ added in v0.0.20
WorkingDir returns the most recent working directory reported via OSC 7 (raw payload, e.g. "file://host/path").
Source Files
¶
- accessors.go
- alt_screen_capture.go
- alt_screen_capture_state.go
- alt_screen_restore_pending.go
- ansi.go
- cache.go
- cell.go
- csi.go
- cursor.go
- lineedit.go
- modes.go
- ops.go
- osc.go
- parser.go
- render.go
- scroll.go
- selection.go
- sgr.go
- sgr_scan.go
- snapshot.go
- sync.go
- vterm.go
- vterm_capture.go
- vterm_scroll.go
- vterm_scrollback_delta.go
- vterm_view_helpers.go