tui

package
v0.4.7 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 41 Imported by: 0

Documentation

Overview

Package tui provides pi's differential terminal renderer and components.

Index

Constants

View Source
const CursorMarker = "\x1b_pi:c\x07"

CursorMarker is a zero-width APC sequence. Focused text components place it at their logical cursor so the renderer can position the hardware cursor for IME candidate windows without displaying it.

Variables

View Source
var TUIKeybindingDefinitions = []KeybindingDefinition{
	{ID: "tui.editor.cursorUp", DefaultKeys: []KeyID{"up"}, Description: "Move cursor up"},
	{ID: "tui.editor.cursorDown", DefaultKeys: []KeyID{"down"}, Description: "Move cursor down"},
	{ID: "tui.editor.cursorLeft", DefaultKeys: []KeyID{"left", "ctrl+b"}, Description: "Move cursor left"},
	{ID: "tui.editor.cursorRight", DefaultKeys: []KeyID{"right", "ctrl+f"}, Description: "Move cursor right"},
	{ID: "tui.editor.cursorWordLeft", DefaultKeys: []KeyID{"alt+left", "ctrl+left", "alt+b"}, Description: "Move cursor word left"},
	{ID: "tui.editor.cursorWordRight", DefaultKeys: []KeyID{"alt+right", "ctrl+right", "alt+f"}, Description: "Move cursor word right"},
	{ID: "tui.editor.cursorLineStart", DefaultKeys: []KeyID{"home", "ctrl+a"}, Description: "Move to line start"},
	{ID: "tui.editor.cursorLineEnd", DefaultKeys: []KeyID{"end", "ctrl+e"}, Description: "Move to line end"},
	{ID: "tui.editor.jumpForward", DefaultKeys: []KeyID{"ctrl+]"}, Description: "Jump forward to character"},
	{ID: "tui.editor.jumpBackward", DefaultKeys: []KeyID{"ctrl+alt+]"}, Description: "Jump backward to character"},
	{ID: "tui.editor.pageUp", DefaultKeys: []KeyID{"pageUp"}, Description: "Page up"},
	{ID: "tui.editor.pageDown", DefaultKeys: []KeyID{"pageDown"}, Description: "Page down"},
	{ID: "tui.editor.deleteCharBackward", DefaultKeys: []KeyID{"backspace"}, Description: "Delete character backward"},
	{ID: "tui.editor.deleteCharForward", DefaultKeys: []KeyID{"delete", "ctrl+d"}, Description: "Delete character forward"},
	{ID: "tui.editor.deleteWordBackward", DefaultKeys: []KeyID{"ctrl+w", "alt+backspace"}, Description: "Delete word backward"},
	{ID: "tui.editor.deleteWordForward", DefaultKeys: []KeyID{"alt+d", "alt+delete"}, Description: "Delete word forward"},
	{ID: "tui.editor.deleteToLineStart", DefaultKeys: []KeyID{"ctrl+u"}, Description: "Delete to line start"},
	{ID: "tui.editor.deleteToLineEnd", DefaultKeys: []KeyID{"ctrl+k"}, Description: "Delete to line end"},
	{ID: "tui.editor.yank", DefaultKeys: []KeyID{"ctrl+y"}, Description: "Yank"},
	{ID: "tui.editor.yankPop", DefaultKeys: []KeyID{"alt+y"}, Description: "Yank pop"},
	{ID: "tui.editor.undo", DefaultKeys: []KeyID{"ctrl+-"}, Description: "Undo"},
	{ID: "tui.input.newLine", DefaultKeys: []KeyID{"shift+enter", "ctrl+j"}, Description: "Insert newline"},
	{ID: "tui.input.submit", DefaultKeys: []KeyID{"enter"}, Description: "Submit input"},
	{ID: "tui.input.tab", DefaultKeys: []KeyID{"tab"}, Description: "Tab / autocomplete"},
	{ID: "tui.input.copy", DefaultKeys: []KeyID{"ctrl+c"}, Description: "Copy selection"},
	{ID: "tui.select.up", DefaultKeys: []KeyID{"up"}, Description: "Move selection up"},
	{ID: "tui.select.down", DefaultKeys: []KeyID{"down"}, Description: "Move selection down"},
	{ID: "tui.select.pageUp", DefaultKeys: []KeyID{"pageUp"}, Description: "Selection page up"},
	{ID: "tui.select.pageDown", DefaultKeys: []KeyID{"pageDown"}, Description: "Selection page down"},
	{ID: "tui.select.confirm", DefaultKeys: []KeyID{"enter"}, Description: "Confirm selection"},
	{ID: "tui.select.cancel", DefaultKeys: []KeyID{"escape", "ctrl+c"}, Description: "Cancel selection"},
}

Functions

func AllocateImageID

func AllocateImageID() uint32

func ApplyBackgroundToLine

func ApplyBackgroundToLine(line string, width int, background StyleFunc) string

ApplyBackgroundToLine pads a line before applying its background callback.

func CalculateImageRows

func CalculateImageRows(image ImageDimensions, targetWidthCells int, cell CellDimensions) int

func DecodeKittyPrintable

func DecodeKittyPrintable(data string) string

DecodeKittyPrintable decodes unmodified or Shift-only CSI-u input.

func DecodePrintableKey

func DecodePrintableKey(data string) string

func DeleteAllKittyImages

func DeleteAllKittyImages() string

func DeleteKittyImage

func DeleteKittyImage(imageID uint32) string

func EncodeITerm2

func EncodeITerm2(base64Data string, width, height any, name string, preserveAspectRatio, inline bool) string

func EncodeKitty

func EncodeKitty(base64Data string, columns, rows int, imageID uint32, moveCursor bool) string

func FindWordBackward

func FindWordBackward(text string, cursor int) int

