vt10x

package module
v0.0.13 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2026 License: MIT Imports: 17 Imported by: 0

README

vt10x

GoDoc

Package vt10x is a vt10x terminal emulation backend, influenced largely by st, rxvt, xterm, and iTerm as reference. Use it for terminal muxing, a terminal emulation frontend, or wherever else you need terminal emulation.

Original vt10x interface has been extended to support the following:

  • ANSI line renderer (can return full terminal buffer as ANSI escaped strings for direct rendering to external terminal emulator)
  • Maintain history buffer for supporting a scroll-back window
  • Standard 256 color palette
  • Support for RGB ANSI color rendering (rgb fg / gb colors on the cell will always be larger than 255)

usage

the vt10x terminal emulator needs to be paired with a pseudo TTY in order to work. the following demonstrates basic operation:

package main

import (
    "os/exec"
    "github.com/creack/pty"
)


func main() {
    // create the terminal with initial size
    term := vt10x.New(vt10x.WithSize(80, 25))

    cmd := exec.Command("/bin/bash")

    // start the command with the pseudo TTY
    ptyFile, err := pty.Start(cmd)

    go func() {
        // create a temporary output buffer
        buf := make([]byte, 4096)

        for {
            // read output from the pseudo TTY
            n, err := ptyFile.Read(buf)
            if err != nil {
                if errors.Is(err, syscall.EIO) {
                    // take appropriate action here, this means the command process exited
					os.Exit(0)
                    return
				}

                log.Fatal(err)
            }

            // write the stdout data from the ptty to the terminal
            _, _ = term.Write(buf[:n])

            // here, your main application should receive a request to redraw the terminal.
            // this will be illustrated below in another block
            ...
        }
    }()

    go func() {
        // this function should receive input and send it to the ptty
        for {
            nBytes, err := os.Stdin.Read(byteBuf)
			if err != nil {
				log.Fatal(err)
			}

            _, _ = ptyFile.Write(byteBuf[:nBytes])
        }
    }()


}

there are two primary interfaces for drawing the terminal, depending on what type of output interface is available. vt10x exposes both a cell interface, allowing an integrator to query data on a per character (cell) basis, which will obtain the character, foreground, and background color

for y := 0; y < term.rows; y++ {
    for x := 0; x < term.cols; x++ {
        glyph := term.Cell(x, y)

        // TODO: draw the character
    }
}

the second interface allows for rendering of ANSI strings to an external terminal emulator. if the application is being executed within a terminal emulator, such as gnome terminal, it often makes sense to merely output ANSI escaped text line by line in raw terminal mode and for that, this interface is available:

rows := term.TextRows()
for y, row := range rows {
    // set cursor position at the top left of the current row
    data, _ := row.Render()
    fmt.Println(data)
}

lastly, a similar interface is also supported to render data from the history buffer.

// the 0 offset means no offset from the present.  it will be similar to simply calling term.TextRows().  A negative offset indicates a position back in the history buffer.  For example -10 would start from 10 rows above the top line
// the history buffer size (including what's not yet part of the history) can be obtained by calling

maxRows := term.HistoryBufferLength()
rows := term.History(0)
for y, row := range rows {
    // set cursor position at the top left of the current row
    data, _ := row.Render()
    fmt.Println(data)
}

history can also be accessed using the cell interface, where the row index < 0

Documentation

Overview

Package terminal is a vt10x terminal emulation backend, influenced largely by st, rxvt, xterm, and iTerm as reference. Use it for terminal muxing, a terminal emulation frontend, or wherever else you need terminal emulation.

In development, but very usable.

Index

Constants

View Source
const DefaultHistoryBufferSize int = 10000
View Source
const MaxLen = 1000

Variables

View Source
var (
	RGBPattern  = regexp.MustCompile(`^([\da-f]{1})\/([\da-f]{1})\/([\da-f]{1})$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$`)
	HashPattern = regexp.MustCompile(`[\da-f]`)
)

Functions

func ResizePty

func ResizePty(pty *os.File, cols, rows int) error

Types

type BufferSource added in v0.0.6

type BufferSource int
const (
	BufferSourceHistory BufferSource = iota
	BufferSourceTerminal
)

type ChangeFlag

type ChangeFlag uint32

ChangeFlag represents possible state changes of the terminal.

const (
	ChangedScreen ChangeFlag = 1 << iota
	ChangedTitle
)

Terminal changes to occur in VT.ReadState

type Color

type Color uint32

Color maps to the ANSI colors [0, 16) and the xterm colors [16, 256).

const (
	Black Color = iota
	Red
	Green
	Yellow
	Blue
	Magenta
	Cyan
	LightGrey
	DarkGrey
	LightRed
	LightGreen
	LightYellow
	LightBlue
	LightMagenta
	LightCyan
	White
)

ANSI color values

const (
	DefaultFG Color = 1<<24 + iota
	DefaultBG
	DefaultCursor
)

Default colors are potentially distinct to allow for special behavior. For example, a transparent background. Otherwise, the simple case is to map default colors to another color.

