purfecterm

package module
v0.2.16 Latest Latest
Warning

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

Go to latest
Published: Dec 27, 2025 License: MIT Imports: 11 Imported by: 0

README

PurfecTerm

A terminal emulator library for Go with GTK3 and Qt5 widget implementations.

Features

  • Full VT100/VT220/xterm terminal emulation
  • 256-color and true color (24-bit) support
  • Unicode and CJK character support
  • Scrollback buffer with configurable size
  • Mouse support (selection, copy/paste)
  • PTY management for running shell commands
  • Platform support: Linux, macOS, Windows

Packages

  • purfecterm - Core terminal buffer, ANSI parser, and PTY abstraction
  • purfecterm/gtk - GTK3 terminal widget
  • purfecterm/qt - Qt5 terminal widget

Installation

go get github.com/phroun/purfecterm
GTK3 Widget
# Linux
sudo apt install libgtk-3-dev

# macOS
brew install gtk+3

go get github.com/phroun/purfecterm/gtk
Qt5 Widget
# Linux
sudo apt install qtbase5-dev

# macOS
brew install qt@5

go get github.com/phroun/purfecterm/qt

Usage

GTK3 Example
package main

import (
    "os"
    "runtime"

    "github.com/gotk3/gotk3/glib"
    "github.com/gotk3/gotk3/gtk"
    terminal "github.com/phroun/purfecterm/gtk"
)

func main() {
    runtime.LockOSThread()

    app, _ := gtk.ApplicationNew("com.example.terminal", glib.APPLICATION_FLAGS_NONE)
    app.Connect("activate", func() {
        win, _ := gtk.ApplicationWindowNew(app)
        win.SetTitle("Terminal")
        win.SetDefaultSize(800, 600)

        term, _ := terminal.New(terminal.Options{
            Cols: 80, Rows: 24, ScrollbackSize: 10000,
            FontFamily: "Monospace", FontSize: 12,
        })

        win.Add(term.Widget())
        win.Connect("destroy", func() { term.Close() })
        win.ShowAll()
        win.Present()

        glib.IdleAdd(func() bool { term.RunShell(); return false })
    })
    os.Exit(app.Run(os.Args))
}
Qt5 Example
package main

import (
    "os"
    "runtime"

    "github.com/mappu/miqt/qt"
    terminal "github.com/phroun/purfecterm/qt"
)

func main() {
    runtime.LockOSThread()
    qt.NewQApplication(os.Args)

    win := qt.NewQMainWindow(nil)
    win.SetWindowTitle("Terminal")
    win.Resize(800, 600)

    term, _ := terminal.New(terminal.Options{
        Cols: 80, Rows: 24, ScrollbackSize: 10000,
        FontFamily: "Monospace", FontSize: 12,
    })

    win.SetCentralWidget(term.Widget())
    win.Show()

    term.RunShell()
    qt.QApplication_Exec()
}
Core Buffer Only
package main

import (
    "fmt"
    "github.com/phroun/purfecterm"
)

func main() {
    // Create a terminal buffer
    buf := purfecterm.NewBuffer(80, 24, 1000)

    // Create parser and feed ANSI data
    parser := purfecterm.NewParser(buf)
    parser.Parse([]byte("\x1b[31mHello, World!\x1b[0m\n"))

    // Get cell content
    cell := buf.GetCell(0, 0)
    fmt.Printf("Character: %c, Color: R=%d G=%d B=%d\n",
        cell.Char, cell.Foreground.R, cell.Foreground.G, cell.Foreground.B)
}

See the examples/ directory for complete working examples.

Color Schemes

// Use the default color scheme
scheme := purfecterm.DefaultColorScheme()

// Or create a custom one
scheme := purfecterm.ColorScheme{
    DarkForeground:  purfecterm.Color{R: 200, G: 200, B: 200},
    DarkBackground:  purfecterm.Color{R: 30, G: 30, B: 30},
    LightForeground: purfecterm.Color{R: 40, G: 40, B: 40},
    LightBackground: purfecterm.Color{R: 255, G: 255, B: 255},
    // ... palette colors
}

term.SetColorScheme(scheme)

License

MIT License - see LICENSE file for details.

Documentation

Overview

Package purfecterm provides the core terminal emulation logic shared between GUI toolkit implementations (GTK, Qt, etc.).

This package contains:

  • Color types and palettes
  • Cell representation
  • Terminal buffer with scrollback
  • ANSI escape sequence parser
  • PTY interfaces

GUI-specific packages (purfecterm-gtk, purfecterm-qt) provide the widget implementations that use this core package.

Index

Constants

This section is empty.

Variables

View Source
var (
	DefaultForeground = Color{Type: ColorTypeDefault, R: 212, G: 212, B: 212}
	DefaultBackground = Color{Type: ColorTypeDefault, R: 30, G: 30, B: 30}
)

Predefined colors

View Source
var ANSIColors = func() []Color {
	colors := make([]Color, 16)
	for i := 0; i < 16; i++ {
		colors[i] = StandardColor(i)
	}
	return colors
}()

ANSIColors returns standard ANSI colors as full Color structs (for backwards compatibility)

View Source
var ANSIColorsRGB = []RGB{
	{R: 0, G: 0, B: 0},
	{R: 170, G: 0, B: 0},
	{R: 0, G: 170, B: 0},
	{R: 170, G: 85, B: 0},
	{R: 0, G: 0, B: 170},
	{R: 170, G: 0, B: 170},
	{R: 0, G: 170, B: 170},
	{R: 170, G: 170, B: 170},

	{R: 85, G: 85, B: 85},
	{R: 255, G: 85, B: 85},
	{R: 85, G: 255, B: 85},
	{R: 255, G: 255, B: 85},
	{R: 85, G: 85, B: 255},
	{R: 255, G: 85, B: 255},
	{R: 85, G: 255, B: 255},
	{R: 255, G: 255, B: 255},
}

Standard ANSI 16-color palette RGB values (in ANSI order for escape code compatibility)

View Source
var ANSIToVGA = []int{0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15}

ANSIToVGA maps ANSI color index to VGA/CGA color index

View Source
var ColorNames = map[string]int{
	"00_black": 0, "01_dark_blue": 1, "02_dark_green": 2, "03_dark_cyan": 3,
	"04_dark_red": 4, "05_purple": 5, "06_brown": 6, "07_silver": 7,
	"08_dark_gray": 8, "09_bright_blue": 9, "10_bright_green": 10, "11_bright_cyan": 11,
	"12_bright_red": 12, "13_pink": 13, "14_yellow": 14, "15_white": 15,
}

ColorNames maps ANSI color index names to their indices (0-15)

View Source
var VGAToANSI = []int{0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15}

VGAToANSI maps VGA/CGA color index to ANSI color index

Functions

func DefaultPaletteHex

func DefaultPaletteHex() []string

DefaultPaletteHex returns the default 16-color palette as hex strings in VGA order

func GetEastAsianWidth

func GetEastAsianWidth(r rune) float64

GetEastAsianWidth returns the East Asian Width property for a rune. Returns the width in cell units: - Halfwidth (H): 1.0 (half compared to normal CJK = same as Latin) - Narrow (Na) / Neutral (N): 1.0 - Ambiguous (A): returns -1.0 to indicate "use context" (caller handles) - Fullwidth (F) / Wide (W): 2.0

func IsAmbiguousWidth

func IsAmbiguousWidth(r rune) bool

IsAmbiguousWidth returns true if the character has ambiguous East Asian Width

func IsBlockOrLineDrawing

func IsBlockOrLineDrawing(r rune) bool

IsBlockOrLineDrawing returns true if the character is a box drawing or block element These characters need full 2.0 scaling to connect properly when rendered wide

func IsCombiningMark

func IsCombiningMark(r rune) bool

IsCombiningMark returns true if the rune is a Unicode combining character. This includes: - Combining Diacritical Marks (0x0300-0x036F) - Hebrew vowel points and marks (0x0591-0x05C7) - Arabic marks (0x0610-0x065F, 0x0670, 0x06D6-0x06ED) - Other combining marks (Mn, Mc, Me categories)