FindWordBackward exposes upstream's UTF-16-indexed default word movement.

func FindWordForward

func FindWordForward(text string, cursor int) int

FindWordForward exposes upstream's UTF-16-indexed default word movement.

func FuzzyFilter

func FuzzyFilter[T any](items []T, query string, getText func(T) string) []T

FuzzyFilter filters and sorts items by fuzzy match quality (best first). Whitespace- and slash-separated query tokens must all match.

func Hyperlink(text, url string) string

Hyperlink wraps text in an OSC 8 hyperlink escape sequence. In terminals without hyperlink support the escape codes are ignored and only the plain text is displayed.

func ImageFallback

func ImageFallback(mimeType string, dimensions *ImageDimensions, filename string) string

func IsImageLine

func IsImageLine(line string) bool

func IsKeyRelease

func IsKeyRelease(data string) bool

func IsKeyRepeat

func IsKeyRepeat(data string) bool

func IsKittyProtocolActive

func IsKittyProtocolActive() bool

func IsMouseReport added in v0.4.6

func IsMouseReport(data string) bool

IsMouseReport matches every SGR mouse report, including the ones parseMouse rejects, so callers swallow them instead of leaking escape bytes as text.

func IsOsc11BackgroundColorResponse

func IsOsc11BackgroundColorResponse(data string) bool

IsOsc11BackgroundColorResponse recognizes the strict OSC 11 reply frame, including payloads that do not contain a parseable color.

func MatchesKey

func MatchesKey(data string, keyID KeyID) bool

MatchesKey checks one raw terminal sequence against a namespaced binding key.

func NormalizeAppleTerminalInput

func NormalizeAppleTerminalInput(data string, appleTerminal, shiftPressed bool) string

func NormalizeTerminalOutput

func NormalizeTerminalOutput(text string) string

NormalizeTerminalOutput applies upstream's display-only Thai/Lao AM decomposition and expands visible tabs without changing terminal strings.

func ParseKey

func ParseKey(data string) string

ParseKey returns the canonical identifier for a recognized terminal sequence.

func ResetCapabilitiesCache

func ResetCapabilitiesCache()

func SetCapabilities

func SetCapabilities(capabilities TerminalCapabilities)

func SetCellDimensions

func SetCellDimensions(dimensions CellDimensions)

func SetKeybindings

func SetKeybindings(manager *KeybindingsManager)

func SetKittyProtocolActive

func SetKittyProtocolActive(active bool)

func SliceByColumn

func SliceByColumn(line string, startCol, length int, strict bool) string

SliceByColumn extracts a range of visible columns from a line. ANSI codes pending at the slice start are re-emitted before the first kept grapheme; strict excludes boundary wide chars that would extend past the range.

func TruncateToWidth

func TruncateToWidth(text string, maxWidth int, ellipsis string, pad bool) string

TruncateToWidth keeps a contiguous grapheme prefix and brackets an ellipsis with resets so styles from truncated content cannot bleed into it.

func VisibleWidth

func VisibleWidth(text string) int

VisibleWidth returns the number of terminal cells occupied by text. Tabs are fixed at three cells and the ANSI, OSC, and APC sequences upstream recognizes are zero-width.

func WrapTextWithANSI

func WrapTextWithANSI(text string, width int) []string

WrapTextWithANSI word-wraps while reopening active SGR and OSC-8 state on physical lines, matching upstream's line-isolated renderer contract.

Types

type AutocompleteItem

type AutocompleteItem struct {
	Value       string
	Label       string
	Description string
}

type AutocompleteProvider

type AutocompleteProvider interface {
	GetSuggestions(ctx context.Context, lines []string, cursorLine, cursorCol int, force bool) *AutocompleteSuggestions
	ApplyCompletion(lines []string, cursorLine, cursorCol int, item AutocompleteItem, prefix string) CompletionResult
}

AutocompleteProvider supplies and applies completions. GetSuggestions runs off the input goroutine; ctx is cancelled when the request becomes stale. A nil result means no suggestions.

type AutocompleteSuggestions

type AutocompleteSuggestions struct {
	Items []AutocompleteItem
	// Prefix is what the suggestions were matched against (e.g. "/" or "src/").
	Prefix string
}

type Box

type Box struct {
	Children []Component
	// contains filtered or unexported fields
}

Box applies horizontal and vertical padding and an optional background to child components.

func NewBox

func NewBox(paddingX, paddingY int, background StyleFunc) *Box

func (*Box) AddChild

func (box *Box) AddChild(component Component)

func (*Box) Clear

func (box *Box) Clear()

func (*Box) Invalidate

func (box *Box) Invalidate()

func (*Box) RemoveChild

func (box *Box) RemoveChild(component Component)

func (*Box) Render

func (box *Box) Render(width int) []string

func (*Box) SetBackground

func (box *Box) SetBackground(background StyleFunc)

type CancellableLoader

type CancellableLoader struct {
	*Loader

	OnAbort func()
	// contains filtered or unexported fields
}

CancellableLoader couples Loader with the standard select-cancel binding.

func NewCancellableLoader

func NewCancellableLoader(ui RenderRequester, spinnerColor, messageColor StyleFunc, message string, indicator *LoaderIndicatorOptions) *CancellableLoader

func (*CancellableLoader) Aborted

func (loader *CancellableLoader) Aborted() bool

func (*CancellableLoader) Context

func (loader *CancellableLoader) Context() context.Context

func (*CancellableLoader) Dispose

func (loader *CancellableLoader) Dispose()

func (*CancellableLoader) HandleInput

func (loader *CancellableLoader) HandleInput(event KeyEvent)

type CellDimensions

type CellDimensions struct {
	WidthPx  int
	HeightPx int
}

func GetCellDimensions

func GetCellDimensions() CellDimensions

type CombinedAutocompleteProvider

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

