Documentation
¶
Overview ¶
Package tui provides the application, semantic view, layout, and runtime facade for Nagi TUI.
Index ¶
- Constants
- Variables
- func RunTerminal[Message any](app App[Message], options TerminalOptions, ...) error
- func RunTerminalContext[Message any](ctx context.Context, app App[Message], options TerminalOptions, ...) error
- type ANSITextOptions
- type App
- type Attributes
- type BorderKind
- type Clock
- type Color
- type ColorKind
- type DeliveryPolicy
- type DuplicateNodeIDError
- type DuplicateSubscriptionKeyError
- type Effect
- func AfterEffect[Message any](delay time.Duration, message Message) Effect[Message]
- func BatchEffects[Message any](effects ...Effect[Message]) Effect[Message]
- func CancelEffect[Message any](key TaskKey) Effect[Message]
- func CancelScopeEffect[Message any](scope ScopeID) Effect[Message]
- func ExitEffect[Message any]() Effect[Message]
- func FocusEffect[Message any](id NodeID) Effect[Message]
- func LatestEffect[Message any](key TaskKey, task Task[Message]) Effect[Message]
- func NoneEffect[Message any]() Effect[Message]
- func RunEffect[Message any](task Task[Message]) Effect[Message]
- func ScopedEffect[Message any](scope ScopeID, effect Effect[Message]) Effect[Message]
- func ScrollToEffect[Message any](id NodeID, offset ScrollOffset) Effect[Message]
- func SequenceEffects[Message any](effects ...Effect[Message]) Effect[Message]
- type EffectDiagnostics
- type EventAction
- type EventActionKind
- type EventDispatch
- type EventResult
- func (r EventResult[Message]) CapturePointer(id NodeID) EventResult[Message]
- func (r EventResult[Message]) Consume() EventResult[Message]
- func (r EventResult[Message]) Emit(message Message) EventResult[Message]
- func (r EventResult[Message]) Focus(id NodeID) EventResult[Message]
- func (r EventResult[Message]) Redraw() EventResult[Message]
- func (r EventResult[Message]) ReleaseFocus() EventResult[Message]
- func (r EventResult[Message]) ReleasePointer() EventResult[Message]
- type Frame
- type HorizontalAlignment
- type Insets
- type InteractionState
- func (s *InteractionState) Focused() (NodeID, bool)
- func (s *InteractionState) PointerCapture() (NodeID, bool)
- func (s *InteractionState) ScrollOffset(id NodeID) ScrollOffset
- func (s *InteractionState) ScrollState(id NodeID) (ScrollState, bool)
- func (s *InteractionState) TextInput(id NodeID) (TextInputState, bool)
- type Length
- type LengthKind
- type Node
- func ANSIText[Message any](input string, options ANSITextOptions) Node[Message]
- func Align[Message any](child Node[Message], horizontal HorizontalAlignment, ...) Node[Message]
- func Border[Message any](child Node[Message], style vt.Style) Node[Message]
- func Clip[Message any](child Node[Message]) Node[Message]
- func Column[Message any](children ...Node[Message]) Node[Message]
- func Gap[Message any](cells uint32) Node[Message]
- func Modal[Message any](id NodeID, child Node[Message]) Node[Message]
- func Padding[Message any](child Node[Message], insets Insets) Node[Message]
- func Panel[Message any](child Node[Message], title string) Node[Message]
- func PanelWithOptions[Message any](child Node[Message], title string, options PanelOptions) Node[Message]
- func Paragraph[Message any](spans []TextSpan, options ParagraphOptions) Node[Message]
- func RichText[Message any](spans ...TextSpan) Node[Message]
- func Row[Message any](children ...Node[Message]) Node[Message]
- func ScrollViewport[Message any](id NodeID, child Node[Message]) Node[Message]
- func ScrollViewportWithOptions[Message any](id NodeID, child Node[Message], options ScrollViewportOptions[Message]) Node[Message]
- func Spacer[Message any](width, height uint32) Node[Message]
- func Stack[Message any](children ...Node[Message]) Node[Message]
- func StyledText[Message any](content string, style vt.Style) Node[Message]
- func StyledTextInput[Message any](id NodeID, value, placeholder string, style, placeholderStyle vt.Style, ...) Node[Message]
- func SurfaceNode[Message any](source *surface.Surface) Node[Message]
- func Text[Message any](content string) Node[Message]
- func TextInput[Message any](id NodeID, value string, onChange func(string) Message) Node[Message]
- func VirtualScrollViewport[Message any](id NodeID, contentSize Size, ...) Node[Message]
- func VirtualScrollViewportWithOptions[Message any](id NodeID, contentSize Size, options ScrollViewportOptions[Message], ...) Node[Message]
- func (n Node[Message]) Focusable(id NodeID) Node[Message]
- func (n Node[Message]) OnEvent(id NodeID, handler func(vt.Event) EventResult[Message]) Node[Message]
- func (n Node[Message]) TabStop(enabled bool) Node[Message]
- func (n Node[Message]) WithFocusedStyle(style vt.Style) Node[Message]
- func (n Node[Message]) WithID(id NodeID) Node[Message]
- func (n Node[Message]) WithLength(length Length) Node[Message]
- type NodeID
- type OptionalColor
- type PanelOptions
- type PanelStyle
- type ParagraphOptions
- type Point
- type Rect
- type Runtime
- func (r *Runtime[Message]) ActiveSubscriptions() int
- func (r *Runtime[Message]) ActiveTasks() int
- func (r *Runtime[Message]) App() App[Message]
- func (r *Runtime[Message]) ClearFocus()
- func (r *Runtime[Message]) Close()
- func (r *Runtime[Message]) DispatchEvent(event vt.Event) (EventDispatch, error)
- func (r *Runtime[Message]) EffectDiagnostics() EffectDiagnostics
- func (r *Runtime[Message]) Enqueue(message Message) error
- func (r *Runtime[Message]) ExitRequested() bool
- func (r *Runtime[Message]) Interaction() *InteractionState
- func (r *Runtime[Message]) PendingEffectMessages() int
- func (r *Runtime[Message]) PendingSubscriptionMessages() int
- func (r *Runtime[Message]) PendingTasks() int
- func (r *Runtime[Message]) PollEffects() int
- func (r *Runtime[Message]) PollSubscriptions() int
- func (r *Runtime[Message]) ProcessPending() (int, error)
- func (r *Runtime[Message]) ProcessPendingWith(observe func(Message)) (int, error)
- func (r *Runtime[Message]) QueuedMessages() int
- func (r *Runtime[Message]) RenderIfDirty() (*Frame, error)
- func (r *Runtime[Message]) RequestFocus(id NodeID) (bool, error)
- func (r *Runtime[Message]) RequestFrame()
- func (r *Runtime[Message]) Resize(size Size)
- func (r *Runtime[Message]) RunningSubscriptionStreams() int
- func (r *Runtime[Message]) RunningTasks() int
- func (r *Runtime[Message]) SetScrollOffset(id NodeID, offset ScrollOffset) bool
- func (r *Runtime[Message]) SetTextCursor(id NodeID, cursor int) bool
- func (r *Runtime[Message]) Size() Size
- func (r *Runtime[Message]) Step() (*Frame, error)
- func (r *Runtime[Message]) SubscriptionActive(key SubscriptionKey) bool
- func (r *Runtime[Message]) SubscriptionDiagnostics() SubscriptionDiagnostics
- func (r *Runtime[Message]) SubscriptionGeneration(key SubscriptionKey) uint64
- func (r *Runtime[Message]) TaskGeneration(key TaskKey) uint64
- func (r *Runtime[Message]) TimeUntilEffectDeadline() (time.Duration, bool)
- func (r *Runtime[Message]) TimeUntilFrameDeadline() (time.Duration, bool)
- func (r *Runtime[Message]) TimeUntilSubscriptionDeadline() (time.Duration, bool)
- type RuntimeConfig
- type ScopeID
- type ScrollAxis
- type ScrollOffset
- type ScrollState
- type ScrollViewportOptions
- type Size
- type Style
- type Subscription
- func BatchSubscriptions[Message any](subscriptions ...Subscription[Message]) Subscription[Message]
- func EverySubscription[Message any](key SubscriptionKey, interval time.Duration, policy DeliveryPolicy, ...) Subscription[Message]
- func NoneSubscription[Message any]() Subscription[Message]
- func StreamSubscription[Message any](key SubscriptionKey, policy DeliveryPolicy, stream SubscriptionStream[Message]) Subscription[Message]
- type SubscriptionDiagnostics
- func (d SubscriptionDiagnostics) BatchFlushes() uint64
- func (d SubscriptionDiagnostics) BlockedSends() uint64
- func (d SubscriptionDiagnostics) DiscardedMessages() uint64
- func (d SubscriptionDiagnostics) LatestReplacements() uint64
- func (d SubscriptionDiagnostics) ProducerPanics() uint64
- func (d SubscriptionDiagnostics) Starts() uint64
- func (d SubscriptionDiagnostics) Stops() uint64
- type SubscriptionKey
- type SubscriptionSink
- type SubscriptionStream
- type SystemClock
- type Task
- type TaskKey
- type TerminalOptions
- type TextInputState
- type TextSpan
- type TimedInputDecoder
- type Timestamp
- type VerticalAlignment
- type ViewContext
- type VirtualClock
- type VirtualFragment
- type VirtualViewport
- type WrapMode
Constants ¶
const ( // ColorDefault is the terminal's default color ColorDefault = vt.ColorDefault // ColorIndexed is an indexed terminal palette entry ColorIndexed = vt.ColorIndexed // ColorRGB is a 24-bit RGB color ColorRGB = vt.ColorRGB )
const DefaultQueueCapacity = 4_096
DefaultQueueCapacity is the default maximum number of waiting messages
const DefaultSubscriptionCapacity = 256
DefaultSubscriptionCapacity is the default per-source subscription inbox capacity
const DefaultTaskLimit = 64
DefaultTaskLimit is the default maximum number of concurrent effect tasks
Variables ¶
var ( // ErrZeroQueueCapacity indicates that runtime queue capacity is zero ErrZeroQueueCapacity = errors.New("runtime queue capacity must be positive") // ErrQueueFull indicates that the bounded runtime message queue is full ErrQueueFull = errors.New("runtime message queue is full") // ErrZeroTaskLimit indicates that concurrent task limit is zero ErrZeroTaskLimit = errors.New("runtime task limit must be positive") // ErrZeroSubscriptionCapacity indicates that subscription capacity is zero ErrZeroSubscriptionCapacity = errors.New("runtime subscription capacity must be positive") // ErrNegativeFrameInterval indicates that a frame interval is negative ErrNegativeFrameInterval = errors.New("runtime minimum frame interval must not be negative") )
Functions ¶
func RunTerminal ¶
func RunTerminal[Message any]( app App[Message], options TerminalOptions, mapEvent func(vt.Event) EventAction[Message], ) error
RunTerminal runs an application in the process terminal until the application or mapEvent requests exit, or terminal input reaches EOF
The terminal session restores raw mode and screen state on normal, error, and panic exits.
func RunTerminalContext ¶
func RunTerminalContext[Message any]( ctx context.Context, app App[Message], options TerminalOptions, mapEvent func(vt.Event) EventAction[Message], ) error
RunTerminalContext runs an application until normal exit, terminal EOF, or context cancellation
Context cancellation returns ctx.Err(). The terminal session restores raw mode and screen state on every return path.
Types ¶
type ANSITextOptions ¶
type ANSITextOptions struct {
// Paragraph contains wrapping and alignment settings for parsed spans
Paragraph ParagraphOptions
}
ANSITextOptions controls paragraph behavior after safe ANSI SGR parsing
type App ¶
type App[Message any] interface { // Init initializes application state and returns startup work Init() Effect[Message] // Update applies one message and returns follow-up work Update(Message) Effect[Message] // Subscriptions describes long-lived message sources for the current state Subscriptions() Subscription[Message] // View rebuilds the semantic view for the current state View(ViewContext) Node[Message] }
App is one application whose state is updated by sequential messages
type Attributes ¶
type Attributes = vt.Attributes
Attributes is the VT-owned Boolean terminal attribute type
type BorderKind ¶
type BorderKind uint8
BorderKind selects a built-in one-cell panel border
const ( // BorderSingle uses square single-line box drawing characters BorderSingle BorderKind = iota // BorderRounded uses rounded single-line corners BorderRounded // BorderDouble uses double-line box drawing characters BorderDouble // BorderThick uses heavy box drawing characters BorderThick )
type Clock ¶
type Clock interface {
// Now returns the current monotonic timestamp
Now() Timestamp
}
Clock is a monotonic time source used by runtime scheduling
type Color ¶
Color is the VT-owned terminal color type
func IndexedColor ¶
IndexedColor returns an indexed terminal palette color
type DeliveryPolicy ¶
type DeliveryPolicy struct {
// contains filtered or unexported fields
}
DeliveryPolicy defines bounded delivery behavior for one subscription
func BatchDelivery ¶
func BatchDelivery(maximumMessages int, maximumDelay time.Duration) DeliveryPolicy
BatchDelivery releases FIFO values after maximumMessages or maximumDelay
It panics when maximumMessages is not positive or maximumDelay is negative.
func LatestDelivery ¶
func LatestDelivery() DeliveryPolicy
LatestDelivery retains only the newest value not yet delivered to Update
func ReliableDelivery ¶
func ReliableDelivery() DeliveryPolicy
ReliableDelivery preserves every value in FIFO order and blocks a full Stream inbox
func (DeliveryPolicy) BatchLimits ¶
func (p DeliveryPolicy) BatchLimits() (int, time.Duration, bool)
BatchLimits returns the count and delay for Batch delivery
func (DeliveryPolicy) IsLatest ¶
func (p DeliveryPolicy) IsLatest() bool
IsLatest reports whether only the newest pending value is retained
func (DeliveryPolicy) IsReliable ¶
func (p DeliveryPolicy) IsReliable() bool
IsReliable reports whether every value is delivered reliably
type DuplicateNodeIDError ¶
type DuplicateNodeIDError struct {
// ID is the duplicated application-defined identity
ID NodeID
}
DuplicateNodeIDError indicates that one semantic tree reused a stable ID
func (*DuplicateNodeIDError) Error ¶
func (e *DuplicateNodeIDError) Error() string
Error returns the duplicate identity diagnostic
type DuplicateSubscriptionKeyError ¶
type DuplicateSubscriptionKeyError struct {
// Key is the duplicated application-defined identity
Key SubscriptionKey
}
DuplicateSubscriptionKeyError indicates that one declaration reused a key
func (*DuplicateSubscriptionKeyError) Error ¶
func (e *DuplicateSubscriptionKeyError) Error() string
Error returns the duplicate identity diagnostic
type Effect ¶
type Effect[Message any] struct { // contains filtered or unexported fields }
Effect is declarative follow-up work produced by App.Init or App.Update
func AfterEffect ¶
AfterEffect emits message after delay according to the runtime clock
A negative delay is treated as zero.
func BatchEffects ¶
BatchEffects starts child effects independently and completes when all finish
func CancelEffect ¶
CancelEffect cancels the current latest task for key
func CancelScopeEffect ¶
CancelScopeEffect cancels current tasks and timers in scope
func ExitEffect ¶
ExitEffect requests normal application exit after the final dirty frame is rendered
func FocusEffect ¶
FocusEffect requests focus for a focusable node in the next application view
func LatestEffect ¶
LatestEffect replaces the current task for key and suppresses stale results
It panics when task is nil.
func NoneEffect ¶
NoneEffect returns an effect that performs no work
func ScopedEffect ¶
ScopedEffect associates every task and timer in effect with a scope
func ScrollToEffect ¶
func ScrollToEffect[Message any](id NodeID, offset ScrollOffset) Effect[Message]
ScrollToEffect requests a ScrollViewport offset in the next application view
func SequenceEffects ¶
SequenceEffects runs child effects in order
func (Effect[Message]) WithoutRedraw ¶ added in v0.1.4
WithoutRedraw declares that the Update returning this effect did not change state observed by View
Follow-up work is still scheduled and Subscriptions are still reconciled. Synchronous UI commands and an already-dirty runtime still produce a frame.
type EffectDiagnostics ¶
type EffectDiagnostics struct {
// contains filtered or unexported fields
}
EffectDiagnostics contains counters for supervised task behavior
func (EffectDiagnostics) Cancellations ¶
func (d EffectDiagnostics) Cancellations() uint64
Cancellations returns the number of cooperative cancellation requests
func (EffectDiagnostics) StaleResults ¶
func (d EffectDiagnostics) StaleResults() uint64
StaleResults returns the number of completed task results suppressed as stale
func (EffectDiagnostics) TaskPanics ¶
func (d EffectDiagnostics) TaskPanics() uint64
TaskPanics returns the number of panics caught at the task boundary
type EventAction ¶
type EventAction[Message any] struct { // contains filtered or unexported fields }
EventAction is the application-level decision for one normalized event
func ExitAction ¶
func ExitAction[Message any]() EventAction[Message]
ExitAction returns an action that finishes the event loop normally
func IgnoreAction ¶
func IgnoreAction[Message any]() EventAction[Message]
IgnoreAction returns an action that consumes an event without state changes
func MessageAction ¶
func MessageAction[Message any](message Message) EventAction[Message]
MessageAction returns an action that adds message to the application queue
func (EventAction[Message]) Kind ¶
func (a EventAction[Message]) Kind() EventActionKind
Kind returns the event decision variant
func (EventAction[Message]) Message ¶
func (a EventAction[Message]) Message() (Message, bool)
Message returns the queued message for EventMessage
type EventActionKind ¶
type EventActionKind uint8
EventActionKind identifies an application-level terminal event decision
const ( // EventIgnore consumes an event without changing application state EventIgnore EventActionKind = iota // EventMessage adds a message to the application queue EventMessage // EventExit finishes the event loop normally EventExit )
type EventDispatch ¶
type EventDispatch struct {
// contains filtered or unexported fields
}
EventDispatch is the observable outcome of routing one normalized event
func (EventDispatch) Consumed ¶
func (d EventDispatch) Consumed() bool
Consumed reports whether a handler consumed the event
func (EventDispatch) Messages ¶
func (d EventDispatch) Messages() int
Messages returns the number of application messages enqueued by handlers
func (EventDispatch) RedrawRequested ¶
func (d EventDispatch) RedrawRequested() bool
RedrawRequested reports whether routing explicitly requested a frame
type EventResult ¶
type EventResult[Message any] struct { // contains filtered or unexported fields }
EventResult is the composable result of one semantic node event handler
func ConsumeResult ¶
func ConsumeResult[Message any]() EventResult[Message]
ConsumeResult returns a consumed result without a message
func IgnoreResult ¶
func IgnoreResult[Message any]() EventResult[Message]
IgnoreResult returns an ignored result that continues ancestor routing
func MessageResult ¶
func MessageResult[Message any](message Message) EventResult[Message]
MessageResult returns a consumed result that emits one application message
func (EventResult[Message]) CapturePointer ¶
func (r EventResult[Message]) CapturePointer(id NodeID) EventResult[Message]
CapturePointer captures pointer routing for a stable Node ID
func (EventResult[Message]) Consume ¶
func (r EventResult[Message]) Consume() EventResult[Message]
Consume stops ancestor routing after applying the result
func (EventResult[Message]) Emit ¶
func (r EventResult[Message]) Emit(message Message) EventResult[Message]
Emit adds an application message to the result
func (EventResult[Message]) Focus ¶
func (r EventResult[Message]) Focus(id NodeID) EventResult[Message]
Focus requests focus for a stable Node ID
func (EventResult[Message]) Redraw ¶
func (r EventResult[Message]) Redraw() EventResult[Message]
Redraw requests a frame even without an application message
func (EventResult[Message]) ReleaseFocus ¶
func (r EventResult[Message]) ReleaseFocus() EventResult[Message]
ReleaseFocus releases node focus
func (EventResult[Message]) ReleasePointer ¶
func (r EventResult[Message]) ReleasePointer() EventResult[Message]
ReleasePointer releases pointer capture
type Frame ¶
type Frame struct {
// contains filtered or unexported fields
}
Frame is one coalesced rendered frame
func (Frame) Operations ¶
func (f Frame) Operations() []vt.TerminalOp
Operations returns a copy of typed VT operations relative to the previous frame
type HorizontalAlignment ¶
type HorizontalAlignment uint8
HorizontalAlignment controls horizontal placement inside an alignment node
const ( // AlignStart places content at the left edge AlignStart HorizontalAlignment = iota // AlignCenter centers content horizontally AlignCenter // AlignEnd places content at the right edge AlignEnd )
type Insets ¶
type Insets struct {
// Top is the number of cells above the child
Top uint32
// Right is the number of cells to the child's right
Right uint32
// Bottom is the number of cells below the child
Bottom uint32
// Left is the number of cells to the child's left
Left uint32
}
Insets contains padding widths around a node
func UniformInsets ¶
UniformInsets returns equal insets on every side
type InteractionState ¶
type InteractionState struct {
// contains filtered or unexported fields
}
InteractionState is runtime-owned UI continuity keyed by stable Node IDs
func NewInteractionState ¶
func NewInteractionState() *InteractionState
NewInteractionState returns empty Interaction State
func (*InteractionState) Focused ¶
func (s *InteractionState) Focused() (NodeID, bool)
Focused returns the focused Node ID
func (*InteractionState) PointerCapture ¶
func (s *InteractionState) PointerCapture() (NodeID, bool)
PointerCapture returns the node holding pointer capture
func (*InteractionState) ScrollOffset ¶
func (s *InteractionState) ScrollOffset(id NodeID) ScrollOffset
ScrollOffset returns a retained scroll offset, defaulting to zero
func (*InteractionState) ScrollState ¶
func (s *InteractionState) ScrollState(id NodeID) (ScrollState, bool)
ScrollState returns resolved ScrollViewport state for a node
func (*InteractionState) TextInput ¶
func (s *InteractionState) TextInput(id NodeID) (TextInputState, bool)
TextInput returns retained TextInput state for a node
type Length ¶
type Length struct {
// contains filtered or unexported fields
}
Length is a main-axis sizing rule for a child node
Its zero value is Auto.
type LengthKind ¶
type LengthKind uint8
LengthKind identifies a main-axis sizing rule
const ( // LengthAuto uses the child's measured size LengthAuto LengthKind = iota // LengthFixed requests an exact cell count LengthFixed // LengthFlex shares cells left after non-flexible requests LengthFlex // LengthPercent requests a percentage of the parent LengthPercent // LengthMinMax requests a preferred size constrained by minimum and maximum LengthMinMax )
type Node ¶
type Node[Message any] struct { // contains filtered or unexported fields }
Node is a semantic view node rebuilt by an application for each frame
func ANSIText ¶
func ANSIText[Message any](input string, options ANSITextOptions) Node[Message]
ANSIText parses SGR styling and discards every non-display control sequence
CSI commands other than SGR, OSC, DCS, SOS, PM, APC, raw escape sequences, and non-line-breaking control characters never reach terminal output.
func Align ¶
func Align[Message any](child Node[Message], horizontal HorizontalAlignment, vertical VerticalAlignment) Node[Message]
Align places a child within the rectangle assigned to the node
func Column ¶
Column returns a vertical container
The returned node retains the supplied variadic slice. Callers must not mutate that slice after construction.
func Gap ¶
Gap returns spacing interpreted along the main axis of its immediate Row or Column
Outside a Row or Column, a Gap has zero measured size.
func PanelWithOptions ¶
func PanelWithOptions[Message any](child Node[Message], title string, options PanelOptions) Node[Message]
PanelWithOptions returns a titled container with configured border, padding, and styles
func Paragraph ¶
func Paragraph[Message any](spans []TextSpan, options ParagraphOptions) Node[Message]
Paragraph returns inline styled text using the supplied wrapping and alignment
func Row ¶
Row returns a horizontal container
The returned node retains the supplied variadic slice. Callers must not mutate that slice after construction.
func ScrollViewport ¶
ScrollViewport returns a clipped viewport with runtime-owned cell offset
The supplied child tree is eager. Use VirtualScrollViewport when content construction must be bounded by the visible region.
func ScrollViewportWithOptions ¶
func ScrollViewportWithOptions[Message any]( id NodeID, child Node[Message], options ScrollViewportOptions[Message], ) Node[Message]
ScrollViewportWithOptions returns a clipped viewport with configured behavior
The supplied child tree is eager. Use VirtualScrollViewportWithOptions when content construction must be bounded by the visible region.
func Stack ¶
Stack returns a front-to-back overlay container
The returned node retains the supplied variadic slice. Callers must not mutate that slice after construction.
func StyledText ¶
StyledText returns a styled text node
func StyledTextInput ¶
func StyledTextInput[Message any]( id NodeID, value, placeholder string, style, placeholderStyle vt.Style, onChange func(string) Message, ) Node[Message]
StyledTextInput returns a styled one-line input with placeholder text
func SurfaceNode ¶
SurfaceNode captures an independent snapshot of a public Surface as a node
A nil source produces an empty node. Surface cells remain typed and cannot introduce raw terminal escape sequences.
func VirtualScrollViewport ¶ added in v0.1.1
func VirtualScrollViewport[Message any]( id NodeID, contentSize Size, builder func(VirtualViewport) VirtualFragment[Message], ) Node[Message]
VirtualScrollViewport returns a viewport that constructs only a visible content fragment
contentSize declares the complete scrollable cell extent without constructing it. The builder is cached for one resolved visible range during the semantic frame and may return bounded overscan before that range. A nil builder produces empty fragments.
func VirtualScrollViewportWithOptions ¶ added in v0.1.1
func VirtualScrollViewportWithOptions[Message any]( id NodeID, contentSize Size, options ScrollViewportOptions[Message], builder func(VirtualViewport) VirtualFragment[Message], ) Node[Message]
VirtualScrollViewportWithOptions returns a virtual viewport with configured scrolling behavior
Only the cached fragment participates in measurement, rendering, focus, hit testing, and event routing. Fragment Node IDs therefore represent visible or overscanned content and must remain stable across requests.
func (Node[Message]) OnEvent ¶
func (n Node[Message]) OnEvent(id NodeID, handler func(vt.Event) EventResult[Message]) Node[Message]
OnEvent attaches an event handler under a stable identity
func (Node[Message]) TabStop ¶
TabStop controls Tab traversal participation without changing the stable ID
func (Node[Message]) WithFocusedStyle ¶
WithFocusedStyle merges style over this node's clipped rectangle while it owns focus. It does not change measurement, layout, hit testing, or routing. The node must also have a stable identity, normally through Focusable or OnEvent.
func (Node[Message]) WithID ¶
WithID attaches a stable semantic identity without changing focus behavior
func (Node[Message]) WithLength ¶
WithLength sets the node's main-axis sizing rule in a row or column
type NodeID ¶
type NodeID string
NodeID is an application-defined stable identity for an interactive or stateful node
type OptionalColor ¶
type OptionalColor = vt.OptionalColor
OptionalColor is the VT-owned optional terminal color type
func SomeColor ¶
func SomeColor(color Color) OptionalColor
SomeColor returns an optional color containing color
type PanelOptions ¶
type PanelOptions struct {
// Border selects the border character set
Border BorderKind
// Padding is applied inside the one-cell border
Padding Insets
// Style controls panel colors and attributes
Style PanelStyle
}
PanelOptions controls panel border, padding, and styles
func DefaultPanelOptions ¶
func DefaultPanelOptions() PanelOptions
DefaultPanelOptions returns a single border with one-cell inner padding
type PanelStyle ¶
type PanelStyle struct {
// Border styles the border cells
Border vt.Style
// Title styles the optional title
Title vt.Style
// Background fills the complete panel rectangle before child rendering
Background vt.Style
}
PanelStyle contains the visual styles used by a Panel node
type ParagraphOptions ¶
type ParagraphOptions struct {
// Wrap controls automatic line boundaries
Wrap WrapMode
// Alignment places each rendered line within the paragraph rectangle
Alignment HorizontalAlignment
}
ParagraphOptions controls paragraph wrapping and horizontal alignment
The zero value uses word wrapping and start alignment.
func DefaultParagraphOptions ¶
func DefaultParagraphOptions() ParagraphOptions
DefaultParagraphOptions returns word wrapping with start alignment
type Runtime ¶
type Runtime[Message any] struct { // contains filtered or unexported fields }
Runtime is a single-goroutine application runtime with a bounded FIFO queue
func NewRuntime ¶
NewRuntime returns a runtime using a production monotonic clock
func NewRuntimeWithClock ¶
func NewRuntimeWithClock[Message any](app App[Message], config RuntimeConfig, clock Clock) (*Runtime[Message], error)
NewRuntimeWithClock returns a runtime using explicit settings and clock
func (*Runtime[Message]) ActiveSubscriptions ¶
ActiveSubscriptions returns the number of currently declared sources
func (*Runtime[Message]) ActiveTasks ¶
ActiveTasks returns supervised tasks that have not fully finished
func (*Runtime[Message]) ClearFocus ¶
func (r *Runtime[Message]) ClearFocus()
ClearFocus releases node focus and schedules a frame when focus existed
func (*Runtime[Message]) Close ¶
func (r *Runtime[Message]) Close()
Close cooperatively cancels active effect tasks and timers
func (*Runtime[Message]) DispatchEvent ¶
func (r *Runtime[Message]) DispatchEvent(event vt.Event) (EventDispatch, error)
DispatchEvent routes one normalized event through focus, hit testing, and ancestors
func (*Runtime[Message]) EffectDiagnostics ¶
func (r *Runtime[Message]) EffectDiagnostics() EffectDiagnostics
EffectDiagnostics returns cancellation, stale-result, and panic counters
func (*Runtime[Message]) ExitRequested ¶
ExitRequested reports whether the application requested normal exit
func (*Runtime[Message]) Interaction ¶
func (r *Runtime[Message]) Interaction() *InteractionState
Interaction returns runtime-owned UI continuity
func (*Runtime[Message]) PendingEffectMessages ¶
PendingEffectMessages returns completed effect messages waiting for capacity
func (*Runtime[Message]) PendingSubscriptionMessages ¶
PendingSubscriptionMessages returns values waiting before the application queue
func (*Runtime[Message]) PendingTasks ¶
PendingTasks returns supervised tasks waiting for a worker slot
func (*Runtime[Message]) PollEffects ¶
PollEffects moves due timers and completed tasks into the bounded queue
func (*Runtime[Message]) PollSubscriptions ¶
PollSubscriptions moves ready subscription values into the bounded queue
func (*Runtime[Message]) ProcessPending ¶
ProcessPending applies every queued message in FIFO order without rendering between messages
func (*Runtime[Message]) ProcessPendingWith ¶
ProcessPendingWith applies queued messages and observes each immediately before Update
func (*Runtime[Message]) QueuedMessages ¶
QueuedMessages returns the number of waiting messages
func (*Runtime[Message]) RenderIfDirty ¶
RenderIfDirty renders one frame when requested or state changed
func (*Runtime[Message]) RequestFocus ¶
RequestFocus requests focus for an ID in the current semantic tree
func (*Runtime[Message]) RequestFrame ¶
func (r *Runtime[Message]) RequestFrame()
RequestFrame schedules a frame even when application state has not changed
func (*Runtime[Message]) Resize ¶
Resize changes terminal size and schedules a frame when it differs
func (*Runtime[Message]) RunningSubscriptionStreams ¶
RunningSubscriptionStreams returns Stream producers that have not returned
func (*Runtime[Message]) RunningTasks ¶
RunningTasks returns supervised tasks occupying worker slots
func (*Runtime[Message]) SetScrollOffset ¶
func (r *Runtime[Message]) SetScrollOffset(id NodeID, offset ScrollOffset) bool
SetScrollOffset requests an offset that is clamped during layout
func (*Runtime[Message]) SetTextCursor ¶
SetTextCursor sets a UTF-8 byte cursor normalized to a grapheme boundary
func (*Runtime[Message]) SubscriptionActive ¶
func (r *Runtime[Message]) SubscriptionActive(key SubscriptionKey) bool
SubscriptionActive reports whether key is currently declared
func (*Runtime[Message]) SubscriptionDiagnostics ¶
func (r *Runtime[Message]) SubscriptionDiagnostics() SubscriptionDiagnostics
SubscriptionDiagnostics returns lifecycle and backpressure counters
func (*Runtime[Message]) SubscriptionGeneration ¶
func (r *Runtime[Message]) SubscriptionGeneration(key SubscriptionKey) uint64
SubscriptionGeneration returns the latest started generation for key
func (*Runtime[Message]) TaskGeneration ¶
TaskGeneration returns the latest generation started for one task key
func (*Runtime[Message]) TimeUntilEffectDeadline ¶
TimeUntilEffectDeadline returns time until the next clock-driven deadline
func (*Runtime[Message]) TimeUntilFrameDeadline ¶
TimeUntilFrameDeadline returns time until a pending rate-limited frame
type RuntimeConfig ¶
type RuntimeConfig struct {
// Size is the initial terminal cell size
Size Size
// QueueCapacity is the maximum number of waiting messages
QueueCapacity int
// TaskLimit is the maximum number of effect tasks executing concurrently
TaskLimit int
// SubscriptionCapacity is the maximum pending values retained per source
SubscriptionCapacity int
// MinimumFrameInterval limits non-urgent rendering; zero disables the limit
MinimumFrameInterval time.Duration
}
RuntimeConfig contains runtime construction settings
func NewRuntimeConfig ¶
func NewRuntimeConfig(size Size) RuntimeConfig
NewRuntimeConfig returns settings with the default bounded queue capacity
type ScopeID ¶
type ScopeID string
ScopeID is a stable key grouping tasks for explicit cancellation
func NewScopeID ¶
NewScopeID returns a scope ID from an application-defined stable value
type ScrollAxis ¶
type ScrollAxis uint8
ScrollAxis selects the axes controlled by a ScrollViewport
const ( // ScrollAxisBoth enables horizontal and vertical scrolling ScrollAxisBoth ScrollAxis = iota // ScrollAxisVertical enables vertical scrolling only ScrollAxisVertical // ScrollAxisHorizontal enables horizontal scrolling only ScrollAxisHorizontal )
type ScrollOffset ¶
type ScrollOffset struct {
// X is the horizontal content offset
X uint32
// Y is the vertical content offset
Y uint32
}
ScrollOffset is a two-dimensional ScrollViewport offset in cells
type ScrollState ¶
type ScrollState struct {
// Offset is the current cell offset after clamping
Offset ScrollOffset
// Maximum is the greatest valid offset for the current content and viewport
Maximum ScrollOffset
// AtStart reports whether every enabled axis is at its beginning
AtStart bool
// AtEnd reports whether every enabled axis is at its end
AtEnd bool
}
ScrollState contains a resolved ScrollViewport position and boundaries
type ScrollViewportOptions ¶
type ScrollViewportOptions[Message any] struct { // Axis selects the axes controlled by user and programmatic scrolling Axis ScrollAxis // StickToEnd follows content growth while the viewport remains at its end StickToEnd bool // EnsureFocusedVisible scrolls a focused descendant into view EnsureFocusedVisible bool // OnScroll optionally maps user scroll state changes to application messages OnScroll func(ScrollState) Message }
ScrollViewportOptions controls ScrollViewport behavior
func DefaultScrollViewportOptions ¶
func DefaultScrollViewportOptions[Message any]() ScrollViewportOptions[Message]
DefaultScrollViewportOptions returns two-dimensional scrolling without automatic following or focus tracking
type Subscription ¶
type Subscription[Message any] struct { // contains filtered or unexported fields }
Subscription is a declarative set of long-lived application message sources
func BatchSubscriptions ¶
func BatchSubscriptions[Message any](subscriptions ...Subscription[Message]) Subscription[Message]
BatchSubscriptions combines declarations while preserving declaration order
func EverySubscription ¶
func EverySubscription[Message any]( key SubscriptionKey, interval time.Duration, policy DeliveryPolicy, factory func() Message, ) Subscription[Message]
EverySubscription returns a runtime-clock interval source
The first value is produced after one full interval. It panics when interval is not positive or factory is nil.
func NoneSubscription ¶
func NoneSubscription[Message any]() Subscription[Message]
NoneSubscription returns an empty subscription set
func StreamSubscription ¶
func StreamSubscription[Message any]( key SubscriptionKey, policy DeliveryPolicy, stream SubscriptionStream[Message], ) Subscription[Message]
StreamSubscription returns a cooperatively cancellable long-lived source
It panics when stream is nil.
func (Subscription[Message]) IsNone ¶
func (s Subscription[Message]) IsNone() bool
IsNone reports whether this declaration contains no sources
func (Subscription[Message]) String ¶
func (s Subscription[Message]) String() string
String returns a diagnostic description of the subscription shape
type SubscriptionDiagnostics ¶
type SubscriptionDiagnostics struct {
// contains filtered or unexported fields
}
SubscriptionDiagnostics contains lifecycle, backpressure, and failure counters
func (SubscriptionDiagnostics) BatchFlushes ¶
func (d SubscriptionDiagnostics) BatchFlushes() uint64
BatchFlushes returns count- or time-triggered Batch releases
func (SubscriptionDiagnostics) BlockedSends ¶
func (d SubscriptionDiagnostics) BlockedSends() uint64
BlockedSends returns Stream sends that encountered a full inbox
func (SubscriptionDiagnostics) DiscardedMessages ¶
func (d SubscriptionDiagnostics) DiscardedMessages() uint64
DiscardedMessages returns values discarded when a generation stopped
func (SubscriptionDiagnostics) LatestReplacements ¶
func (d SubscriptionDiagnostics) LatestReplacements() uint64
LatestReplacements returns pending Latest values replaced before delivery
func (SubscriptionDiagnostics) ProducerPanics ¶
func (d SubscriptionDiagnostics) ProducerPanics() uint64
ProducerPanics returns producer or Every factory panics isolated by the supervisor
func (SubscriptionDiagnostics) Starts ¶
func (d SubscriptionDiagnostics) Starts() uint64
Starts returns the number of started subscription generations
func (SubscriptionDiagnostics) Stops ¶
func (d SubscriptionDiagnostics) Stops() uint64
Stops returns the number of stopped subscription generations
type SubscriptionKey ¶
type SubscriptionKey string
SubscriptionKey is a stable identity for one long-lived source
func NewSubscriptionKey ¶
func NewSubscriptionKey(value string) SubscriptionKey
NewSubscriptionKey returns a key from an application-defined stable value
func (SubscriptionKey) String ¶
func (k SubscriptionKey) String() string
String returns the application-defined key
type SubscriptionSink ¶
type SubscriptionSink[Message any] struct { // contains filtered or unexported fields }
SubscriptionSink is a cancellation-aware sender owned by one Stream producer
func (SubscriptionSink[Message]) Closed ¶
func (s SubscriptionSink[Message]) Closed() bool
Closed reports whether the runtime stopped this subscription generation
func (SubscriptionSink[Message]) Done ¶
func (s SubscriptionSink[Message]) Done() <-chan struct{}
Done is closed when the runtime stops this subscription generation
func (SubscriptionSink[Message]) Send ¶
func (s SubscriptionSink[Message]) Send(message Message) bool
Send submits a value according to the source delivery policy
Reliable and Batch delivery can block while the bounded inbox is full. It returns false after the runtime stops this subscription generation.
type SubscriptionStream ¶
type SubscriptionStream[Message any] func(context.Context, SubscriptionSink[Message])
SubscriptionStream is one cooperatively cancellable long-lived producer
type SystemClock ¶
type SystemClock struct {
// contains filtered or unexported fields
}
SystemClock is a production monotonic clock based on time.Time
func NewSystemClock ¶
func NewSystemClock() SystemClock
NewSystemClock returns a production clock with a new origin
func (SystemClock) Now ¶
func (c SystemClock) Now() Timestamp
Now returns elapsed monotonic time from the clock origin
type TaskKey ¶
type TaskKey string
TaskKey is a stable key for replacement and cancellation of one latest task
func NewTaskKey ¶
NewTaskKey returns a task key from an application-defined stable value
type TerminalOptions ¶
type TerminalOptions struct {
// Capabilities contains optional output encoder capabilities
Capabilities vt.Capabilities
// MouseTracking enables SGR mouse reports when non-nil
//
// It is disabled by default so terminal text selection remains available.
MouseTracking *vt.MouseTracking
// FocusFirst focuses the first focusable node before the initial frame
FocusFirst bool
// EscapeTimeout disambiguates a lone ESC from an escape sequence
EscapeTimeout time.Duration
// QueueCapacity is the maximum number of waiting application messages
QueueCapacity int
// TaskLimit is the maximum number of effect tasks executing concurrently
TaskLimit int
// SubscriptionCapacity is the maximum pending values retained per source
SubscriptionCapacity int
// MinimumFrameInterval limits non-urgent rendering; the default is 120 FPS
// and zero disables the limit
MinimumFrameInterval time.Duration
}
TerminalOptions contains settings for RunTerminal
func DefaultTerminalOptions ¶
func DefaultTerminalOptions() TerminalOptions
DefaultTerminalOptions returns event-driven settings with bounded queues and non-urgent rendering limited to 120 FPS
type TextInputState ¶
type TextInputState struct {
// contains filtered or unexported fields
}
TextInputState is Interaction State retained for one TextInput node
func (TextInputState) Cursor ¶
func (s TextInputState) Cursor() int
Cursor returns the UTF-8 byte cursor at a grapheme boundary
type TextSpan ¶
type TextSpan struct {
// Text is UTF-8 content rendered with Style
Text string
// Style applies to every grapheme in Text
Style vt.Style
}
TextSpan is one styled run of paragraph text
type TimedInputDecoder ¶
type TimedInputDecoder struct {
// contains filtered or unexported fields
}
TimedInputDecoder is a VT input decoder whose ambiguous lone-ESC timeout uses an injected clock
func NewTimedInputDecoder ¶
func NewTimedInputDecoder(clock Clock, escapeTimeout time.Duration) *TimedInputDecoder
NewTimedInputDecoder returns a timed decoder
It panics when clock is nil. A negative escape timeout is treated as zero.
func (*TimedInputDecoder) Feed ¶
func (d *TimedInputDecoder) Feed(input []byte) []vt.Event
Feed consumes one arbitrary input byte chunk
func (*TimedInputDecoder) Flush ¶
func (d *TimedInputDecoder) Flush() []vt.Event
Flush resolves all currently incomplete input immediately
func (*TimedInputDecoder) HasPending ¶
func (d *TimedInputDecoder) HasPending() bool
HasPending reports whether incomplete input is buffered
func (*TimedInputDecoder) Poll ¶
func (d *TimedInputDecoder) Poll() []vt.Event
Poll resolves a lone ESC when its deadline has elapsed
func (*TimedInputDecoder) TimeUntilDeadline ¶
func (d *TimedInputDecoder) TimeUntilDeadline() (time.Duration, bool)
TimeUntilDeadline returns time until a lone-ESC deadline
type Timestamp ¶
type Timestamp uint64
Timestamp is a monotonic runtime time measured in nanoseconds from a clock origin
func (Timestamp) Add ¶
Add returns a timestamp advanced by duration, saturating at the maximum
A nonpositive duration leaves the timestamp unchanged.
func (Timestamp) Nanoseconds ¶
Nanoseconds returns nanoseconds since the clock origin
type VerticalAlignment ¶
type VerticalAlignment uint8
VerticalAlignment controls vertical placement inside an alignment node
const ( // AlignTop places content at the top edge AlignTop VerticalAlignment = iota // AlignMiddle centers content vertically AlignMiddle // AlignBottom places content at the bottom edge AlignBottom )
type ViewContext ¶
type ViewContext struct {
// Size is the current terminal size in cells
Size Size
}
ViewContext contains environment information available while rebuilding a semantic view
type VirtualClock ¶
type VirtualClock struct {
// contains filtered or unexported fields
}
VirtualClock is a manually advanced monotonic clock for deterministic tests
func NewVirtualClock ¶
func NewVirtualClock() *VirtualClock
NewVirtualClock returns a virtual clock at timestamp zero
func (*VirtualClock) Advance ¶
func (c *VirtualClock) Advance(duration time.Duration) Timestamp
Advance moves the clock forward and returns its new timestamp
A nonpositive duration leaves the clock unchanged.
func (*VirtualClock) Now ¶
func (c *VirtualClock) Now() Timestamp
Now returns the current virtual timestamp
type VirtualFragment ¶ added in v0.1.1
type VirtualFragment[Message any] struct { // Origin is the fragment origin in content coordinates Origin ScrollOffset // Node is the semantic subtree beginning at Origin Node Node[Message] }
VirtualFragment is one lazily constructed visible or overscanned fragment
func NewVirtualFragment ¶ added in v0.1.1
func NewVirtualFragment[Message any](origin ScrollOffset, node Node[Message]) VirtualFragment[Message]
NewVirtualFragment returns a fragment beginning at origin
type VirtualViewport ¶ added in v0.1.1
type VirtualViewport struct {
// Offset is the first visible cell in content coordinates
Offset ScrollOffset
// Size is the visible viewport size in cells
Size Size
// ContentSize is the complete resolved content extent in cells
ContentSize Size
}
VirtualViewport is the visible content range requested by a virtual ScrollViewport
Source Files
¶
- ansi_text.go
- app.go
- clock.go
- core_node_render.go
- doc.go
- effect.go
- effect_supervisor.go
- geometry.go
- identity.go
- input.go
- interaction.go
- layout.go
- node.go
- node_interaction.go
- node_render.go
- panel.go
- renderer.go
- rich_text.go
- routing.go
- runtime.go
- style.go
- subscription.go
- subscription_supervisor.go
- terminal.go
- text_edit.go
- wake.go
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
async-search
command
|
|
|
command-palette
command
|
|
|
counter
command
Command counter is a minimal stateful Nagi TUI application
|
Command counter is a minimal stateful Nagi TUI application |
|
dashboard
command
|
|
|
extended-widget-gallery
command
|
|
|
file-browser
command
|
|
|
filtered-list
command
|
|
|
form-validation
command
|
|
|
log-viewer
command
|
|
|
multi-pane-log-viewer
command
|
|
|
virtual-scroll
command
Command virtual-scroll renders a million-row virtual viewport
|
Command virtual-scroll renders a million-row virtual viewport |
|
widget-gallery
command
|
|
|
internal
|
|
|
conformance
Package conformance contains private helpers for shared fixture tests
|
Package conformance contains private helpers for shared fixture tests |
|
ttyunix
Package ttyunix contains private Linux and macOS terminal-session integration for Nagi TUI.
|
Package ttyunix contains private Linux and macOS terminal-session integration for Nagi TUI. |
|
Package surface provides cell surface composition and diff primitives for Nagi TUI.
|
Package surface provides cell surface composition and diff primitives for Nagi TUI. |
|
Package tuitest provides virtual terminal and deterministic application test support for Nagi TUI.
|
Package tuitest provides virtual terminal and deterministic application test support for Nagi TUI. |
|
Package widget provides standard widgets composed exclusively from the public Nagi TUI semantic Node, style, identity, layout, and event APIs
|
Package widget provides standard widgets composed exclusively from the public Nagi TUI semantic Node, style, identity, layout, and event APIs |