func PaletteColorNames

func PaletteColorNames() []string

PaletteColorNames returns the names for the 16 palette colors in order

Types

type AmbiguousWidthMode

type AmbiguousWidthMode int

AmbiguousWidthMode controls how ambiguous East Asian Width characters are rendered

const (
	AmbiguousWidthAuto   AmbiguousWidthMode = iota // Match width of previous character
	AmbiguousWidthNarrow                           // Force 1.0 width
	AmbiguousWidthWide                             // Force 2.0 width
)

type BlinkMode

type BlinkMode int

BlinkMode determines how the blink attribute is rendered

const (
	BlinkModeBounce BlinkMode = iota // Bobbing wave animation (default)
	BlinkModeBlink                   // Traditional on/off blinking
	BlinkModeBright                  // Interpret as bright background (VGA style)
)

func ParseBlinkMode

func ParseBlinkMode(s string) BlinkMode

ParseBlinkMode parses a blink mode string

type Buffer

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

Buffer manages the terminal screen and scrollback buffer

func NewBuffer

func NewBuffer(cols, rows, maxScrollback int) *Buffer

NewBuffer creates a new terminal buffer

func (*Buffer) Backspace

func (b *Buffer) Backspace()

Backspace moves cursor left one position

func (*Buffer) CarriageReturn

func (b *Buffer) CarriageReturn()

CarriageReturn moves cursor to the beginning of the current line

func (*Buffer) CheckCursorAutoScroll

func (b *Buffer) CheckCursorAutoScroll() bool

CheckCursorAutoScroll checks if the cursor was not drawn last frame and auto-scroll is active, then scrolls toward the cursor position to bring the cursor back into view. When the cursor is multiple lines away, it scrolls multiple lines at once for faster catch-up. Returns true if a scroll occurred.

func (*Buffer) CheckCursorAutoScrollHoriz

func (b *Buffer) CheckCursorAutoScrollHoriz() bool

CheckCursorAutoScrollHoriz checks horizontal memos and auto-scrolls if needed. Returns true if a scroll occurred. Call this after paint, after memos have been populated.

func (*Buffer) ClearDirty

func (b *Buffer) ClearDirty()

ClearDirty clears the dirty flag

func (*Buffer) ClearHorizMemos

func (b *Buffer) ClearHorizMemos()

ClearHorizMemos clears all horizontal scroll memos before a new paint frame. Call this at the start of each paint.

func (*Buffer) ClearLine

func (b *Buffer) ClearLine()

ClearLine clears the entire current line This updates the line's default cell

func (*Buffer) ClearScreen

func (b *Buffer) ClearScreen()

ClearScreen clears the entire screen and resets view to show top

func (*Buffer) ClearScreenCrop

func (b *Buffer) ClearScreenCrop()

ClearScreenCrop removes both width and height crops.

func (*Buffer) ClearScrollback

func (b *Buffer) ClearScrollback()

ClearScrollback clears the scrollback buffer

func (*Buffer) ClearSelection

func (b *Buffer) ClearSelection()

ClearSelection clears any active selection

func (*Buffer) ClearToEndOfLine

func (b *Buffer) ClearToEndOfLine()

ClearToEndOfLine clears from cursor to end of line This updates the line's default cell and truncates the line at cursor position

func (*Buffer) ClearToEndOfScreen

func (b *Buffer) ClearToEndOfScreen()

ClearToEndOfScreen clears from cursor to end of screen This updates the ScreenInfo default cell

func (*Buffer) ClearToStartOfLine

func (b *Buffer) ClearToStartOfLine()

ClearToStartOfLine clears from start of line to cursor Note: Does NOT update LineInfo (LineInfo is for right side of line) Note: Does NOT extend the line - only clears existing cells

func (*Buffer) ClearToStartOfScreen

func (b *Buffer) ClearToStartOfScreen()

ClearToStartOfScreen clears from start of screen to cursor Note: Does NOT update ScreenInfo (ScreenInfo is for lines below stored content) Note: Does NOT extend lines - only clears existing cells

func (*Buffer) ColorToANSICode

func (b *Buffer) ColorToANSICode(c Color) int

ColorToANSICode returns the ANSI color code for this color. For Standard colors (0-15), returns 30-37 or 90-97. For Palette colors (0-255), returns the palette index mapped to SGR codes. For TrueColor or Default, returns 37 (white) as fallback.

func (*Buffer) DeleteAllCropRects

func (b *Buffer) DeleteAllCropRects()

DeleteAllCropRects removes all crop rectangles

func (*Buffer) DeleteAllGlyphs

func (b *Buffer) DeleteAllGlyphs()

DeleteAllGlyphs removes all custom glyph definitions

func (*Buffer) DeleteAllPalettes

func (b *Buffer) DeleteAllPalettes()

DeleteAllPalettes removes all custom palettes

func (*Buffer) DeleteAllScreenSplits

func (b *Buffer) DeleteAllScreenSplits()

DeleteAllScreenSplits removes all screen splits.

func (*Buffer) DeleteAllSprites

func (b *Buffer) DeleteAllSprites()

DeleteAllSprites removes all sprites

func (*Buffer) DeleteChars

func (b *Buffer) DeleteChars(n int)

DeleteChars deletes n characters at cursor

func (*Buffer) DeleteCropRect

func (b *Buffer) DeleteCropRect(id int)

DeleteCropRect removes a specific crop rectangle

func (*Buffer) DeleteGlyph

func (b *Buffer) DeleteGlyph(r rune)

DeleteGlyph removes a specific custom glyph definition

func (*Buffer) DeleteLines

func (b *Buffer) DeleteLines(n int)

DeleteLines deletes n lines at cursor

func (*Buffer) DeletePalette

func (b *Buffer) DeletePalette(n int)

DeletePalette removes a specific palette

func (*Buffer) DeleteScreenSplit

func (b *Buffer) DeleteScreenSplit(id int)

DeleteScreenSplit removes a specific screen split by ID.

func (*Buffer) DeleteSprite

func (b *Buffer) DeleteSprite(id int)

DeleteSprite removes a specific sprite

func (*Buffer) EffectiveCols

func (b *Buffer) EffectiveCols() int

EffectiveCols returns the logical column count (physical if logical is 0)

func (*Buffer) EffectiveRows

func (b *Buffer) EffectiveRows() int

EffectiveRows returns the logical row count (physical if logical is 0)

func (*Buffer) EndSelection

func (b *Buffer) EndSelection()

EndSelection finalizes the selection

func (*Buffer) EraseChars

func (b *Buffer) EraseChars(n int)

EraseChars erases n characters at cursor (replaces with blanks) Does not extend line beyond current length - only erases existing cells

func (*Buffer) Get132ColumnMode

func (b *Buffer) Get132ColumnMode() bool

Get132ColumnMode returns whether 132-column mode is enabled

func (*Buffer) Get40ColumnMode

func (b *Buffer) Get40ColumnMode() bool

Get40ColumnMode returns whether 40-column mode is enabled

func (*Buffer) GetAmbiguousWidthMode

func (b *Buffer) GetAmbiguousWidthMode() AmbiguousWidthMode

GetAmbiguousWidthMode returns the current ambiguous width mode

func (*Buffer) GetBGP

func (b *Buffer) GetBGP() int

GetBGP returns the current Base Glyph Palette setting

func (*Buffer) GetCell

func (b *Buffer) GetCell(x, y int) Cell

GetCell returns the cell at the given screen position For positions beyond stored line length, returns the line's default cell

func (*Buffer) GetCellForSplit

func (b *Buffer) GetCellForSplit(screenX, screenY, bufferRow, bufferCol int) Cell

GetCellForSplit returns a cell for split rendering. screenX/screenY: position within the split region (0 = first cell of split) bufferRow/bufferCol: buffer offset for this split (0-indexed) The cell is fetched from the logical screen at position (screenX + bufferCol, screenY + bufferRow) accounting for the current scroll offset.

func (*Buffer) GetCropRect