CombinedAutocompleteProvider stacks slash-command, command-argument, "@" fuzzy-file, and path completion, mirroring upstream provider stacking.

func NewCombinedAutocompleteProvider

func NewCombinedAutocompleteProvider(commands []SlashCommand, basePath, fdPath string) *CombinedAutocompleteProvider

func (*CombinedAutocompleteProvider) ApplyCompletion

func (provider *CombinedAutocompleteProvider) ApplyCompletion(lines []string, cursorLine, cursorCol int, item AutocompleteItem, prefix string) CompletionResult

func (*CombinedAutocompleteProvider) GetSuggestions

func (provider *CombinedAutocompleteProvider) GetSuggestions(ctx context.Context, lines []string, cursorLine, cursorCol int, force bool) *AutocompleteSuggestions

func (*CombinedAutocompleteProvider) ShouldTriggerFileCompletion

func (provider *CombinedAutocompleteProvider) ShouldTriggerFileCompletion(lines []string, cursorLine, cursorCol int) bool

ShouldTriggerFileCompletion vetoes Tab file completion while typing a slash command name at line start.

type CompletionResult

type CompletionResult struct {
	Lines      []string
	CursorLine int
	CursorCol  int
}

CompletionResult is the new editor text and cursor after a completion.

type Component

type Component interface {
	Render(width int) []string
}

Component is the stable rendering contract shared with extension UIs.

type Container

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

Container renders child components vertically in insertion order.

func NewWindowedContainer added in v0.3.0

func NewWindowedContainer() *Container

NewWindowedContainer caches child layout so a viewport can render only its visible range. ChildChanged must be called after mutating an existing child.

func (*Container) AddChild

func (container *Container) AddChild(component Component)

func (*Container) ChildChanged added in v0.3.0

func (container *Container) ChildChanged(component Component)

ChildChanged invalidates the aggregate layout after an existing child mutates.

func (*Container) Children

func (container *Container) Children() []Component

func (*Container) Clear

func (container *Container) Clear()

func (*Container) EndsWith

func (container *Container) EndsWith(components ...Component) bool

EndsWith safely exposes the suffix check needed by upstream components, whose TypeScript container children are directly observable.

func (*Container) Invalidate

func (container *Container) Invalidate()

func (*Container) LineCount added in v0.3.0

func (container *Container) LineCount(width int) int

LineCount returns the rendered height without flattening cached child lines.

func (*Container) RemoveChild

func (container *Container) RemoveChild(component Component)

func (*Container) Render

func (container *Container) Render(width int) []string

func (*Container) RenderLines added in v0.3.0

func (container *Container) RenderLines(width, start, end int) []string

RenderLines renders the half-open line range [start, end).

type DefaultTextStyle

type DefaultTextStyle struct {
	Color         StyleFunc
	Background    StyleFunc
	Bold          bool
	Italic        bool
	Strikethrough bool
	Underline     bool
}

type Editor

type Editor struct {
	OnSubmit      func(string)
	OnChange      func(string)
	DisableSubmit bool

	// InputInterceptor is called before default key handling. Return true to
	// consume the event and suppress further processing.
	InputInterceptor func(KeyEvent) bool
	// contains filtered or unexported fields
}

Editor is the multi-line text editor: undo, kill ring, word navigation, paste collapse, prompt history, autocomplete.

func NewEditor

func NewEditor(ui *TUI, theme EditorTheme) *Editor

func (*Editor) AddToHistory

func (editor *Editor) AddToHistory(text string)

AddToHistory records a prompt for up/down navigation, skipping empties and consecutive duplicates, keeping at most 100 entries.

func (*Editor) GetAutocompleteMaxVisible

func (editor *Editor) GetAutocompleteMaxVisible() int

func (*Editor) GetBorderColor

func (editor *Editor) GetBorderColor() StyleFunc

func (*Editor) GetCursor

func (editor *Editor) GetCursor() (line, col int)

GetCursor returns the upstream-compatible UTF-16 column offset.

func (*Editor) GetExpandedText

func (editor *Editor) GetExpandedText() string

GetExpandedText returns the text with paste markers expanded to their actual content (e.g. for an external editor).

func (*Editor) GetLines

func (editor *Editor) GetLines() []string

func (*Editor) GetPaddingX

func (editor *Editor) GetPaddingX() int

func (*Editor) GetText

func (editor *Editor) GetText() string

func (*Editor) HandleInput

func (editor *Editor) HandleInput(event KeyEvent)

func (*Editor) HandleMouse added in v0.4.6

func (editor *Editor) HandleMouse(event MouseEvent) bool

HandleMouse places the cursor on a clicked character and accepts a clicked autocomplete suggestion. Border rows and the wheel fall through so the transcript keeps them.

func (*Editor) HasHiddenLinesAbove added in v0.4.7

func (editor *Editor) HasHiddenLinesAbove(width int) bool

HasHiddenLinesAbove predicts whether the next render needs the top scroll border.

func (*Editor) InsertTextAtCursor

func (editor *Editor) InsertTextAtCursor(text string)

InsertTextAtCursor inserts text at the cursor as one undoable unit.

func (*Editor) Invalidate

func (editor *Editor) Invalidate()

func (*Editor) IsShowingAutocomplete

func (editor *Editor) IsShowingAutocomplete() bool

func (*Editor) Render

func (editor *Editor) Render(width int) []string

func (*Editor) SetAutocompleteMaxVisible

func (editor *Editor) SetAutocompleteMaxVisible(maxVisible int)

func (*Editor) SetAutocompleteProvider

func (editor *Editor) SetAutocompleteProvider(provider AutocompleteProvider)

func (*Editor) SetBorderColor

func (editor *Editor) SetBorderColor(color StyleFunc)

func (*Editor) SetFocused

func (editor *Editor) SetFocused(focused bool)

