vterm

package
v0.2.11 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package vterm wraps a virtual terminal emulator (vt10x) that interprets PTY output into a 2D screen buffer suitable for rendering in the TUI. This enables support for interactive programs like vim, htop, and less.

Index

Constants

View Source
const (
	MouseOff    = ""       // no tracking
	MouseX10    = "x10"    // \x1b[?9h    — button presses only, no release, no wheel
	MouseNormal = "normal" // \x1b[?1000h — press + release
	MouseButton = "button" // \x1b[?1002h — press + release + motion while a button is held
	MouseAny    = "any"    // \x1b[?1003h — press + release + all motion
)

Mouse tracking protocols a child program can request. These name the tracking MODE — which events the child wants reported. The wire ENCODING is a separate axis, reported by MouseProtocol's sgr return.

Variables

This section is empty.

Functions

This section is empty.

Types

type VTerm

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

VTerm wraps a virtual terminal emulator that interprets PTY output into a 2D screen buffer suitable for rendering in the TUI.

func New

func New(rows, cols int) *VTerm

New creates a VTerm with the given dimensions.

func NewWithWriter

func NewWithWriter(rows, cols int, w io.Writer) *VTerm

NewWithWriter creates a VTerm with a response writer. The writer is used by terminal query responses such as CPR (ESC[6n -> ESC[row;colR), which interactive programs expect from a real terminal.

func (*VTerm) ClearDirty

func (v *VTerm) ClearDirty()

ClearDirty resets the dirty flag.

func (*VTerm) ClearScrollback

func (v *VTerm) ClearScrollback()

ClearScrollback discards all retained scrollback history.

func (*VTerm) Cols

func (v *VTerm) Cols() int

Cols returns the current number of columns.

func (*VTerm) CursorPos

func (v *VTerm) CursorPos() (row, col int)

CursorPos returns the current cursor position (row, col), 0-indexed.

func (*VTerm) IsAltScreen

func (v *VTerm) IsAltScreen() bool

IsAltScreen returns true if the alternate screen buffer is active. This indicates an interactive fullscreen program (vim, htop, less, etc.).

func (*VTerm) IsAppCursorKeys

func (v *VTerm) IsAppCursorKeys() bool

IsAppCursorKeys returns true while DECCKM (\x1b[?1h, terminfo smkx) is active: the child program expects cursor keys in the SS3 "application" encoding (\x1bOA..\x1bOD) instead of CSI (\x1b[A..\x1b[D). less and other termcap-driven programs IGNORE the CSI form entirely, so web/mobile clients must consult this before synthesizing arrow keys.

func (*VTerm) IsCursorHidden

func (v *VTerm) IsCursorHidden() bool

IsCursorHidden returns true if the terminal cursor is hidden (\x1b[?25l). TUI frameworks like Bubble Tea (used by Claude Code) hide the cursor on startup even when they don't use alternate screen mode.

func (*VTerm) IsDirty

func (v *VTerm) IsDirty() bool

IsDirty returns true if the screen has been written to since last ClearDirty.

func (*VTerm) IsMouseEnabled

func (v *VTerm) IsMouseEnabled() bool

IsMouseEnabled returns true if any mouse tracking mode is active. Programs that want mouse input (vim, htop) enable tracking via \x1b[?1000h, \x1b[?1002h, \x1b[?1003h, etc. When mouse tracking is NOT enabled, mouse events should not be forwarded to the PTY — the shell would display them as garbled text.

func (*VTerm) MouseProtocol added in v0.2.3

func (v *VTerm) MouseProtocol() (mode string, sgr bool)

MouseProtocol reports what the child program actually asked for: its tracking mode (one of the Mouse* constants, MouseOff when tracking is off) and whether it also enabled SGR extended encoding (\x1b[?1006h).

Both halves matter when synthesizing an event for the child. A program that enabled \x1b[?1000h WITHOUT \x1b[?1006h expects the legacy X10 byte encoding (\x1b[M Cb+32 Cx+32 Cy+32) and cannot parse an SGR report (\x1b[<0;5;7M) — a line editor handed one typically eats the escape introducer and echoes the rest into its input buffer as literal text.

func (*VTerm) Render

func (v *VTerm) Render() []string

Render produces the current screen content as a slice of strings (one per row).

func (*VTerm) RenderANSI

func (v *VTerm) RenderANSI() []string

RenderANSI produces the current screen content as a slice of strings with ANSI escape sequences that preserve foreground/background colours and text attributes (bold, italic, underline, blink, reverse). Trailing cells that are plain spaces with default colours are trimmed to keep lines compact.

func (*VTerm) RenderANSIWithCursor

func (v *VTerm) RenderANSIWithCursor() []string

RenderANSIWithCursor is like RenderANSI but draws a block cursor (reverse video on the cursor cell) when the cursor is visible. It is used for the in-pane VT rendering: the TUI renders the screen as plain text and cannot position a real hardware cursor, so without this the cursor of interactive programs such as vim would be invisible. When the cursor is hidden (\x1b[?25l, e.g. Bubble Tea apps like Claude Code) no cursor is drawn.

func (*VTerm) Repaint

func (v *VTerm) Repaint() []byte

Repaint returns a byte sequence that, when written to a freshly created terminal emulator, reconstructs the current screen contents and cursor position. It is used to resume an interactive share session for a (re)joining subscriber whose remote VTerm starts empty: the source replays this so the subscriber sees the live app immediately instead of waiting for the app to redraw on its own.

The sequence clears the screen, then positions the cursor explicitly at the start of each row before writing that row's ANSI-styled content (avoiding any reliance on auto-wrap), and finally restores the real cursor position.

func (*VTerm) ResetMouseModes added in v0.2.3

func (v *VTerm) ResetMouseModes()

ResetMouseModes turns every mouse tracking and encoding mode off (\x1b[?9l, ?1000l, ?1002l, ?1003l, ?1006l).

The emulator outlives the programs that run in the pane: it is created once and fed every byte that pane's PTY ever produces. A program that enables tracking and dies without disabling it — killed with Ctrl+C, crashed, or simply sloppy on teardown — therefore leaves the tracking bit set for the rest of the pane's life, and every later program looks like it wants mouse reports. The TUI then forwards wheel and click events into the PTY of something that never asked for them (Claude Code, a bare shell), which shows them as literal text like "<65;50;54M".

Callers reset when the pane's foreground program changes; anything that wants tracking re-enables it on startup.

func (*VTerm) Resize

func (v *VTerm) Resize(rows, cols int)

Resize changes the virtual terminal dimensions.

func (*VTerm) Rows

func (v *VTerm) Rows() int

Rows returns the current number of rows.

func (*VTerm) ScrollbackANSI

func (v *VTerm) ScrollbackANSI() []string

ScrollbackANSI returns the scrollback history rendered to ANSI strings, oldest line first.

func (*VTerm) ScrollbackEvictedTotal

func (v *VTerm) ScrollbackEvictedTotal() int64

ScrollbackEvictedTotal returns the monotonic count of lines ever captured into scrollback. Lets a consumer compute how many new lines appeared since it last checked, even after the ring has dropped older lines.

func (*VTerm) ScrollbackLen

func (v *VTerm) ScrollbackLen() int

ScrollbackLen returns the number of retained scrollback lines.

func (*VTerm) ScrollbackTailANSI

func (v *VTerm) ScrollbackTailANSI(n int) []string

ScrollbackTailANSI returns the last n scrollback lines rendered to ANSI strings, oldest of the returned set first (fewer if the ring holds fewer).

func (*VTerm) SetScrollbackMax

func (v *VTerm) SetScrollbackMax(n int)

SetScrollbackMax sets how many scrolled-off lines the emulator retains.

func (*VTerm) Write

func (v *VTerm) Write(p []byte) (int, error)

Write feeds raw PTY output bytes into the VT emulator. Thread-safe: can be called from the PTY read goroutine.

Before forwarding to vt10x, CSI sequences with private parameter markers '>', '<', or '=' are stripped. These are modern terminal protocol extensions (Kitty keyboard protocol, xterm modifyOtherKeys, etc.) that vt10x does not understand. Without filtering, vt10x misinterprets e.g. ESC[>1u (Kitty keyboard push) as ESC[u (SCORC — restore cursor), resetting the cursor to the origin and breaking inline TUI layout (Claude Code, Bubble Tea apps).

Directories

Path Synopsis
Package terminal is a vt10x terminal emulation backend, influenced largely by st, rxvt, xterm, and iTerm as reference.
Package terminal is a vt10x terminal emulation backend, influenced largely by st, rxvt, xterm, and iTerm as reference.

Jump to

Keyboard shortcuts

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