func (b *Buffer) GetCropRect(id int) *CropRectangle

GetCropRect returns a crop rectangle by ID, or nil if not found

func (*Buffer) GetCursor

func (b *Buffer) GetCursor() (x, y int)

GetCursor returns the current cursor position

func (*Buffer) GetCursorStyle

func (b *Buffer) GetCursorStyle() (shape, blink int)

GetCursorStyle returns the cursor shape and blink mode

func (*Buffer) GetCursorVisiblePosition

func (b *Buffer) GetCursorVisiblePosition() (x, y int)

GetCursorVisiblePosition returns the visible (x, y) position of the cursor accounting for scroll offset and magnetic zone. Returns (-1, -1) if the cursor is not currently visible.

func (*Buffer) GetCursorVisibleY

func (b *Buffer) GetCursorVisibleY() int

GetCursorVisibleY returns just the cursor's visible Y position (row) on the physical screen, even if the cursor is horizontally off-screen. Returns -1 if the cursor's line is not within the visible vertical area. This is useful for cursor tracking: we want to know if the cursor's LINE is being rendered, regardless of whether the cursor itself is visible.

func (*Buffer) GetEffectiveScrollOffset

func (b *Buffer) GetEffectiveScrollOffset() int

GetEffectiveScrollOffset returns the scroll offset adjusted for the magnetic zone. Use this for rendering sprites, splits, and other positioned elements that should remain stable during the magnetic zone.

func (*Buffer) GetGlyph

func (b *Buffer) GetGlyph(r rune) *CustomGlyph

GetGlyph returns the custom glyph for a rune, or nil if none defined

func (*Buffer) GetHorizMemos

func (b *Buffer) GetHorizMemos() []HorizMemo

GetHorizMemos returns a copy of all horizontal memos (for debugging/inspection).

func (*Buffer) GetHorizOffset

func (b *Buffer) GetHorizOffset() int

GetHorizOffset returns current horizontal scroll offset

func (*Buffer) GetHorizontalScale

func (b *Buffer) GetHorizontalScale() float64

GetHorizontalScale returns the combined horizontal scaling factor 132-column mode: 0.6060, 40-column mode: 2.0 If both enabled: 0.6060 * 2.0 = 1.212

func (*Buffer) GetLineAttribute

func (b *Buffer) GetLineAttribute(y int) LineAttribute

GetLineAttribute returns the display attribute for the specified line

func (*Buffer) GetLineAttributeForSplit

func (b *Buffer) GetLineAttributeForSplit(screenY, bufferRow int) LineAttribute

GetLineAttributeForSplit returns the line attribute for split rendering.

func (*Buffer) GetLineDensity

func (b *Buffer) GetLineDensity() int

GetLineDensity returns the current line density

func (*Buffer) GetLineInfo

func (b *Buffer) GetLineInfo(y int) LineInfo

GetLineInfo returns the full LineInfo for the specified line

func (*Buffer) GetLineLengthForSplit

func (b *Buffer) GetLineLengthForSplit(screenY, bufferRow, bufferCol int) int

GetLineLengthForSplit returns the effective content length for a split row. This is the line length minus the BufferCol offset (content before BufferCol is excluded). Used to know when to stop rendering (no more content on line).

func (*Buffer) GetLineVisualWidth

func (b *Buffer) GetLineVisualWidth(row, col int) float64

GetLineVisualWidth returns the visual width of a line up to (but not including) col. This is the public thread-safe version.

func (*Buffer) GetLogicalSize

func (b *Buffer) GetLogicalSize() (logicalRows, logicalCols int)

GetLogicalSize returns the logical terminal dimensions Returns 0 for dimensions that are set to "use physical"

func (*Buffer) GetLongestLineInScrollback

func (b *Buffer) GetLongestLineInScrollback() int

GetLongestLineInScrollback returns the length of the longest line in scrollback

func (*Buffer) GetLongestLineOnScreen

func (b *Buffer) GetLongestLineOnScreen() int

GetLongestLineOnScreen returns the length of the longest line currently on the logical screen

func (*Buffer) GetLongestLineVisible

func (b *Buffer) GetLongestLineVisible() int

GetLongestLineVisible returns the longest line width currently visible. Only includes scrollback width when the yellow dashed boundary line is visible.

func (*Buffer) GetMaxHorizOffset

func (b *Buffer) GetMaxHorizOffset() int

GetMaxHorizOffset returns the maximum horizontal scroll offset

func (*Buffer) GetMaxScrollOffset

func (b *Buffer) GetMaxScrollOffset() int

GetMaxScrollOffset returns the maximum vertical scroll offset This accounts for scrollback AND any logical rows hidden above the visible area

func (*Buffer) GetPalette

func (b *Buffer) GetPalette(n int) *Palette

GetPalette returns a palette by number, or nil if it doesn't exist

func (*Buffer) GetPreferredDarkTheme

func (b *Buffer) GetPreferredDarkTheme() bool

GetPreferredDarkTheme returns the user's preferred theme

func (*Buffer) GetScreenCrop

func (b *Buffer) GetScreenCrop() (widthCrop, heightCrop int)

GetScreenCrop returns the current width and height crop values. -1 means no crop for that dimension.

func (*Buffer) GetScreenSplit

func (b *Buffer) GetScreenSplit(id int) *ScreenSplit

GetScreenSplit returns a screen split by ID, or nil if not found.

func (*Buffer) GetScreenSplitsSorted

func (b *Buffer) GetScreenSplitsSorted() []*ScreenSplit

GetScreenSplitsSorted returns all screen splits sorted by ScreenY coordinate.

func (*Buffer) GetScrollOffset

func (b *Buffer) GetScrollOffset() int

GetScrollOffset returns current scroll offset

func (*Buffer) GetScrollbackBoundaryVisibleRow

func (b *Buffer) GetScrollbackBoundaryVisibleRow() int

GetScrollbackBoundaryVisibleRow returns the visible row (0-indexed from top of display) where the boundary between scrollback and logical screen is located. Returns -1 if the boundary is not currently visible (either fully in scrollback or fully in logical screen). The magnetic threshold suppresses the boundary for the first few rows after it would appear, creating a "sticky" feel when transitioning from logical screen to scrollback.

func (*Buffer) GetScrollbackSize

func (b *Buffer) GetScrollbackSize() int

GetScrollbackSize returns the number of lines in scrollback

func (*Buffer) GetSelectedText

func (b *Buffer) GetSelectedText() string

GetSelectedText returns the text in the current selection

func (*Buffer) GetSelection

func (b *Buffer) GetSelection() (startX, startY, endX, endY int, active bool)

GetSelection returns the normalized selection bounds in buffer-absolute coordinates

func (*Buffer) GetSize

func (b *Buffer) GetSize() (cols, rows int)

GetSize returns the current terminal dimensions

func (*Buffer) GetSplitContentWidth

func (b *Buffer) GetSplitContentWidth() int

GetSplitContentWidth returns the max content width found across all split regions. Returns 0 if no splits are active or have content.

func (*Buffer) GetSprite

func (b *Buffer) GetSprite(id int) *Sprite

GetSprite returns a sprite by ID, or nil if not found

func (*Buffer) GetSpriteUnits

func (b *Buffer) GetSpriteUnits() (unitX, unitY int)

GetSpriteUnits returns the subdivisions per cell for sprite coordinates

func (*Buffer) GetSpritesForRendering

func (b *Buffer) GetSpritesForRendering() (behind, front []*Sprite)

GetSpritesForRendering returns sprites sorted by Z-index and ID for rendering Returns two slices: behind (negative Z) and front (non-negative Z)

func (*Buffer) GetTotalLineVisualWidth

func (b *Buffer) GetTotalLineVisualWidth(row int) float64

GetTotalLineVisualWidth returns the total visual width of a line.

func (*Buffer) GetVerticalScale

func (b *Buffer) GetVerticalScale() float64