func (*Editor) SetPaddingX

func (editor *Editor) SetPaddingX(padding int)

func (*Editor) SetText

func (editor *Editor) SetText(text string)

type EditorTheme

type EditorTheme struct {
	BorderColor StyleFunc
	SelectList  SelectListTheme
}

type FileCompletionGate

type FileCompletionGate interface {
	ShouldTriggerFileCompletion(lines []string, cursorLine, cursorCol int) bool
}

FileCompletionGate optionally vetoes explicit-Tab file completion.

type Focusable

type Focusable interface {
	Component
	InputHandler
	SetFocused(bool)
}

Focusable receives input and exposes focus state for cursor-marker emission.

type FuzzyMatch

type FuzzyMatch struct {
	Matches bool
	Score   float64
}

FuzzyMatch reports whether all query characters appear in order in text. Lower score = better match.

func FuzzyMatchScore

func FuzzyMatchScore(query, text string) FuzzyMatch

FuzzyMatchScore mirrors upstream fuzzyMatch, including the swapped alpha-numeric fallback (e.g. "o1" also tries "1o").

type Image

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

func NewImage

func NewImage(base64Data, mimeType string, theme ImageTheme, options *ImageOptions, dimensions *ImageDimensions) *Image

func (*Image) GetImageID

func (image *Image) GetImageID() *uint32

func (*Image) Invalidate

func (image *Image) Invalidate()

func (*Image) Render

func (image *Image) Render(width int) []string

type ImageCellSize

type ImageCellSize struct {
	Columns int
	Rows    int
}

func CalculateImageCellSize

func CalculateImageCellSize(image ImageDimensions, maxWidthCells int, maxHeightCells *int, cell CellDimensions) ImageCellSize

type ImageDimensions

type ImageDimensions struct {
	WidthPx  int
	HeightPx int
}

func GetGIFDimensions

func GetGIFDimensions(data string) *ImageDimensions

func GetImageDimensions

func GetImageDimensions(data, mimeType string) *ImageDimensions

func GetJPEGDimensions

func GetJPEGDimensions(data string) *ImageDimensions

func GetPNGDimensions

func GetPNGDimensions(data string) *ImageDimensions

func GetWebPDimensions

func GetWebPDimensions(data string) *ImageDimensions

type ImageOptions

type ImageOptions struct {
	MaxWidthCells  *int
	MaxHeightCells *int
	Filename       string
	ImageID        *uint32
}

type ImageProtocol

type ImageProtocol string
const (
	ImageProtocolKitty  ImageProtocol = "kitty"
	ImageProtocolITerm2 ImageProtocol = "iterm2"
)

type ImageRenderOptions

type ImageRenderOptions struct {
	MaxWidthCells       *int
	MaxHeightCells      *int
	PreserveAspectRatio *bool
	ImageID             *uint32
	MoveCursor          *bool
}

type ImageRenderResult

type ImageRenderResult struct {
	Sequence string
	Rows     int
	ImageID  *uint32
}

func RenderImage

func RenderImage(data string, dimensions ImageDimensions, options ImageRenderOptions) *ImageRenderResult

type ImageTheme

type ImageTheme struct {
	FallbackColor StyleFunc
}

type Input

type Input struct {
	OnSubmit func(string)
	OnEscape func()
	// contains filtered or unexported fields
}

Input is a single-line text input with horizontal scrolling. The cursor is a rune index into the value.

func NewInput

func NewInput() *Input

func (*Input) GetCursor

func (input *Input) GetCursor() int

GetCursor returns the upstream-compatible UTF-16 column offset.

func (*Input) GetValue

func (input *Input) GetValue() string

func (*Input) HandleInput

func (input *Input) HandleInput(event KeyEvent)

func (*Input) Invalidate

func (input *Input) Invalidate()

func (*Input) Render

func (input *Input) Render(width int) []string

func (*Input) SetFocused

func (input *Input) SetFocused(focused bool)

func (*Input) SetValue

func (input *Input) SetValue(value string)

type InputHandler

type InputHandler interface {
	HandleInput(KeyEvent)
}

InputHandler receives input while its component has focus.

type InputListener

type InputListener func(string) InputListenerResult

type InputListenerResult

type InputListenerResult struct {
	Consume bool
	Data    *string
}

type Invalidatable

type Invalidatable interface {
	Invalidate()
}

Invalidatable clears render state derived from theme or size changes.

type KeyEvent

type KeyEvent struct {
	Raw  string
	Key  string
	Type KeyEventType
}

KeyEvent is one terminal input sequence after protocol-aware parsing.

type KeyEventType

type KeyEventType string
const (
	KeyPress   KeyEventType = "press"
	KeyRepeat  KeyEventType = "repeat"
	KeyRelease KeyEventType = "release"
)

func KeyEventTypeOf

func KeyEventTypeOf(data string) KeyEventType

type KeyID

type KeyID string

type KeyReleaseConsumer

type KeyReleaseConsumer interface {
	WantsKeyRelease() bool
}

KeyReleaseConsumer opts into Kitty key-release events, which are otherwise filtered before dispatch just as upstream does.

type KeybindingConflict

type KeybindingConflict struct {
	Key         KeyID
	Keybindings []string
}

type KeybindingDefinition

type KeybindingDefinition struct {
	ID          string
	DefaultKeys []KeyID
	Description string
}

type KeybindingsConfig

type KeybindingsConfig map[string][]KeyID

func LoadKeybindingsFile

func LoadKeybindingsFile(path string) KeybindingsConfig

LoadKeybindingsFile mirrors upstream's forgiving keybindings.json parser: absent, malformed, and non-object files all resolve to an empty override.

type KeybindingsManager

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

func GetKeybindings

func GetKeybindings() *KeybindingsManager

func NewDefaultKeybindings

func NewDefaultKeybindings(user KeybindingsConfig) *KeybindingsManager