type Cursor

type Cursor struct {
	Attr  Glyph
	X, Y  int
	State uint8
}

type Glyph

type Glyph struct {
	Char   rune
	Mode   int16
	FG, BG Color
}

type ModeFlag

type ModeFlag uint32

ModeFlag represents various terminal mode states.

const (
	ModeWrap ModeFlag = 1 << iota
	ModeInsert
	ModeAppKeypad
	ModeAltScreen
	ModeCRLF
	ModeMouseButton
	ModeMouseMotion
	ModeReverse
	ModeKeyboardLock
	ModeHide
	ModeEcho
	ModeAppCursor
	ModeMouseSgr
	Mode8bit
	ModeBlink
	ModeFBlink
	ModeFocus
	ModeMouseX10
	ModeMouseMany
	ModeMouseMask = ModeMouseButton | ModeMouseMotion | ModeMouseX10 | ModeMouseMany
)

Terminal modes

type State

type State struct {
	DebugLogger *log.Logger
	// contains filtered or unexported fields
}

State represents the terminal emulation state. Use Lock/Unlock methods to synchronize data access with VT.

func (*State) Cell

func (t *State) Cell(x, y int) Glyph

Cell returns the glyph containing the character code, foreground color, and background color at position (x, y) relative to the top left of the terminal. When y is a negative number, it will be pulled from the history buffer a -y rows from the current row.

func (*State) Changed

func (t *State) Changed(change ChangeFlag) bool

Changed returns true if change has occured.

func (*State) Cursor

func (t *State) Cursor() Cursor

Cursor returns the current position of the cursor.

func (*State) CursorVisible

func (t *State) CursorVisible() bool

CursorVisible returns the visible state of the cursor.

func (*State) History added in v0.0.4

func (t *State) History(offset int) []*style.Text

History returns the history buffer starting from a negative offset point from the present moment. An offset of zero represents the current moment in time, which will represent the last row in the returned array. The returned array will contain one vertical terminal worth of rows.

func (*State) HistoryBufferLength added in v0.0.4

func (t *State) HistoryBufferLength() int

HistoryBufferLength returns the length of the history buffer, including the active termninal height

func (*State) Lock

func (t *State) Lock()

Lock locks the state object's mutex.

func (*State) Mode

func (t *State) Mode() ModeFlag

Mode returns the current terminal mode.

func (*State) Size

func (t *State) Size() (cols, rows int)

func (*State) String

func (t *State) String() string

func (*State) Text added in v0.0.10

func (t *State) Text(bufferSource BufferSource, rowNum int) *style.Text

func (*State) TextRows added in v0.0.10

func (t *State) TextRows() []*style.Text

TextRows returns the contents as a list of ANSI strings

func (*State) Title

func (t *State) Title() string

Title returns the current title set via the tty.

func (*State) Unlock

func (t *State) Unlock()

Unlock resets change flags and unlocks the state object's mutex.

type Terminal

type Terminal interface {
	// View displays the virtual terminal.
	View

	// Write parses input and writes terminal changes to state.
	io.Writer

	// Parse blocks on read on pty or io.Reader, then parses sequences until
	// buffer empties. State is locked as soon as first rune is read, and unlocked
	// when buffer is empty.
	Parse(bf *bufio.Reader) error
}

Terminal represents the virtual terminal emulator.

func New

func New(opts ...TerminalOption) Terminal

New returns a new virtual terminal emulator.

type TerminalInfo

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

type TerminalOption

type TerminalOption func(*TerminalInfo)

func WithHistoryBuffer added in v0.0.4

func WithHistoryBuffer(historyLength int) TerminalOption

func WithSize

func WithSize(cols, rows int) TerminalOption

func WithWriter

func WithWriter(w io.Writer) TerminalOption

type View

type View interface {
	// String dumps the virtual terminal contents.
	fmt.Stringer

	// Size returns the size of the virtual terminal.
	Size() (cols, rows int)

	// Resize changes the size of the virtual terminal.
	Resize(cols, rows int)

	// Mode returns the current terminal mode.//
	Mode() ModeFlag

	// Title represents the title of the console window.
	Title() string

	// Cell returns the glyph containing the character code, foreground color, and
	// background color at position (x, y) relative to the top left of the terminal.
	Cell(x, y int) Glyph

	// TextRows returns the contents as a list of *style.Text items
	TextRows() []*style.Text

	// History returns a viewport sized array of lines representing the scrollback history, starting from offset.
	// An offset of zero represents the current moment in time
	History(offset int) []*style.Text

	// HistoryBufferLength returns the length of the history buffer, including the active termninal height
	HistoryBufferLength() int

	// Cursor returns the current position of the cursor.
	Cursor() Cursor

	// CursorVisible returns the visible state of the cursor.
	CursorVisible() bool

	// Lock locks the state object's mutex.
	Lock()

	// Unlock resets change flags and unlocks the state object's mutex.
	Unlock()
}

View represents the view of the virtual terminal emulator.

Jump to

Keyboard shortcuts

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