GetVerticalScale returns the vertical scaling factor based on line density density 25 (default) = scale 1.0 density 30 = scale 25/30 = 0.8333 density 43 = scale 25/43 = 0.5814 density 50 = scale 25/50 = 0.5 density 60 = scale 25/60 = 0.4167

func (*Buffer) GetVisibleCell

func (b *Buffer) GetVisibleCell(x, y int) Cell

GetVisibleCell returns the cell accounting for scroll offset (both vertical and horizontal)

func (*Buffer) GetVisibleLineAttribute

func (b *Buffer) GetVisibleLineAttribute(y int) LineAttribute

GetVisibleLineAttribute returns the line attribute accounting for scroll offset

func (*Buffer) GetVisibleLineInfo

func (b *Buffer) GetVisibleLineInfo(y int) LineInfo

GetVisibleLineInfo returns the full LineInfo accounting for scroll offset

func (*Buffer) GetXFlip

func (b *Buffer) GetXFlip() bool

GetXFlip returns the current horizontal flip setting

func (*Buffer) GetYFlip

func (b *Buffer) GetYFlip() bool

GetYFlip returns the current vertical flip setting

func (*Buffer) HasCustomGlyph

func (b *Buffer) HasCustomGlyph(r rune) bool

HasCustomGlyph returns true if a custom glyph is defined for the rune

func (*Buffer) HasSelection

func (b *Buffer) HasSelection() bool

HasSelection returns true if there's an active selection

func (*Buffer) InitPalette

func (b *Buffer) InitPalette(n int, length int)

InitPalette creates or reinitializes a palette with the specified number of entries

func (*Buffer) InsertChars

func (b *Buffer) InsertChars(n int)

InsertChars inserts n blank characters at cursor

func (*Buffer) InsertLines

func (b *Buffer) InsertLines(n int)

InsertLines inserts n blank lines at cursor

func (*Buffer) IsAutoScrollDisabled

func (b *Buffer) IsAutoScrollDisabled() bool

IsAutoScrollDisabled returns true if auto-scroll is disabled.

func (*Buffer) IsAutoWrapModeEnabled

func (b *Buffer) IsAutoWrapModeEnabled() bool

IsAutoWrapModeEnabled returns true if auto-wrap is enabled (DECAWM).

func (*Buffer) IsBracketedPasteModeEnabled

func (b *Buffer) IsBracketedPasteModeEnabled() bool

IsBracketedPasteModeEnabled returns whether bracketed paste mode is enabled

func (*Buffer) IsCellInSelection

func (b *Buffer) IsCellInSelection(screenX, screenY int) bool

IsCellInSelection checks if a cell at screen coordinates is within the selection

func (*Buffer) IsCursorVisible

func (b *Buffer) IsCursorVisible() bool

IsCursorVisible returns cursor visibility

func (*Buffer) IsDarkTheme

func (b *Buffer) IsDarkTheme() bool

IsDarkTheme returns the current theme state (true=dark, false=light)

func (*Buffer) IsDirty

func (b *Buffer) IsDirty() bool

IsDirty returns true if the buffer has changed since last render

func (*Buffer) IsFlexWidthModeEnabled

func (b *Buffer) IsFlexWidthModeEnabled() bool

IsFlexWidthModeEnabled returns whether flexible East Asian Width mode is enabled

func (*Buffer) IsInSelection

func (b *Buffer) IsInSelection(x, y int) bool

IsInSelection returns true if the given screen position is within the selection Deprecated: Use IsCellInSelection for clearer semantics

func (*Buffer) IsScrollbackDisabled

func (b *Buffer) IsScrollbackDisabled() bool

IsScrollbackDisabled returns true if scrollback accumulation is disabled

func (*Buffer) IsSmartWordWrapEnabled

func (b *Buffer) IsSmartWordWrapEnabled() bool

IsSmartWordWrapEnabled returns true if smart word wrap is enabled.

func (*Buffer) IsViewingScrollbackInternal

func (b *Buffer) IsViewingScrollbackInternal() bool

IsViewingScrollbackInternal returns true if currently viewing scrollback buffer (internal, no lock).

func (*Buffer) IsVisualWidthWrapEnabled

func (b *Buffer) IsVisualWidthWrapEnabled() bool

IsVisualWidthWrapEnabled returns whether visual width-based wrapping is enabled

func (*Buffer) LineFeed

func (b *Buffer) LineFeed()

LineFeed moves cursor down one line

func (*Buffer) MoveCursorBackward

func (b *Buffer) MoveCursorBackward(n int)

MoveCursorBackward moves cursor left n columns (CSI D)

func (*Buffer) MoveCursorDown

func (b *Buffer) MoveCursorDown(n int)

MoveCursorDown moves cursor down n rows

func (*Buffer) MoveCursorForward

func (b *Buffer) MoveCursorForward(n int)

MoveCursorForward moves cursor right n columns (CSI C)

func (*Buffer) MoveCursorUp

func (b *Buffer) MoveCursorUp(n int)

MoveCursorUp moves cursor up n rows

func (*Buffer) MoveSprite

func (b *Buffer) MoveSprite(id int, x, y float64) bool

MoveSprite updates only the position of an existing sprite Returns false if sprite doesn't exist

func (*Buffer) MoveSpriteAndRunes

func (b *Buffer) MoveSpriteAndRunes(id int, x, y float64, runes []rune) bool

MoveSpriteAndRunes updates position and runes of an existing sprite Returns false if sprite doesn't exist

func (*Buffer) NeedsHorizScrollbar

func (b *Buffer) NeedsHorizScrollbar() bool

NeedsHorizScrollbar returns true if there's content beyond the visible width

func (*Buffer) Newline

func (b *Buffer) Newline()

Newline moves cursor to the beginning of the next line

func (*Buffer) NormalizeScrollOffset

func (b *Buffer) NormalizeScrollOffset() bool

NormalizeScrollOffset snaps the scroll offset back if it's in the magnetic zone. The magnetic zone is when the boundary would appear at rows 1-threshold (5% of scrollable content). This should be called when scrolling down to create a "sticky" effect at the boundary between logical screen and scrollback. Returns true if the offset was changed.

func (*Buffer) NotifyKeyboardActivity

func (b *Buffer) NotifyKeyboardActivity()

NotifyKeyboardActivity signals that keyboard input occurred. This starts/restarts the auto-scroll timer.

func (*Buffer) NotifyManualHorizScroll

func (b *Buffer) NotifyManualHorizScroll()

NotifyManualHorizScroll should be called when the user manually scrolls horizontally. This temporarily suppresses horizontal auto-scrolling.

func (*Buffer) NotifyManualVertScroll

func (b *Buffer) NotifyManualVertScroll()

NotifyManualVertScroll signals that the user manually scrolled vertically (via mouse wheel, scrollbar, etc). This cancels vertical auto-scroll to avoid fighting with user intent.

func (*Buffer) Reset

func (b *Buffer) Reset()

Reset resets the terminal to initial state Moves current screen content to scrollback, then resets all modes and cursor

func (*Buffer) ResetAttributes

func (b *Buffer) ResetAttributes()

ResetAttributes resets text attributes to defaults

func (*Buffer) ResetBGP

func (b *Buffer) ResetBGP()

ResetBGP resets the Base Glyph Palette to default (-1)

func (*Buffer) ResetUnderlineColor

func (b *Buffer) ResetUnderlineColor()

ResetUnderlineColor resets underline color to use foreground color

func (*Buffer) Resize

func (b *Buffer) Resize(cols, rows int)

Resize resizes the physical terminal dimensions This updates the visible area but does NOT truncate line content

func (*Buffer) ResolveGlyphColor

func (b *Buffer) ResolveGlyphColor(cell *Cell, paletteIdx int) (Color, bool)

ResolveGlyphColor resolves a palette index to an actual color for rendering cell is the cell being rendered, paletteIdx is the pixel's palette index Returns the color to use and whether the pixel should be rendered (false = transparent)

func (*Buffer) ResolveSpriteGlyphColor

func (b *Buffer) ResolveSpriteGlyphColor(fgp int, paletteIdx int, defaultFg, defaultBg Color) (Color, bool)