func NewKeybindingsFromFile

func NewKeybindingsFromFile(definitions []KeybindingDefinition, path string) *KeybindingsManager

func NewKeybindingsManager

func NewKeybindingsManager(definitions []KeybindingDefinition, user KeybindingsConfig) *KeybindingsManager

func (*KeybindingsManager) Conflicts

func (manager *KeybindingsManager) Conflicts() []KeybindingConflict

func (*KeybindingsManager) Definition

func (manager *KeybindingsManager) Definition(id string) (KeybindingDefinition, bool)

func (*KeybindingsManager) Keys

func (manager *KeybindingsManager) Keys(id string) []KeyID

func (*KeybindingsManager) Matches

func (manager *KeybindingsManager) Matches(data, id string) bool

func (*KeybindingsManager) Reload

func (manager *KeybindingsManager) Reload()

func (*KeybindingsManager) ResolvedBindings

func (manager *KeybindingsManager) ResolvedBindings() KeybindingsConfig

func (*KeybindingsManager) SetUserBindings

func (manager *KeybindingsManager) SetUserBindings(user KeybindingsConfig)

func (*KeybindingsManager) UserBindings

func (manager *KeybindingsManager) UserBindings() KeybindingsConfig

type KeyboardProtocolNegotiation

type KeyboardProtocolNegotiation struct {
	Type  string
	Flags int
}

func ParseKeyboardProtocolNegotiation

func ParseKeyboardProtocolNegotiation(sequence string) (KeyboardProtocolNegotiation, bool)

type LineSegments

type LineSegments struct {
	Before      string
	BeforeWidth int
	After       string
	AfterWidth  int
}

LineSegments is the before/after result used by overlay composition.

func ExtractSegments

func ExtractSegments(line string, beforeEnd, afterStart, afterLength int, strictAfter bool) LineSegments

ExtractSegments extracts styled visible columns on each side of an overlay.

type Loader

type Loader struct {
	*Text
	// contains filtered or unexported fields
}

Loader is an optional animated indicator followed by a message.

func NewLoader

func NewLoader(ui RenderRequester, spinnerColor, messageColor StyleFunc, message string, indicator *LoaderIndicatorOptions) *Loader

func (*Loader) Render

func (loader *Loader) Render(width int) []string

func (*Loader) SetIndicator

func (loader *Loader) SetIndicator(indicator *LoaderIndicatorOptions)

func (*Loader) SetMessage

func (loader *Loader) SetMessage(message string)

func (*Loader) Start

func (loader *Loader) Start()

func (*Loader) Stop

func (loader *Loader) Stop()

type LoaderIndicatorOptions

type LoaderIndicatorOptions struct {
	Frames   []string
	Interval time.Duration
}

type Markdown

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

func NewMarkdown

func NewMarkdown(text string, paddingX, paddingY int, theme MarkdownTheme, defaultStyle *DefaultTextStyle, options *MarkdownOptions) *Markdown

func (*Markdown) Invalidate

func (markdown *Markdown) Invalidate()

func (*Markdown) Render

func (markdown *Markdown) Render(width int) []string

func (*Markdown) SetText

func (markdown *Markdown) SetText(value string)

type MarkdownOptions

type MarkdownOptions struct {
	PreserveOrderedListMarkers bool
	PreserveBackslashEscapes   bool
	Hyperlinks                 bool
}

type MarkdownTheme

type MarkdownTheme struct {
	Heading         StyleFunc
	Link            StyleFunc
	LinkURL         StyleFunc
	Code            StyleFunc
	CodeBlock       StyleFunc
	CodeBlockBorder StyleFunc
	Quote           StyleFunc
	QuoteBorder     StyleFunc
	HorizontalRule  StyleFunc
	ListBullet      StyleFunc
	Bold            StyleFunc
	Italic          StyleFunc
	Strikethrough   StyleFunc
	Underline       StyleFunc
	HighlightCode   func(code, language string) []string
	CodeBlockIndent string
}

type MouseEvent added in v0.4.6

type MouseEvent struct {
	Type   MouseEventType
	Button int // 0 left, 1 middle, 2 right
	Row    int
	Column int
	Shift  bool
	Alt    bool
	Ctrl   bool
	// Clicks is 2 for a second press on the same cell within
	// doubleClickInterval. It is only set on MousePress.
	Clicks int
}

MouseEvent is one decoded SGR mouse report. Row and Column are zero-based and, once dispatched, local to the receiving component.

type MouseEventType added in v0.4.6

type MouseEventType uint8

MouseEventType is the gesture an SGR mouse report describes.

const (
	MousePress MouseEventType = iota
	MouseRelease
	MouseDrag
	MouseWheelUp
	MouseWheelDown
)

type MouseHandler added in v0.4.6

type MouseHandler interface {
	// HandleMouse reports whether the event was consumed.
	HandleMouse(MouseEvent) bool
}

MouseHandler is the optional capability a component advertises to receive mouse input. It is discovered by type assertion so the Component contract stays Render-only and every existing component and extension UI keeps working untouched.

type OverlayAnchor

type OverlayAnchor string

OverlayAnchor positions an overlay within the terminal's available area.

const (
	OverlayCenter       OverlayAnchor = "center"
	OverlayTopLeft      OverlayAnchor = "top-left"
	OverlayTopRight     OverlayAnchor = "top-right"
	OverlayBottomLeft   OverlayAnchor = "bottom-left"
	OverlayBottomRight  OverlayAnchor = "bottom-right"
	OverlayTopCenter    OverlayAnchor = "top-center"
	OverlayBottomCenter OverlayAnchor = "bottom-center"
	OverlayLeftCenter   OverlayAnchor = "left-center"
	OverlayRightCenter  OverlayAnchor = "right-center"
)

type OverlayHandle