ResolveSpriteGlyphColor resolves a palette index to a color for sprite rendering Similar to ResolveGlyphColor but uses sprite's FGP and handles transparency differently Returns the color and whether the pixel should be rendered (false = transparent)

func (*Buffer) RestoreCursor

func (b *Buffer) RestoreCursor()

RestoreCursor restores the saved cursor position

func (*Buffer) SaveCursor

func (b *Buffer) SaveCursor()

SaveCursor saves the current cursor position

func (*Buffer) SaveScrollbackANS

func (b *Buffer) SaveScrollbackANS() string

SaveScrollbackANS returns the scrollback and screen with full ANSI/PawScript codes preserved. The output format: 1. TOP: Custom palette definitions (OSC 7000), custom glyph definitions (OSC 7001) 2. BODY: Content lines with DEC line attributes, SGR codes, BGP/flip attributes 3. END: Sprite units, screen splits, screen crop, crop rectangles, sprites, cursor position Callers may prepend a header comment using OSC 9999 before this output.

func (*Buffer) SaveScrollbackText

func (b *Buffer) SaveScrollbackText() string

SaveScrollbackText returns the scrollback and screen content as plain text

func (*Buffer) ScrollDown

func (b *Buffer) ScrollDown(n int)

ScrollDown scrolls down by n lines

func (*Buffer) ScrollUp

func (b *Buffer) ScrollUp(n int)

ScrollUp scrolls up by n lines

func (*Buffer) SelectAll

func (b *Buffer) SelectAll()

SelectAll selects all text in the terminal (including scrollback)

func (*Buffer) Set132ColumnMode

func (b *Buffer) Set132ColumnMode(enabled bool)