type OverlayHandle interface {
	Hide()
	SetHidden(bool)
	IsHidden() bool
	Focus()
	Unfocus(...OverlayUnfocusOptions)
	IsFocused() bool
}

OverlayHandle controls one overlay after it has been shown.

type OverlayLayout

type OverlayLayout struct {
	Width, MinWidth, MaxHeight int
	Anchor                     string
	OffsetX, OffsetY           int
	Row, Column                *int
	Margin                     *OverlayMargin
	Visible                    func(width, height int) bool
	NonCapturing               bool
}

OverlayLayout preserves the existing Go extension adapter while the public TUI surface follows upstream's OverlayOptions. The callback is evaluated on every render so dynamic extension layouts remain responsive.

type OverlayMargin

type OverlayMargin struct {
	Top    int
	Right  int
	Bottom int
	Left   int
}

OverlayMargin reserves terminal cells around an overlay. Negative values are accepted here and clamped to zero during layout, as upstream does.

func UniformOverlayMargin

func UniformOverlayMargin(value int) *OverlayMargin

UniformOverlayMargin returns the number form of upstream's margin option.

type OverlayOptions

type OverlayOptions struct {
	Width        SizeValue
	MinWidth     int
	MaxHeight    SizeValue
	Anchor       OverlayAnchor
	OffsetX      int
	OffsetY      int
	Row          SizeValue
	Col          SizeValue
	Margin       *OverlayMargin
	Visible      func(termWidth, termHeight int) bool
	NonCapturing bool
}

OverlayOptions controls overlay sizing, placement, visibility, and focus capture.

type OverlayUnfocusOptions

type OverlayUnfocusOptions struct {
	Target Component
}

OverlayUnfocusOptions selects an explicit focus target, including nil.

type ProcessTerminal

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

ProcessTerminal owns raw-mode and protocol state for a pair of terminal files. NewProcessTerminal uses the process standard streams.

func NewProcessTerminal

func NewProcessTerminal() *ProcessTerminal

func NewProcessTerminalFiles

func NewProcessTerminalFiles(input, output *os.File) *ProcessTerminal

func (*ProcessTerminal) ClearFromCursor

func (terminal *ProcessTerminal) ClearFromCursor()

func (*ProcessTerminal) ClearLine

func (terminal *ProcessTerminal) ClearLine()

func (*ProcessTerminal) ClearScreen

func (terminal *ProcessTerminal) ClearScreen()

func (*ProcessTerminal) Columns

func (terminal *ProcessTerminal) Columns() int

func (*ProcessTerminal) DrainInput

func (terminal *ProcessTerminal) DrainInput(maxDuration, idleDuration time.Duration)

func (*ProcessTerminal) HideCursor

func (terminal *ProcessTerminal) HideCursor()

func (*ProcessTerminal) KittyProtocolActive

func (terminal *ProcessTerminal) KittyProtocolActive() bool

func (*ProcessTerminal) MoveBy

func (terminal *ProcessTerminal) MoveBy(lines int)

func (*ProcessTerminal) Rows

func (terminal *ProcessTerminal) Rows() int

func (*ProcessTerminal) Run

func (terminal *ProcessTerminal) Run(onInput func(string), onResize func(), body func()) (err error)

Run restores terminal state even when body panics, then propagates the panic.

func (*ProcessTerminal) SetProgress

func (terminal *ProcessTerminal) SetProgress(active bool)

func (*ProcessTerminal) SetTitle

func (terminal *ProcessTerminal) SetTitle(title string)

func (*ProcessTerminal) ShowCursor

func (terminal *ProcessTerminal) ShowCursor()

func (*ProcessTerminal) Start

func (terminal *ProcessTerminal) Start(onInput func(string), onResize func()) error

func (*ProcessTerminal) Stop

func (terminal *ProcessTerminal) Stop() error

func (*ProcessTerminal) Write

func (terminal *ProcessTerminal) Write(data string)

type RenderRequester

type RenderRequester interface {
	RequestRender()
}

RenderRequester is the narrow seam animated components need from TUI.

type RgbColor

type RgbColor struct {
	R int `json:"r"`
	G int `json:"g"`
	B int `json:"b"`
}

RgbColor is an 8-bit terminal color parsed from an OSC 11 response.

func ParseOsc11BackgroundColor

func ParseOsc11BackgroundColor(data string) (RgbColor, bool)

ParseOsc11BackgroundColor parses #RRGGBB, #RRRRGGGGBBBB, rgb:, and rgba: responses, scaling arbitrary hexadecimal channel widths to 8-bit values.

type SelectItem

type SelectItem struct {
	Value       string
	Label       string
	Description string
}

type SelectList

type SelectList struct {
	OnSelect          func(SelectItem)
	OnCancel          func()
	OnSelectionChange func(SelectItem)
	// contains filtered or unexported fields
}

SelectList renders a scrolling picker with optional description column.

func NewSelectList

func NewSelectList(items []SelectItem, maxVisible int, theme SelectListTheme, layout SelectListLayoutOptions) *SelectList

func (*SelectList) GetSelectedItem

func (list *SelectList) GetSelectedItem() (SelectItem, bool)

GetSelectedItem returns the highlighted item, or false when none.

func (*SelectList) HandleInput

func (list *SelectList) HandleInput(event KeyEvent)

func (*SelectList) HandleMouse added in v0.4.6

func (list *SelectList) HandleMouse(event MouseEvent) bool

HandleMouse selects the clicked row and confirms on a double click. The scroll-info line below the items is not clickable.

func (*SelectList) Invalidate

func (list *SelectList) Invalidate()

func (*SelectList) Render

func (list *SelectList) Render(width int) []string

func (*SelectList) SetFilter

func (list *SelectList) SetFilter(filter string)

SetFilter keeps items whose value starts with filter (case-insensitive) and resets the selection.

func (*SelectList) SetSelectedIndex

func (list *SelectList) SetSelectedIndex(index int)

type SelectListLayoutOptions

type SelectListLayoutOptions struct {
	MinPrimaryColumnWidth int
	MaxPrimaryColumnWidth int
	TruncatePrimary       func(SelectListTruncatePrimaryContext) string
}

SelectListLayoutOptions tunes the primary column; zero values mean unset.

type SelectListTheme

type SelectListTheme struct {
	SelectedPrefix StyleFunc
	SelectedText   StyleFunc
	Description    StyleFunc
	ScrollInfo     StyleFunc
	NoMatch        StyleFunc
}

type SelectListTruncatePrimaryContext

type SelectListTruncatePrimaryContext struct {
	Text        string
	MaxWidth    int
	ColumnWidth int
	Item        SelectItem
	IsSelected  bool
}

type SettingItem

type SettingItem struct {
	// ID uniquely identifies the setting.
	ID string
	// Label is the display text (left side).
	Label string
	// Description is shown when the item is selected.
	Description string
	// CurrentValue is displayed on the right side.
	CurrentValue string
	// Values, when set, are cycled through by Enter/Space.
	Values []string
	// Submenu, when set, is opened by Enter. It receives the current value
	// and a done callback; done(nil) cancels and done(&value) selects.
	Submenu func(currentValue string, done func(selected *string)) Component
}

type SettingsList

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

SettingsList renders label/value rows with cycling values, submenus, and optional fuzzy search.

func NewSettingsList

func NewSettingsList(items []SettingItem, maxVisible int, theme SettingsListTheme, onChange func(id, newValue string), onCancel func(), options SettingsListOptions) *SettingsList

func (*SettingsList) HandleInput

func (list *SettingsList) HandleInput(event KeyEvent)

func (*SettingsList) HandleMouse added in v0.4.6

func (list *SettingsList) HandleMouse(event MouseEvent) bool

HandleMouse selects the clicked setting and cycles its value on a double click, matching Enter/Space. An open submenu keeps the mouse, as it keeps keyboard input.

func (*SettingsList) Invalidate

func (list *SettingsList) Invalidate()

func (*SettingsList) Render

func (list *SettingsList) Render(width int) []string

func (*SettingsList) UpdateValue

func (list *SettingsList) UpdateValue(id, newValue string)

UpdateValue updates an item's current value.

type SettingsListOptions

type SettingsListOptions struct {
	EnableSearch bool
}

type SettingsListTheme

type SettingsListTheme struct {
	Label       SettingsStyleFunc
	Value       SettingsStyleFunc
	Description StyleFunc
	Cursor      string
	Hint        StyleFunc
}

type SettingsStyleFunc

type SettingsStyleFunc func(text string, selected bool) string

SettingsStyleFunc styles text differently for the selected row.

type SizeValue

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

SizeValue is either an absolute terminal-cell value or a percentage. The zero value means that the corresponding overlay option is unset.

func AbsoluteSize

func AbsoluteSize(value int) SizeValue

AbsoluteSize creates an absolute overlay size or position.

func PercentSize

func PercentSize(value float64) SizeValue

PercentSize creates a percentage overlay size or position, where 50 means 50%.

type SlashCommand

type SlashCommand struct {
	Name         string
	Description  string
	ArgumentHint string
	// GetArgumentCompletions returns completions for the command's argument
	// text, or nil when unavailable.
	GetArgumentCompletions func(argumentPrefix string) []AutocompleteItem
}

SlashCommand describes a command offered by slash completion.

type Spacer

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

Spacer renders a configurable number of empty rows.

func NewSpacer

func NewSpacer(lines int) *Spacer

func (*Spacer) Invalidate

func (spacer *Spacer) Invalidate()

func (*Spacer) Render

func (spacer *Spacer) Render(_ int) []string

func (*Spacer) SetLines

func (spacer *Spacer) SetLines(lines int)

type StdinBuffer

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

StdinBuffer turns arbitrarily chunked terminal bytes into individual escape sequences and bracketed-paste payloads.

func NewStdinBuffer

func NewStdinBuffer(timeout time.Duration, onData, onPaste func(string)) *StdinBuffer

func (*StdinBuffer) Buffered

func (buffer *StdinBuffer) Buffered() string

func (*StdinBuffer) Clear

func (buffer *StdinBuffer) Clear()

func (*StdinBuffer) Close

func (buffer *StdinBuffer) Close()

func (*StdinBuffer) Flush

func (buffer *StdinBuffer) Flush() []string

func (*StdinBuffer) Process

func (buffer *StdinBuffer) Process(data string)

func (*StdinBuffer) ProcessBytes

func (buffer *StdinBuffer) ProcessBytes(data []byte)

ProcessBytes preserves upstream's Buffer input compatibility: a single high byte is decoded as the legacy meta-key form ESC + (byte - 128).

type StyleFunc

type StyleFunc func(string) string

StyleFunc applies ANSI styling or a background to a complete string.

type TUI

type TUI struct {
	Container

	OnDebug func()
	// contains filtered or unexported fields
}

TUI owns focus and performs synchronized line-level differential rendering.

func NewTUI

func NewTUI(terminal Terminal) *TUI

func (*TUI) AddInputListener

func (ui *TUI) AddInputListener(listener InputListener) func()

func (*TUI) ClearOnShrink

func (ui *TUI) ClearOnShrink() bool

func (*TUI) ForceRender

func (ui *TUI) ForceRender()

func (*TUI) FullRedraws

func (ui *TUI) FullRedraws() int

func (*TUI) HasOverlay

func (ui *TUI) HasOverlay() bool

HasOverlay reports whether at least one overlay is currently visible.

func (*TUI) HideOverlay

func (ui *TUI) HideOverlay()