Set132ColumnMode enables or disables 132-column mode (horizontal scale 0.6060) This corresponds to DECCOLM (ESC [ ? 3 h / ESC [ ? 3 l)

func (*Buffer) Set40ColumnMode

func (b *Buffer) Set40ColumnMode(enabled bool)

Set40ColumnMode enables or disables 40-column mode (horizontal scale 2.0) This is a custom extension

func (*Buffer) SetAmbiguousWidthMode

func (b *Buffer) SetAmbiguousWidthMode(mode AmbiguousWidthMode)

SetAmbiguousWidthMode sets the handling for ambiguous East Asian Width characters Auto: match width of previous character (default) Narrow: always 1.0 width Wide: always 2.0 width

func (*Buffer) SetAttributes

func (b *Buffer) SetAttributes(fg, bg Color, bold, italic, underline, reverse bool)

SetAttributes sets current text rendering attributes

func (*Buffer) SetAutoScrollDisabled

func (b *Buffer) SetAutoScrollDisabled(disabled bool)

SetAutoScrollDisabled enables or disables cursor-following auto-scroll. When disabled, tracking still occurs but no automatic scrolling happens. This is controlled by a DEC Private Mode sequence.

func (*Buffer) SetAutoWrapMode

func (b *Buffer) SetAutoWrapMode(enabled bool)

SetAutoWrapMode enables or disables auto-wrap at end of line (DECAWM, mode 7). When disabled, the cursor stays at the last column and characters overwrite that position.

func (*Buffer) SetBGP

func (b *Buffer) SetBGP(n int)

SetBGP sets the Base Glyph Palette for subsequent characters -1 means use the foreground color code as the palette number

func (*Buffer) SetBackground

func (b *Buffer) SetBackground(c Color)

SetBackground sets the current background color

func (b *Buffer) SetBlink(blink bool)

SetBlink sets blink attribute

func (*Buffer) SetBold

func (b *Buffer) SetBold(bold bool)

SetBold sets bold attribute

func (*Buffer) SetBracketedPasteMode

func (b *Buffer) SetBracketedPasteMode(enabled bool)

SetBracketedPasteMode enables or disables bracketed paste mode

func (*Buffer) SetCropRect

func (b *Buffer) SetCropRect(id int, minX, minY, maxX, maxY float64)

SetCropRect creates or updates a crop rectangle

func (*Buffer) SetCursor

func (b *Buffer) SetCursor(x, y int)

SetCursor sets the cursor position (clamped to valid range)

func (*Buffer) SetCursorDrawn

func (b *Buffer) SetCursorDrawn(drawn bool)

SetCursorDrawn is called by the widget after rendering to indicate whether the cursor was actually drawn on screen.

func (*Buffer) SetCursorStyle

func (b *Buffer) SetCursorStyle(shape, blink int)

SetCursorStyle sets the cursor shape and blink mode

func (*Buffer) SetCursorVisible

func (b *Buffer) SetCursorVisible(visible bool)

SetCursorVisible sets cursor visibility

func (*Buffer) SetDarkTheme

func (b *Buffer) SetDarkTheme(dark bool)

SetDarkTheme sets the current theme (true=dark, false=light) This is called by DECSCNM (CSI ? 5 h/l) escape sequences

func (*Buffer) SetDirtyCallback

func (b *Buffer) SetDirtyCallback(fn func())

SetDirtyCallback sets a callback to be invoked when the buffer changes

func (*Buffer) SetFlexWidthMode

func (b *Buffer) SetFlexWidthMode(enabled bool)

SetFlexWidthMode enables or disables flexible East Asian Width mode When enabled, new characters get FlexWidth=true and their CellWidth calculated based on Unicode East_Asian_Width property (0.5/1.0/1.5/2.0 cell units)

func (*Buffer) SetForeground

func (b *Buffer) SetForeground(c Color)

SetForeground sets the current foreground color

func (*Buffer) SetGlyph

func (b *Buffer) SetGlyph(r rune, width int, pixels []int)

SetGlyph defines a custom glyph for a rune width is the pixel width, pixels are palette indices (row by row, left to right) height is automatically calculated from len(pixels)/width

func (*Buffer) SetHorizMemo

func (b *Buffer) SetHorizMemo(scanline int, memo HorizMemo)

SetHorizMemo sets the horizontal scroll memo for a specific scanline. Call this during paint for each row where the cursor's logical line is being rendered.

func (*Buffer) SetHorizOffset

func (b *Buffer) SetHorizOffset(offset int)

SetHorizOffset sets the horizontal scroll offset

func (*Buffer) SetItalic

func (b *Buffer) SetItalic(italic bool)

SetItalic sets italic attribute

func (*Buffer) SetLineAttribute

func (b *Buffer) SetLineAttribute(attr LineAttribute)

SetLineAttribute sets the display attribute for the current line

func (*Buffer) SetLineDensity

func (b *Buffer) SetLineDensity(density int)

SetLineDensity sets the line density (vertical scaling) Valid values: 25 (default), 30, 43, 50, 60 Higher density = more lines in same space = smaller vertical scale

func (*Buffer) SetLogicalSize

func (b *Buffer) SetLogicalSize(logicalRows, logicalCols int)

SetLogicalSize sets the logical terminal dimensions A value of 0 means "use physical dimension" This implements the ESC [ 8 ; rows ; cols t escape sequence

func (*Buffer) SetPaletteEntry

func (b *Buffer) SetPaletteEntry(paletteNum int, idx int, colorCode int, dim bool)

SetPaletteEntry sets a single entry in a palette colorCode uses SGR-style: 30-37/40-47 (normal), 90-97/100-107 (bright), 8 (transparent), 9 (default fg) If dim is true, the color is a dim variant

func (*Buffer) SetPaletteEntryColor

func (b *Buffer) SetPaletteEntryColor(paletteNum int, idx int, color Color, dim bool)

SetPaletteEntryColor sets a palette entry directly from a Color value Use this for 256-color and true color palette entries

func (*Buffer) SetPreferredDarkTheme

func (b *Buffer) SetPreferredDarkTheme(dark bool)

SetPreferredDarkTheme sets the user's preferred theme from config This is restored on terminal reset

func (*Buffer) SetReverse

func (b *Buffer) SetReverse(reverse bool)

SetReverse sets reverse video attribute

func (*Buffer) SetScaleChangeCallback

func (b *Buffer) SetScaleChangeCallback(fn func())

SetScaleChangeCallback sets a callback to be invoked when screen scaling modes change This allows the widget to recalculate terminal dimensions when scale changes

func (*Buffer) SetScreenCrop

func (b *Buffer) SetScreenCrop(widthCrop, heightCrop int)

SetScreenCrop sets the width and height crop in sprite coordinate units. -1 means no crop for that dimension.

func (*Buffer) SetScreenSplit

func (b *Buffer) SetScreenSplit(id int, screenY, bufferRow, bufferCol, topFineScroll, leftFineScroll int, charWidthScale float64, lineDensity int)

SetScreenSplit creates or updates a screen split. screenY: Y coordinate in sprite units where this split begins on screen bufferRow, bufferCol: 0-indexed logical screen coordinates to draw from topFineScroll, leftFineScroll: 0 to (subdivisions-1), higher = more clipped charWidthScale: character width multiplier (0 = inherit) lineDensity: line density override (0 = inherit)

func (*Buffer) SetScrollOffset

func (b *Buffer) SetScrollOffset(offset int)

SetScrollOffset sets how many lines we're scrolled back

func (*Buffer) SetScrollbackDisabled

func (b *Buffer) SetScrollbackDisabled(disabled bool)

SetScrollbackDisabled enables or disables scrollback accumulation. When disabled, lines scrolling off the top are discarded instead of saved. Existing scrollback is preserved but inaccessible until re-enabled.

func (*Buffer) SetSmartWordWrap

func (b *Buffer) SetSmartWordWrap(enabled bool)

SetSmartWordWrap enables or disables smart word wrap (mode 7702). When enabled, wrap occurs at word boundaries (space, hyphen, comma, semicolon, emdash) instead of mid-word.

func (*Buffer) SetSplitContentWidth

func (b *Buffer) SetSplitContentWidth(width int)

SetSplitContentWidth sets the max content width found across all split regions. This is called by the renderer after processing splits and is used for horizontal scrollbar calculation independent from scrollback content.

func (*Buffer) SetSprite

func (b *Buffer) SetSprite(id int, x, y float64, zIndex, fgp, flipCode int, xScale, yScale float64, cropRect int, runes []rune)

SetSprite creates or updates a sprite

func (*Buffer) SetSpriteUnits

func (b *Buffer) SetSpriteUnits(unitX, unitY int)

SetSpriteUnits sets how many subdivisions per cell for sprite coordinates

func (*Buffer) SetStrikethrough

func (b *Buffer) SetStrikethrough(strikethrough bool)

SetStrikethrough sets strikethrough attribute

func (*Buffer) SetThemeChangeCallback

func (b *Buffer) SetThemeChangeCallback(fn func(bool))

SetThemeChangeCallback sets a callback to be invoked when the terminal theme changes The callback receives true for dark theme, false for light theme

func (*Buffer) SetUnderline

func (b *Buffer) SetUnderline(underline bool)

SetUnderline sets underline attribute (single underline style)

func (*Buffer) SetUnderlineColor

func (b *Buffer) SetUnderlineColor(color Color)

SetUnderlineColor sets the underline color

func (*Buffer) SetUnderlineStyle

func (b *Buffer) SetUnderlineStyle(style UnderlineStyle)

SetUnderlineStyle sets the underline style (also sets Underline bool for compatibility)

func (*Buffer) SetVisualWidthWrap

func (b *Buffer) SetVisualWidthWrap(enabled bool)

SetVisualWidthWrap enables or disables visual width-based line wrapping When enabled, lines wrap based on accumulated visual width (sum of CellWidth) When disabled, lines wrap based on cell count

func (*Buffer) SetXFlip

func (b *Buffer) SetXFlip(on bool)

SetXFlip sets the horizontal flip attribute for subsequent characters

func (*Buffer) SetYFlip

func (b *Buffer) SetYFlip(on bool)

SetYFlip sets the vertical flip attribute for subsequent characters

func (*Buffer) StartSelection

func (b *Buffer) StartSelection(x, y int)

StartSelection begins a text selection (coordinates are screen-relative)

func (*Buffer) Tab

func (b *Buffer) Tab()

Tab moves cursor to the next tab stop

func (*Buffer) UpdatePreferredDarkTheme

func (b *Buffer) UpdatePreferredDarkTheme(dark bool)

UpdatePreferredDarkTheme updates the user's preferred theme from config without changing the current DECSCNM state. Use this when updating settings while preserving any \e[?5h/\e[?5l state the program has set.

func (*Buffer) UpdateSelection

func (b *Buffer) UpdateSelection(x, y int)

UpdateSelection updates the end point of the selection (coordinates are screen-relative)

func (*Buffer) UpdateSpriteRunes

func (b *Buffer) UpdateSpriteRunes(id int, runes []rune) bool

UpdateSpriteRunes updates only the runes of an existing sprite Returns false if sprite doesn't exist

func (*Buffer) WriteChar

func (b *Buffer) WriteChar(ch rune)

WriteChar writes a character at the current cursor position

type Cell

type Cell struct {
	Char              rune   // Base character
	Combining         string // Combining marks (vowel points, diacritics, etc.)
	Foreground        Color
	Background        Color
	Bold              bool
	Italic            bool
	Underline         bool           // Legacy: true if any underline style is active
	UnderlineStyle    UnderlineStyle // Underline style (None, Single, Double, Curly, Dotted, Dashed)
	UnderlineColor    Color          // Underline color (if set; use HasUnderlineColor to check)
	HasUnderlineColor bool           // True if UnderlineColor is explicitly set
	Reverse           bool
	Blink             bool    // When true, character animates (bobbing wave instead of traditional blink)
	Strikethrough     bool    // When true, draw a line through the character
	FlexWidth         bool    // When true, cell uses East Asian Width for variable width rendering
	CellWidth         float64 // Visual width in cell units (0.5, 1.0, 1.5, 2.0) - only used when FlexWidth is true
	BGP               int     // Base Glyph Palette index (-1 = use foreground color code as palette)
	XFlip             bool    // Horizontal flip for custom glyphs
	YFlip             bool    // Vertical flip for custom glyphs
}

Cell represents a single character cell in the terminal

func EmptyCell

func EmptyCell() Cell

EmptyCell returns an empty cell with default attributes

func EmptyCellWithAttrs

func EmptyCellWithAttrs(fg, bg Color, bold, italic, underline, reverse, blink bool) Cell

EmptyCellWithAttrs returns an empty cell with full attribute specification

func EmptyCellWithColors

func EmptyCellWithColors(fg, bg Color) Cell

EmptyCellWithColors returns an empty cell with specified colors

func (*Cell) String

func (c *Cell) String() string

String returns the full character including any combining marks

type Color

type Color struct {
	Type    ColorType // How the color was specified
	Index   uint8     // For Standard (0-15) or Palette (0-255)
	R, G, B uint8     // For TrueColor, or resolved RGB for display
}

Color represents a terminal color with its original specification preserved. This allows proper round-tripping for ANS files and dynamic palette swapping.

func Get256Color

func Get256Color(idx int) Color

Get256Color returns the color for a 256-color mode index (returns PaletteColor type)

func PaletteColor

func PaletteColor(index int) Color

PaletteColor creates a 256-color palette color (index 0-255)

func ParseHexColor

func ParseHexColor(s string) (Color, bool)

ParseHexColor parses a hex color string in "#RRGGBB" or "#RGB" format Returns a TrueColor type

func StandardColor

func StandardColor(index int) Color

StandardColor creates a standard 16-color ANSI color (index 0-15)

func TrueColor

func TrueColor(r, g, b uint8) Color

TrueColor creates a 24-bit true color

func (Color) IsDefault

func (c Color) IsDefault() bool

IsDefault returns true if this is the default fg/bg color

func (Color) ToANSIIndex

func (c Color) ToANSIIndex() int

ToANSIIndex returns the color index for standard/palette colors, or -1 for true color

func (Color) ToHex

func (c Color) ToHex() string

ToHex returns the color as a hex string like "#RRGGBB"

func (Color) ToSGRCode

func (c Color) ToSGRCode(isFg bool) string

ToSGRCode returns the SGR color code(s) for this color (foreground if isFg=true)

type ColorScheme

type ColorScheme struct {
	// Dark mode colors (DECSCNM off / \e[?5l)
	DarkForeground Color
	DarkBackground Color
	DarkPalette    []Color // 16 ANSI colors for dark mode

	// Light mode colors (DECSCNM on / \e[?5h)
	LightForeground Color
	LightBackground Color
	LightPalette    []Color // 16 ANSI colors for light mode

	// Shared settings
	Cursor    Color
	Selection Color
	BlinkMode BlinkMode
}

ColorScheme defines the colors used by the terminal for both dark and light modes. The terminal switches between modes via DECSCNM (\e[?5h / \e[?5l).

func DefaultColorScheme

func DefaultColorScheme() ColorScheme

DefaultColorScheme returns a color scheme with both dark and light mode colors

func (ColorScheme) Background

func (s ColorScheme) Background(isDark bool) Color

Background returns the background color for the specified mode

func (ColorScheme) Foreground

func (s ColorScheme) Foreground(isDark bool) Color

Foreground returns the foreground color for the specified mode

func (ColorScheme) Palette

func (s ColorScheme) Palette(isDark bool) []Color

Palette returns the 16-color palette for the specified mode

func (ColorScheme) ResolveColor

func (s ColorScheme) ResolveColor(c Color, isFg bool, isDark bool) Color

ResolveColor resolves a color using the appropriate palette based on mode. For ColorTypeStandard (0-15), looks up the color in the scheme's palette. For ColorTypeDefault, returns the scheme's foreground (if isFg) or background. For other types, returns the color unchanged.

type ColorType

type ColorType uint8

ColorType indicates how a color was specified

const (
	ColorTypeDefault   ColorType = iota // Use terminal default fg/bg (SGR 39/49)
	ColorTypeStandard                   // Standard 16 ANSI colors (0-15)
	ColorTypePalette                    // 256-color palette (0-255)
	ColorTypeTrueColor                  // 24-bit RGB
)

type CropRectangle

type CropRectangle struct {
	ID         int
	MinX, MinY float64
	MaxX, MaxY float64
}

CropRectangle defines a rectangular clipping area for sprites

func NewCropRectangle

func NewCropRectangle(id int, minX, minY, maxX, maxY float64) *CropRectangle

NewCropRectangle creates a new crop rectangle

func (*CropRectangle) Contains

func (cr *CropRectangle) Contains(x, y float64) bool

Contains returns true if the point is within the crop rectangle

type CustomGlyph

type CustomGlyph struct {
	Width  int   // Width in pixels
	Height int   // Height in pixels (derived from len(Pixels)/Width)
	Pixels []int // Palette indices, row by row, left to right, top to bottom
}

CustomGlyph represents a custom pixel-art glyph that replaces a Unicode character

func NewCustomGlyph

func NewCustomGlyph(width int, pixels []int) *CustomGlyph

NewCustomGlyph creates a new custom glyph from pixel data Width is the pixel width, pixels are palette indices Height is automatically calculated from len(pixels)/width

func (*CustomGlyph) ComputeHash

func (g *CustomGlyph) ComputeHash() uint64

ComputeHash returns a hash of the glyph data for cache key purposes. This hash changes whenever the glyph's pixel data would change.

func (*CustomGlyph) GetPixel

func (g *CustomGlyph) GetPixel(x, y int) int

GetPixel returns the palette index at the given x,y position Returns 0 if out of bounds

type EastAsianWidth

type EastAsianWidth int

EastAsianWidth represents the Unicode East Asian Width property

const (
	EAWidthNeutral   EastAsianWidth = iota // N - Neutral (most Western characters)
	EAWidthAmbiguous                       // A - Ambiguous (characters that can be narrow or wide)
	EAWidthHalfwidth                       // H - Halfwidth (halfwidth CJK punctuation, Katakana)
	EAWidthFullwidth                       // F - Fullwidth (fullwidth ASCII, punctuation)
	EAWidthNarrow                          // Na - Narrow (narrow but not neutral)
	EAWidthWide                            // W - Wide (CJK ideographs, etc.)
)

func GetEastAsianWidthCategory

func GetEastAsianWidthCategory(r rune) EastAsianWidth

GetEastAsianWidthCategory returns the category for a rune (exported for debugging)

type GlyphCacheKey

type GlyphCacheKey struct {
	Rune   rune
	Width  int16 // Target width in pixels
	Height int16 // Target height in pixels

	// Text glyph attributes
	Bold   bool
	Italic bool

	// Custom glyph attributes
	IsCustomGlyph bool
	XFlip         bool
	YFlip         bool
	PaletteHash   uint64 // Hash of palette content (0 = no palette/fallback mode)
	GlyphHash     uint64 // Hash of custom glyph pixel data (allows animated glyphs to cache all frames)

	// Resolved foreground color - needed when:
	// - Text glyph (always)
	// - Custom glyph with missing palette (fallback uses cell foreground)
	// - Custom glyph with palette containing PaletteEntryDefaultFG entries
	FgR, FgG, FgB uint8

	// Resolved background color - needed for custom glyphs with
	// transparent entries or single-entry palettes (index 0 = background)
	BgR, BgG, BgB uint8
}

GlyphCacheKey uniquely identifies a rendered glyph for caching. For text glyphs: uses Rune, Width, Height, Bold, Italic, FgR/G/B For custom glyphs: uses Rune, Width, Height, XFlip, YFlip, PaletteHash, GlyphHash,

and FgR/G/B/BgR/G/B (for fallback rendering or palettes with default FG entries)

type HorizMemo

type HorizMemo struct {
	Valid           bool // True if this scanline was processed during paint
	LogicalRow      int  // Which buffer row is being rendered at this scanline (for debugging)
	LeftmostCell    int  // Leftmost rendered cell column number
	RightmostCell   int  // Rightmost rendered cell column number
	DistanceToLeft  int  // Distance to scroll left to reach cursor (-1 if N/A)
	DistanceToRight int  // Distance to scroll right to reach cursor (-1 if N/A)
	CursorLocated   bool // True if cursor was found within rendered area
}

HorizMemo stores horizontal scroll memo data for a single scanline. This is populated during paint to track cursor position relative to rendered content.

type LineAttribute

type LineAttribute int

LineAttribute defines the display mode for a line (VT100 DECDHL/DECDWL)

const (
	LineAttrNormal       LineAttribute = iota // Normal single-width, single-height
	LineAttrDoubleWidth                       // DECDWL: Double-width line (ESC#6)
	LineAttrDoubleTop                         // DECDHL: Double-height top half (ESC#3)
	LineAttrDoubleBottom                      // DECDHL: Double-height bottom half (ESC#4)
)

type LineInfo

type LineInfo struct {
	Attribute   LineAttribute // DECDWL/DECDHL display mode
	DefaultCell Cell          // Used for rendering beyond stored line length
}

LineInfo contains per-line metadata including display attributes and default cell for rendering characters beyond the stored line length

func DefaultLineInfo

func DefaultLineInfo() LineInfo

DefaultLineInfo returns a LineInfo with normal attributes and default colors

func LineInfoWithCell

func LineInfoWithCell(cell Cell) LineInfo

LineInfoWithCell returns a LineInfo with normal attributes and the given default cell

type PTY

type PTY interface {
	// Start starts the PTY with the given command
	Start(cmd *exec.Cmd) error

	// Read reads from the PTY
	Read(p []byte) (n int, err error)

	// Write writes to the PTY
	Write(p []byte) (n int, err error)

	// Resize resizes the PTY
	Resize(cols, rows int) error

	// Close closes the PTY
	Close() error
}

PTY is the interface for platform-specific pseudo-terminal implementations

func NewPTY

func NewPTY() (PTY, error)

NewPTY creates a new PTY

type Palette

type Palette struct {
	Entries       []PaletteEntry
	UsesDefaultFG bool // True if any entry uses PaletteEntryDefaultFG (affects cache key)
	UsesBg        bool // True if any entry uses PaletteEntryTransparent (affects cache key)
}

Palette represents a custom color palette for glyph rendering

func NewPalette

func NewPalette(size int) *Palette

NewPalette creates a new palette with the specified number of entries

func (*Palette) ComputeHash

func (p *Palette) ComputeHash() uint64

ComputeHash returns a hash of the palette content for cache key purposes. This hash changes whenever the palette's visual output would change. Note: Does not include foreground color - caller must add that if UsesDefaultFG is true.

type PaletteEntry

type PaletteEntry struct {
	Type  PaletteEntryType // Type of entry
	Color Color            // Color value (only used when Type == PaletteEntryColor)
	Dim   bool             // Whether this is a dim variant
}

PaletteEntry represents a single entry in a custom palette

type PaletteEntryType

type PaletteEntryType int

PaletteEntryType defines the type of a palette entry

const (
	PaletteEntryColor       PaletteEntryType = iota // Normal color entry
	PaletteEntryTransparent                         // Use cell's background color (SGR code 8)
	PaletteEntryDefaultFG                           // Use cell's foreground color (SGR code 9)
)

type Parser

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

Parser parses ANSI escape sequences and updates a Buffer

func NewParser

func NewParser(buffer *Buffer) *Parser

NewParser creates a new ANSI parser for the given buffer

func (*Parser) Parse

func (p *Parser) Parse(data []byte)

Parse processes input data and updates the terminal buffer

func (*Parser) ParseString

func (p *Parser) ParseString(data string)

ParseString processes a string and updates the terminal buffer

type RGB

type RGB struct {
	R, G, B uint8
}

RGB holds just the red, green, blue components (used internally)

func Get256ColorRGB

func Get256ColorRGB(idx int) RGB

Get256ColorRGB returns the RGB values for a 256-color palette index

type SGRParam

type SGRParam struct {
	Base int   // Primary parameter value
	Subs []int // Subparameters (colon-separated values after the base)
}

SGRParam represents an SGR parameter with optional subparameters For example, "38:2:255:128:0" becomes {Base: 38, Subs: [2, 255, 128, 0]}

type ScreenInfo

type ScreenInfo struct {
	DefaultCell Cell // Used for rendering logical lines beyond stored lines
}

ScreenInfo contains buffer-wide metadata for rendering logical lines that have no stored data yet

func DefaultScreenInfo

func DefaultScreenInfo() ScreenInfo

DefaultScreenInfo returns a ScreenInfo with default colors

func ScreenInfoWithCell

func ScreenInfoWithCell(cell Cell) ScreenInfo

ScreenInfoWithCell returns a ScreenInfo with the given default cell

type ScreenSplit

type ScreenSplit struct {
	ScreenY        int     // Y in sprite units relative to logical screen start (NOT absolute screen)
	BufferRow      int     // 0-indexed row in logical screen to start drawing from
	BufferCol      int     // 0-indexed column in logical screen to start drawing from
	TopFineScroll  int     // 0 to (subdivisions-1), higher = more of top row clipped
	LeftFineScroll int     // 0 to (subdivisions-1), higher = more of left column clipped
	CharWidthScale float64 // Character width multiplier (0 = inherit from main screen)
	LineDensity    int     // Line density override (0 = inherit from main screen)
}

ScreenSplit defines a split region that can show a different part of the buffer. ScreenY is a LOGICAL scanline number relative to the scroll boundary (yellow dotted line). The first logical scanline (0) begins after the scrollback area - no splits can occur in the scrollback area above the yellow dotted line.

type Sprite

type Sprite struct {
	ID       int      // Unique identifier
	X, Y     float64  // Position in coordinate units
	ZIndex   int      // Z-order (negative = behind text layer)
	FGP      int      // Foreground Glyph Palette (-1 = use default based on rune)
	FlipCode int      // 0=none, 1=XFlip, 2=YFlip, 3=both
	XScale   float64  // Horizontal scale multiplier
	YScale   float64  // Vertical scale multiplier
	CropRect int      // Crop rectangle ID (-1 = no cropping)
	Runes    [][]rune // 2D array of characters (rows of runes, for multi-tile sprites)
}

Sprite represents an overlay sprite that can be positioned anywhere on screen

func NewSprite

func NewSprite(id int) *Sprite

NewSprite creates a new sprite with default values

func (*Sprite) GetXFlip

func (s *Sprite) GetXFlip() bool

GetXFlip returns true if sprite should be horizontally flipped

func (*Sprite) GetYFlip

func (s *Sprite) GetYFlip() bool

GetYFlip returns true if sprite should be vertically flipped

func (*Sprite) SetRunes

func (s *Sprite) SetRunes(runes []rune)

SetRunes parses rune data, splitting on newline (rune 10) for multi-row sprites

type TerminalCapabilities

type TerminalCapabilities struct {

	// Terminal type and detection
	TermType      string // e.g., "xterm-256color", "gui-console"
	IsTerminal    bool   // true if this is an interactive terminal
	IsRedirected  bool   // true if output is being redirected (piped/file)
	SupportsANSI  bool   // true if ANSI escape codes are supported
	SupportsColor bool   // true if color output is supported
	ColorDepth    int    // 0=none, 8=basic, 16=extended, 256=256color, 24=truecolor

	// Screen dimensions
	Width  int // columns
	Height int // rows

	// Input capabilities
	SupportsInput bool // true if this channel can receive input
	EchoEnabled   bool // true if input should be echoed (duplex mode)
	LineMode      bool // true if input is line-buffered, false for raw/char mode

	// Custom metadata (for host-provided channels)
	Metadata map[string]interface{}
	// contains filtered or unexported fields
}

TerminalCapabilities holds terminal capabilities that can be associated with a channel. This allows different channels (e.g., system stdout vs gui_console) to report their own capabilities independently.

func NewTerminalCapabilities

func NewTerminalCapabilities() *TerminalCapabilities

NewTerminalCapabilities creates a new capabilities struct with defaults

func (*TerminalCapabilities) GetSize

func (tc *TerminalCapabilities) GetSize() (width, height int)

GetSize returns the terminal dimensions

func (*TerminalCapabilities) SetSize

func (tc *TerminalCapabilities) SetSize(width, height int)

SetSize updates the terminal dimensions

type UnderlineStyle

type UnderlineStyle int

UnderlineStyle represents different underline rendering styles

const (
	UnderlineNone   UnderlineStyle = iota // No underline
	UnderlineSingle                       // Single straight underline (default)
	UnderlineDouble                       // Double underline
	UnderlineCurly                        // Curly/wavy underline
	UnderlineDotted                       // Dotted underline
	UnderlineDashed                       // Dashed underline
)

type UnixPTY

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

UnixPTY implements PTY for Unix systems (Linux, macOS, BSD)

func (*UnixPTY) Close

func (p *UnixPTY) Close() error

Close closes the PTY

func (*UnixPTY) Read

func (p *UnixPTY) Read(b []byte) (int, error)

Read reads from the PTY

func (*UnixPTY) Resize

func (p *UnixPTY) Resize(cols, rows int) error

Resize resizes the PTY

func (*UnixPTY) Start

func (p *UnixPTY) Start(cmd *exec.Cmd) error

Start starts the PTY with the given command

func (*UnixPTY) Write

func (p *UnixPTY) Write(b []byte) (int, error)

Write writes to the PTY

Directories

Path Synopsis
cli
Package cli provides a CLI-based terminal emulator adapter for PurfecTerm.
Package cli provides a CLI-based terminal emulator adapter for PurfecTerm.
example command
examples
buffer-only command
Example: Using the core terminal buffer without a GUI widget.
Example: Using the core terminal buffer without a GUI widget.
gtk-basic command
Example: Basic GTK3 terminal emulator.
Example: Basic GTK3 terminal emulator.
qt-basic command
Example: Basic Qt5 terminal emulator.
Example: Basic Qt5 terminal emulator.

Jump to

Keyboard shortcuts

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