HideOverlay removes the most recently created overlay, independent of focus order.

func (*TUI) Invalidate

func (ui *TUI) Invalidate()

func (*TUI) OnTerminalColorSchemeChange

func (ui *TUI) OnTerminalColorSchemeChange(listener func(TerminalColorScheme)) func()

OnTerminalColorSchemeChange registers an insertion-ordered scheme listener.

func (*TUI) QueryTerminalBackgroundColor

func (ui *TUI) QueryTerminalBackgroundColor(timeout time.Duration) <-chan *RgbColor

QueryTerminalBackgroundColor sends OSC 11 and returns a one-result channel. A nil result means timeout or a strict reply with an unparseable payload.

func (*TUI) QueryTerminalColorScheme

func (ui *TUI) QueryTerminalColorScheme(timeout time.Duration) <-chan TerminalColorScheme

QueryTerminalColorScheme sends the DSR query and resolves from the same notification path used by persistent listeners. An empty result is timeout.

func (*TUI) RenderNow

func (ui *TUI) RenderNow()

func (*TUI) RequestRender

func (ui *TUI) RequestRender()

func (*TUI) SetClearOnShrink

func (ui *TUI) SetClearOnShrink(enabled bool)

func (*TUI) SetFocus

func (ui *TUI) SetFocus(component Component)

func (*TUI) SetSelectionHandler added in v0.3.3

func (ui *TUI) SetSelectionHandler(handler func(string))

func (*TUI) SetShowHardwareCursor

func (ui *TUI) SetShowHardwareCursor(enabled bool)

func (*TUI) SetTerminalColorSchemeNotifications

func (ui *TUI) SetTerminalColorSchemeNotifications(enabled bool)

SetTerminalColorSchemeNotifications enables or disables CSI ? 2031 reports.

func (*TUI) SetViewport added in v0.3.0

func (ui *TUI) SetViewport(body, chrome Component)

SetViewport keeps chrome pinned below a scrollable body. It is opt-in so embedders retain upstream's inline renderer unless they explicitly own the screen.

func (*TUI) ShowHardwareCursor

func (ui *TUI) ShowHardwareCursor() bool

func (*TUI) ShowOverlay

func (ui *TUI) ShowOverlay(component Component, options ...OverlayOptions) OverlayHandle

ShowOverlay adds an overlay and returns a permanent control handle. Omitting options applies upstream's centered, width-at-most-80 defaults.

func (*TUI) Start

func (ui *TUI) Start() error

func (*TUI) Stop

func (ui *TUI) Stop() error

func (*TUI) Terminal

func (ui *TUI) Terminal() Terminal

type Terminal

type Terminal interface {
	Start(onInput func(string), onResize func()) error
	Stop() error
	DrainInput(maxDuration, idleDuration time.Duration)
	Write(string)
	Columns() int
	Rows() int
	KittyProtocolActive() bool
	MoveBy(lines int)
	HideCursor()
	ShowCursor()
	ClearLine()
	ClearFromCursor()
	ClearScreen()
	SetTitle(string)
	SetProgress(bool)
}

Terminal is the renderer's minimal terminal contract.

type TerminalCapabilities

type TerminalCapabilities struct {
	Images     ImageProtocol
	TrueColor  bool
	Hyperlinks bool
}

func DetectCapabilities

func DetectCapabilities(tmuxForwardsHyperlink func() bool) TerminalCapabilities

func GetCapabilities

func GetCapabilities() TerminalCapabilities

type TerminalColorScheme

type TerminalColorScheme string

TerminalColorScheme is a terminal-reported dark or light preference.

const (
	TerminalColorSchemeDark  TerminalColorScheme = "dark"
	TerminalColorSchemeLight TerminalColorScheme = "light"
)

func ParseTerminalColorSchemeReport

func ParseTerminalColorSchemeReport(data string) (TerminalColorScheme, bool)

ParseTerminalColorSchemeReport parses CSI ? 997 ; 1/2 n reports.

type Text

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

Text renders wrapped multi-line text with optional padding and background.

func NewText

func NewText(text string, paddingX, paddingY int, background StyleFunc) *Text

func (*Text) Invalidate

func (text *Text) Invalidate()

func (*Text) Render

func (text *Text) Render(width int) []string

func (*Text) SetBackground

func (text *Text) SetBackground(background StyleFunc)

func (*Text) SetText

func (text *Text) SetText(value string)

type TextChunk

type TextChunk struct {
	Text       string
	StartIndex int
	EndIndex   int
}

TextChunk is one upstream-compatible UTF-16-indexed wrapped segment.

func WordWrapLine

func WordWrapLine(line string, maxWidth int) []TextChunk

WordWrapLine exposes upstream's default word-wrapping helper.

type TriggerCharacterProvider

type TriggerCharacterProvider interface {
	TriggerCharacters() []string
}

TriggerCharacterProvider optionally contributes extra characters that trigger completion at token boundaries (stacked onto the built-in "@"/"#").

type TruncatedText

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

TruncatedText renders only the first logical line, padded to the viewport.

func NewTruncatedText

func NewTruncatedText(text string, paddingX, paddingY int) *TruncatedText

func (*TruncatedText) Invalidate

func (text *TruncatedText) Invalidate()

func (*TruncatedText) Render

func (text *TruncatedText) Render(width int) []string

type VisualTruncateResult

type VisualTruncateResult struct {
	VisualLines  []string
	SkippedCount int
}

VisualTruncateResult contains the tail visual lines of wrapped text and the number of visual lines omitted before them.

func TruncateToVisualLines

func TruncateToVisualLines(text string, maxVisualLines, width, paddingX int) VisualTruncateResult

TruncateToVisualLines renders text with Text's width and padding semantics, then retains the last maxVisualLines physical terminal rows.

Jump to

Keyboard shortcuts

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