Documentation
¶
Overview ¶
Package tui is the terminal-I/O layer around github.com/go-widgets/painter's CellPainter. It renders a widget tree into an ANSI cell stream sized to the current terminal, so the same widget code that produces pixels for a WUI or GUI back-end also produces text for a terminal — no widget changes required.
The package is deliberately minimal: no raw mode, no keyboard event loop, no alt-screen management. It ships a "snapshot" model — render one frame to a writer and return — that composes cleanly with either a caller-managed event loop or a CLI that prints once and exits. Higher-level facilities (an App runner with input, resize, and cleanup handling) live in a follow-up cycle.
Sizing follows the caller's preference:
- RenderOnceSized takes explicit (cols, rows) — the reliable form used by tests, size-aware callers, and headless renderers.
- RenderOnce queries the size from environment variables (EnvSize) and falls back to [DefaultCols]x[DefaultRows] when the environment does not report a size. This keeps the package stdlib-only — no ioctl, no cgo, no dependency on golang.org/x/term.
Both variants write a self-contained ANSI stream to the caller's writer via painter.CellPainter.WriteANSI; the caller is responsible for the surrounding terminal state (raw mode, alt screen, cursor visibility) if any.
Index ¶
- Constants
- func EnvSize() (cols, rows int, ok bool)
- func GutterWidth(lineCount int) int
- func LineNumberInk(theme *toolkit.Theme) toolkit.RGBA
- func RenderOnce(w io.Writer, widgets []painter.Widget, theme *painter.Theme) error
- func RenderOnceSized(w io.Writer, cols, rows int, widgets []painter.Widget, theme *painter.Theme) error
- func RenderToolkit(w io.Writer, widgets []toolkit.Widget, theme *toolkit.Theme) error
- func RenderToolkitSized(w io.Writer, cols, rows int, widgets []toolkit.Widget, theme *toolkit.Theme) error
- func SizeOrDefault() (cols, rows int)
- func SyntaxInk(k syntax.Kind, theme *toolkit.Theme) toolkit.RGBA
- type App
- type Cell
- type Color
- type HSplit
- type InputParser
- type ListBox
- type MenuBar
- type MenuDropdown
- type MenuItem
- type Popover
- type Statusbar
- type TTY
- type TermGrid
- type TextEditor
- func (t *TextEditor) Copy() string
- func (t *TextEditor) Cut() string
- func (t *TextEditor) DeleteSelection() bool
- func (t *TextEditor) Draw(pnt painter.Painter, theme *toolkit.Theme)
- func (t *TextEditor) Find(query string) bool
- func (t *TextEditor) FindNext() bool
- func (t *TextEditor) OnEvent(ev toolkit.Event)
- func (t *TextEditor) Paste()
- func (t *TextEditor) Replace(query, repl string) bool
- func (t *TextEditor) ReplaceAll(query, repl string) int
- func (t *TextEditor) SelectedText() string
- func (t *TextEditor) SetText(s string)
- func (t *TextEditor) Text() string
- type VBox
Constants ¶
const ( // HSplitMinFrac / HSplitMaxFrac bound LeftFrac so neither pane vanishes. HSplitMinFrac = 10 HSplitMaxFrac = 90 )
const ( DefaultCols = 80 DefaultRows = 24 )
DefaultCols and DefaultRows are the terminal dimensions used when neither the environment nor the caller supplies a size — the classic VT100 defaults every terminal emulator honours as a floor.
const EventTick toolkit.EventKind = 100
EventTick is the toolkit.EventKind the App emits at a caller- configured tick rate. Widgets that animate (Toast, Spinner) match on this kind to advance a frame counter and repaint. The value is deliberately placed above the toolkit's own iota range so it can never collide with a widget-produced Click / KeyDown / Char event.
const StatusbarSegmentMinW = 10
StatusbarSegmentMinW is the default minimum width of a non-last segment.
Variables ¶
This section is empty.
Functions ¶
func EnvSize ¶
EnvSize reads the terminal size from the COLUMNS and LINES environment variables. It returns (cols, rows, true) when both parse cleanly and hold positive integers; otherwise it returns (0, 0, false) and the caller should substitute defaults.
The env-vars-only strategy is a deliberate trade-off: it keeps the package stdlib-only (no TIOCGWINSZ ioctl per platform, no cgo, no golang.org/x/term dependency). Interactive shells that need dynamic sizes should export COLUMNS / LINES from their prompt hook, or pass an explicit size to RenderOnceSized.
func GutterWidth ¶ added in v0.8.0
GutterWidth returns the cell width of a line-number gutter for a code pane of lineCount lines: the number of digits in the largest line number (a minimum of 2) plus one cell of separation before the code. Shared by tui-explorer + tui-editor so their gutters line up.
func LineNumberInk ¶ added in v0.8.0
LineNumberInk is the muted ink for a line-number gutter: the theme's Border colour, which reads as a dim separator tone against any pane background.
func RenderOnce ¶
RenderOnce paints the widget tree into a fresh CellPainter sized to SizeOrDefault, fills the background with theme.Background, calls each widget's Draw, and writes the resulting ANSI stream to w. It is the snapshot form: no raw mode, no event loop; one frame then return.
The theme argument may be nil, in which case painter.LightTheme is used. This keeps CLI callers ergonomic (`tui.RenderOnce(os.Stdout, widgets, nil)`) without forcing them to import painter just to name the default theme.
func RenderOnceSized ¶
func RenderOnceSized(w io.Writer, cols, rows int, widgets []painter.Widget, theme *painter.Theme) error
RenderOnceSized is like RenderOnce but uses the explicit (cols, rows) dimensions instead of querying the environment. Cols and rows must both be positive; a non-positive value falls back to the corresponding default so callers cannot accidentally produce an empty render.
func RenderToolkit ¶ added in v0.2.0
RenderToolkit paints a toolkit.Widget tree into a fresh CellPainter sized to SizeOrDefault, fills the background with theme.Background, calls each widget's Draw, and writes the resulting ANSI stream to w.
It is the toolkit-widget counterpart of RenderOnce (which renders painter.Widget). The two exist side-by-side because toolkit.Theme carries fields (SurfaceAlt, OnBackground, Extra) that painter.Theme does not, so a toolkit widget cannot be rendered through RenderOnce without losing theme surface.
The theme argument may be nil, in which case toolkit.DefaultLight is used.
func RenderToolkitSized ¶ added in v0.2.0
func RenderToolkitSized(w io.Writer, cols, rows int, widgets []toolkit.Widget, theme *toolkit.Theme) error
RenderToolkitSized is like RenderToolkit but uses the explicit (cols, rows) dimensions instead of querying the environment. Cols and rows must both be positive; a non-positive value falls back to the corresponding default so callers cannot accidentally produce an empty render.
func SizeOrDefault ¶
func SizeOrDefault() (cols, rows int)
SizeOrDefault returns EnvSize when the environment reports a size, otherwise [DefaultCols]x[DefaultRows]. This is what RenderOnce consumes.
func SyntaxInk ¶ added in v0.5.0
SyntaxInk maps a syntax.Kind to a terminal ink for the given theme, choosing a dark- or light-appropriate One Dark / One Light-style palette from the theme's background luminance. Plain + Punct fall back to the theme foreground. Shared by tui-explorer + tui-editor so their code panes colour identically.
Types ¶
type App ¶ added in v0.3.0
type App struct {
// Root is the widget tree the App draws and dispatches events
// to. Callers wire the composition once and mutate its fields
// during OnKey callbacks; the next repaint reflects the state.
Root toolkit.Widget
// Theme cascades through the widget tree on every draw. Defaults
// to [toolkit.DefaultLight] if left nil.
Theme *toolkit.Theme
// Keys is a map from a key Code (matching InputParser output —
// "q", "Ctrl+C", "Up", "Enter", …) to a handler. Handlers can
// mutate App state (e.g. call [App.Quit]) or the widget tree.
// Global handlers run BEFORE the event reaches Root.OnEvent — the
// App always dispatches to Root afterwards.
Keys map[string]func(*App)
// TickHz sets the auto-tick frequency in Hz. 0 disables ticks. A
// widget subscribing to EventTick needs TickHz > 0 to animate.
TickHz int
// contains filtered or unexported fields
}
App is an interactive TUI runner. Instantiate one, set App.Root to your widget tree, optionally register keybindings + a tick rate, and call App.Run. The App handles alt-screen + raw mode, parses stdin into toolkit.Event values, dispatches them to the widget tree, repaints on demand, and cleans up on exit — including on panic, via a deferred TTY.Leave.
func NewApp ¶ added in v0.3.0
func NewApp() *App
NewApp returns an App wired to the real terminal: OpenTTY, os.Stdin, os.Stdout, real Unix signal handling, and time.NewTicker for the tick channel. Tests build an App by hand and swap the seams instead.
func (*App) Consume ¶ added in v0.3.1
func (a *App) Consume()
Consume tells the event loop that the current Keys handler fully handled the event and it must NOT propagate to Root.OnEvent. Without Consume, every key that matches a Keys handler also reaches Root — which is fine for global shortcuts (Ctrl+C to quit still lets the Root repaint from its own state), but wrong for mode-switching editors where pressing 'i' to enter edit mode would otherwise ALSO insert 'i' into the underlying TextView.
Idempotent within a single event dispatch. The event loop clears the flag at the top of every event so a Consume from a previous event never affects the next one.
func (*App) IsQuitting ¶ added in v0.3.0
IsQuitting reports whether Quit has been called (whether the loop is on its way to exit). Non-blocking. Useful for consumer tests that verify a key handler triggered a quit without spinning the event loop.
func (*App) Quit ¶ added in v0.3.0
func (a *App) Quit()
Quit signals the event loop to exit on the next iteration. Safe to call from a key handler or a goroutine, and idempotent: a second call is a no-op (the underlying quit channel is closed exactly once via sync.Once).
func (*App) Refresh ¶ added in v0.3.0
func (a *App) Refresh()
Refresh marks the frame dirty so the next iteration repaints. It also nudges the wake channel so a loop currently blocked in select unblocks — enabling async I/O goroutines to schedule a redraw without racing an unrelated event.
func (*App) Run ¶ added in v0.3.0
Run blocks, driving the event loop until Quit is called or an interrupt signal arrives. Returns the exit code (0 by default; 1 if TTY setup fails; 2 if a key handler or widget panics). Terminal state is guaranteed to be restored on exit — even on panic — via a deferred TTY.Leave.
The return is named (exitCode) so a panic recovered by the deferred recover func can overwrite it; without the named return the panic path would still yield the pre-panic value.
func (*App) SetOpenTTYFn ¶ added in v0.3.0
SetOpenTTYFn overrides the TTY factory the event loop uses at Run time. Consumer tests inject a fake TTY (or an error) so they can drive Run() without needing a real controlling terminal. Passing a factory that returns an error is a valid way to force Run() to exit with a non-zero code before any raw-mode side effect.
type Cell ¶ added in v0.3.6
Cell is one grid position after ANSI-decoding a terminal frame: the rune actually written, plus the foreground and background colors that were active when it was written. All zero-value colors mean "default" (nothing set). Cell exists so consumer tests can assert on the visual output at cell-precision — the previous text-strip protocol dropped color information and let bugs like "highlight rendered as `█` characters" ship undetected.
type Color ¶ added in v0.3.6
Color carries the 24-bit RGB values decoded from a CSI SGR "38;2" (foreground) or "48;2" (background) sequence. Zero value means "default" — SGR 0 or no color set.
type HSplit ¶ added in v0.23.0
type HSplit struct {
toolkit.Base
Left, Right toolkit.Widget
LeftFrac int
// contains filtered or unexported fields
}
HSplit is a cell-native resizable horizontal split: Left takes LeftFrac percent of the width, a 1-cell grip column separates it from Right, and Right takes the remainder. The grip glyph doubles as a drag handle -- a click on it starts a drag session; subsequent EventMouseDrag events (routed here by a parent VBox's drag-capture, or any container that keeps forwarding a captured drag) update LeftFrac; EventMouseUp ends the session. LeftFrac is clamped to [HSplitMinFrac, HSplitMaxFrac] so neither pane can collapse to zero cells.
Events are local (0-based within the split); bounds are absolute for Draw. Renders through painter.Painter, so the same split drives the cell (TUI) and RGBA (WUI/GUI) backends.
func (*HSplit) Draw ¶ added in v0.23.0
Draw paints both panes, then the grip column on top (Accent while dragging, Border otherwise) so the separator stays visible over either pane's bg.
type InputParser ¶ added in v0.3.0
type InputParser struct {
// contains filtered or unexported fields
}
InputParser reads bytes from a terminal stdin stream and emits toolkit.Event values. A single call to InputParser.Feed may produce zero, one, or many events: typing "abc" yields three toolkit.EventChar events, pasting a control sequence like "\x1b[A" yields one arrow-up event but consumes three bytes.
The toolkit exposes toolkit.EventKeyDown for named-key presses (Enter, Tab, arrows, Escape, …) and toolkit.EventChar for printable characters — the parser routes accordingly.
The pending buffer holds the incomplete tail of the last Feed call: a lone ESC (0x1B) whose next byte has not arrived, an ESC [ … partial CSI sequence still waiting for its final byte (0x40..0x7E), or a partial UTF-8 rune (1–3 bytes of a multi-byte codepoint split across two Reads). It is consumed automatically on the next Feed call, or drained by InputParser.Flush on an input-idle deadline.
func NewInputParser ¶ added in v0.3.0
func NewInputParser() *InputParser
NewInputParser returns a fresh parser with an empty buffer.
func (*InputParser) Feed ¶ added in v0.3.0
func (p *InputParser) Feed(b []byte) []toolkit.Event
Feed hands b bytes to the parser and returns any events that completed as a result. Bytes belonging to an incomplete sequence (a lone ESC, a partial CSI, a partial UTF-8 rune) are buffered internally and consumed on the next Feed call.
The classic Escape-vs-CSI ambiguity is resolved as follows: a lone ESC at the end of the buffer is held pending; on the next Feed a leading '[' starts a CSI sequence, any other byte causes the held ESC to be emitted as "Escape" and the following byte is then processed as a fresh input. Callers waiting on an idle deadline flush the held ESC via InputParser.Flush.
func (*InputParser) Flush ¶ added in v0.3.0
func (p *InputParser) Flush() []toolkit.Event
Flush emits any pending ESC (or partial CSI) as an "Escape" event and clears the buffer. Callers invoke it on an input-idle deadline to resolve the Escape-vs-CSI ambiguity in favour of a plain Escape. A partial UTF-8 rune is discarded silently — its tail bytes would be indistinguishable from an unrelated new keystroke by the time an idle timeout fires.
type ListBox ¶ added in v0.18.0
type ListBox struct {
toolkit.Base
Items []string
Selected int
// OnSelect fires after Selected changes (keyboard or click). Optional; a
// nil callback is a no-op. It receives the new index.
OnSelect func(int)
// contains filtered or unexported fields
}
ListBox is a cell-native single-selection list: one item per row, an accent-highlighted selection, arrow / Home / End / PageUp / PageDown navigation, click-to-select, and a viewport that scrolls to keep the selection visible. It is a toolkit.Widget, so like every widget here it renders through painter.Painter -- a terminal cell grid (TUI) or an RGBA pixel buffer (WUI/GUI) with the same code.
func NewListBox ¶ added in v0.18.0
NewListBox returns a ListBox over items with the first row selected.
type MenuBar ¶ added in v0.19.0
MenuBar is a cell-native horizontal menu: item labels laid out left to right on a single row, separated by menuBarSep cells, with a click on a label's cell range firing its OnClick. It is a toolkit.Widget, rendering through painter.Painter (cell grid for TUI, RGBA buffer for WUI/GUI).
func NewMenuBar ¶ added in v0.19.0
NewMenuBar returns a MenuBar over items.
func (*MenuBar) ItemXRange ¶ added in v0.19.0
ItemXRange returns the [start, end) local-X cell range of the i-th item, or (-1, -1) if i is out of range. Callers use it both to hit-test and to anchor a dropdown directly under an item.
type MenuDropdown ¶ added in v0.21.0
type MenuDropdown struct {
toolkit.Base
Title string
Body []string
ItemActions []func() // parallel to Body; nil / short = informational row
Visible bool
AnchorX int
AnchorY int
}
MenuDropdown is an anchored, self-sizing dropdown menu -- the panel that opens under a MenuBar item. It positions itself at (AnchorX, AnchorY) and sizes to its content, ignoring any bounds a container hands it. A click on a Body row runs the matching ItemActions entry (nil / short slice = an informational row: the click still dismisses the menu but runs nothing) and hides the menu.
A toolkit.Widget rendering through painter.Painter (cell grid / RGBA buffer).
func (*MenuDropdown) Draw ¶ added in v0.21.0
func (d *MenuDropdown) Draw(pnt painter.Painter, theme *toolkit.Theme)
Draw paints the anchored box (when Visible): Title on the top row, Body rows below.
func (*MenuDropdown) HitTest ¶ added in v0.21.0
func (d *MenuDropdown) HitTest(px, py int) bool
HitTest — hidden dropdowns claim no clicks.
func (*MenuDropdown) OnEvent ¶ added in v0.21.0
func (d *MenuDropdown) OnEvent(ev toolkit.Event)
OnEvent runs the clicked Body row's action (if any) and dismisses the menu.
func (*MenuDropdown) SetBounds ¶ added in v0.21.0
func (d *MenuDropdown) SetBounds(_ toolkit.Rect)
SetBounds ignores the requested rect and self-positions at the anchor with the natural size (a container's layout pass calls this; the dropdown opts out of the normal flow).
type MenuItem ¶ added in v0.19.0
type MenuItem struct {
Label string
OnClick func()
}
MenuItem is one clickable entry in a MenuBar. OnClick is optional -- a nil callback is a no-op (useful for a decorative or coming-soon slot).
type Popover ¶ added in v0.20.0
Popover is a cell-native modal overlay: a bordered box with a Title on the top row and Body lines below, shown only while Visible. It sizes its drawn height to the content (3 border/title rows + one per Body line, capped to its bounds). HitTest returns false while hidden, so an invisible Popover never claims a click from the widgets beneath it.
A toolkit.Widget: renders through painter.Painter (cell grid for TUI, RGBA buffer for WUI/GUI).
type Statusbar ¶ added in v0.24.0
type Statusbar struct {
toolkit.Base
Segments []string
// SegmentMinW is the minimum width (in cells) any non-last segment takes;
// the last segment always fills the rest of the bar. Defaults to
// StatusbarSegmentMinW when <= 0.
SegmentMinW int
}
Statusbar is a cell-native footer strip: N text segments laid out left-to-right (e.g. "Line 12, Col 4" + "UTF-8" + "Go" in an editor), each with a 1-cell pad, a thin vertical divider between them, and the LAST segment stretched to fill the remaining width so an empty bar still looks deliberate. It is the natural pairing for a MenuBar above and a document area between — together they assemble the stock window frame at terminal scale.
A toolkit.Widget rendering through painter.Painter (cell grid / RGBA buffer).
func NewStatusbar ¶ added in v0.24.0
NewStatusbar builds a Statusbar with the given segments and the default minimum segment width.
func (*Statusbar) Draw ¶ added in v0.24.0
Draw paints the strip background plus every segment, with a divider column between adjacent segments.
func (*Statusbar) SetSegment ¶ added in v0.24.0
SetSegment replaces the i-th segment in place. An index past the end grows the bar (filling intermediate slots with "") so callers can add segments lazily; a negative index is ignored.
type TTY ¶ added in v0.3.0
type TTY interface {
// Enter puts the terminal in raw mode, saves the current
// termios state, switches to the alt-screen, and hides the
// cursor. Idempotent — a second call while entered is a no-op.
Enter() error
// Leave reverses Enter: restores the alt-screen, shows the
// cursor, and restores the saved termios state. Always safe to
// call, including from a defer or a panic recovery.
Leave() error
// Size returns the current terminal dimensions in cells.
Size() (cols, rows int, err error)
}
TTY is the abstraction the App runner uses to talk to a real terminal. Implementations set raw mode, hide the cursor, switch to the alt-screen, and reverse everything on Close. The mock implementation used in tests satisfies the same interface without touching a real terminal.
type TermGrid ¶ added in v0.3.6
TermGrid is a 2D cell buffer produced by DecodeANSI. Rows and Cols are the grid dimensions; Cells is row-major (Cells[y*Cols+x]).
func DecodeANSI ¶ added in v0.3.6
DecodeANSI parses stream as a sequence of CSI SGR + printable runes + cursor-positioning + line breaks, and lays every printable rune into a Cell at the current cursor position with the current foreground / background color. Only the subset of CSI a painter.CellPainter emits is honored:
- CSI H → cursor to (1, 1)
- CSI r ; c H → cursor to (c, r), 1-indexed
- CSI 0 m → reset colors
- CSI 38 ; 2 ; R ; G ; B m → foreground truecolor
- CSI 48 ; 2 ; R ; G ; B m → background truecolor
- CSI ?1049 h / l → alt-screen enter/leave (recognised, no-op)
- CSI ?25 h / l → cursor show/hide (recognised, no-op)
Unknown CSI sequences consume their bytes and are ignored so a caller can freely pass a frame that also contains cursor styling or bracketed paste. \n and \r reset the cursor to column 0 and advance the row (LF) or stay on the same row (CR).
func (*TermGrid) At ¶ added in v0.3.6
At returns the cell at (x, y). Out-of-bounds coordinates return the zero Cell — callers that care about bounds should check dims.
func (*TermGrid) Row ¶ added in v0.3.6
Row returns the y-th row as a Cell slice. Panics on out-of-bounds y — mirrors slice indexing conventions.
type TextEditor ¶ added in v0.9.0
type TextEditor struct {
toolkit.Base
Lines []string
CursorLine int
CursorCol int
Focused bool
Filename string
ReadOnly bool
ShowGutter bool
// contains filtered or unexported fields
}
TextEditor is a cell-native, read-write multi-line text editor widget with syntax highlighting and an optional line-number gutter. It is a toolkit.Widget: give it a bounds, set Focused, and forward events to OnEvent.
- One cell per glyph, one row per line (no soft wrap).
- Filename's extension drives the syntax language (see the syntax package); "" leaves the text plain. Highlighting is recomputed on every change so it tracks live edits.
- Set ReadOnly to use it as a code viewer: insert / delete / newline events are ignored, but the caret still navigates (arrows, click).
- ShowGutter draws a right-aligned line-number gutter (NewTextEditor enables it).
func NewTextEditor ¶ added in v0.9.0
func NewTextEditor() *TextEditor
NewTextEditor returns an empty editor with the line-number gutter enabled.
func (*TextEditor) Copy ¶ added in v0.13.0
func (t *TextEditor) Copy() string
Copy stores the selection in the widget clipboard and returns it.
func (*TextEditor) Cut ¶ added in v0.13.0
func (t *TextEditor) Cut() string
Cut copies the selection to the clipboard and removes it, returning the text.
func (*TextEditor) DeleteSelection ¶ added in v0.13.0
func (t *TextEditor) DeleteSelection() bool
DeleteSelection removes the selected text (a single undo step). Returns whether anything was deleted.
func (*TextEditor) Draw ¶ added in v0.9.0
func (t *TextEditor) Draw(pnt painter.Painter, theme *toolkit.Theme)
Draw paints the pane background, the (optional) line-number gutter, the syntax-highlighted text, and the caret.
func (*TextEditor) Find ¶ added in v0.11.0
func (t *TextEditor) Find(query string) bool
Find moves the caret to the next occurrence of query at or after the current caret, searching forward and wrapping to the top; it returns whether a match was found. An empty query is a no-op. The query is remembered for FindNext.
func (*TextEditor) FindNext ¶ added in v0.11.0
func (t *TextEditor) FindNext() bool
FindNext repeats the last Find starting just past the caret, so successive calls walk consecutive matches (wrapping). No-op with no prior Find.
func (*TextEditor) OnEvent ¶ added in v0.9.0
func (t *TextEditor) OnEvent(ev toolkit.Event)
OnEvent applies one input event: character insert, Backspace, Delete, Enter, Ctrl+Z/Y (undo/redo), Ctrl+X/V (cut/paste) -- all no-ops when ReadOnly -- the arrow / Home / End / PageUp / PageDown navigation keys, or a click / drag (caret + selection). Re-highlights after any change.
func (*TextEditor) Paste ¶ added in v0.13.0
func (t *TextEditor) Paste()
Paste inserts the clipboard at the caret, replacing an active selection. A single undo step. No-op when ReadOnly or the clipboard is empty.
func (*TextEditor) Replace ¶ added in v0.12.0
func (t *TextEditor) Replace(query, repl string) bool
Replace finds the next occurrence of query (forward from the caret, wrapping) and replaces it with repl, leaving the caret just after the replacement so a repeated call walks to the next one. Returns whether a replacement happened. No-op (false) when ReadOnly or query is empty. Undoable as one step.
func (*TextEditor) ReplaceAll ¶ added in v0.12.0
func (t *TextEditor) ReplaceAll(query, repl string) int
ReplaceAll replaces every occurrence of query with repl across the whole buffer and returns the number replaced. The caret column is clamped to its (possibly shorter) line. No-op (0) when ReadOnly or query is empty; the whole operation is a single undo step.
func (*TextEditor) SelectedText ¶ added in v0.13.0
func (t *TextEditor) SelectedText() string
SelectedText returns the text covered by the active selection, or "" if none.
func (*TextEditor) SetText ¶ added in v0.9.0
func (t *TextEditor) SetText(s string)
SetText replaces the buffer (split on "\n"), resets the caret to the top, and re-highlights.
func (*TextEditor) Text ¶ added in v0.9.0
func (t *TextEditor) Text() string
Text returns the buffer joined by newlines (no trailing newline).
type VBox ¶ added in v0.22.0
type VBox struct {
toolkit.Base
Header toolkit.Widget
Body toolkit.Widget
HeaderH int
Overlays []toolkit.Widget
// contains filtered or unexported fields
}
VBox is a header / body / footer vertical layout: Header keeps a fixed HeaderH rows at the top, Footer a fixed FooterH rows at the bottom, and Body fills the space between. Overlays float on top, inset from the body area, and are hit-tested (so an invisible Popover / anchored MenuDropdown claims clicks only when it wants them). It captures a drag once a click lands on a child so subsequent EventMouseDrag / EventMouseUp keep flowing to that child with the same coordinate translation.
A toolkit.Widget rendering through painter.Painter (cell grid / RGBA buffer).
func (*VBox) Draw ¶ added in v0.22.0
Draw paints body first, then header + footer chrome, then overlays on top.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
tui-catalogue
command
tui-catalogue renders the complete go-widgets/toolkit widget catalogue (every kind with a public constructor) into a scrollable cell-grid frame written to stdout as an ANSI stream.
|
tui-catalogue renders the complete go-widgets/toolkit widget catalogue (every kind with a public constructor) into a scrollable cell-grid frame written to stdout as an ANSI stream. |
|
tui-editor
command
tui-editor is the reference loom-style interactive demo for tui.App: a modal (vi-inspired) text editor built on top of the existing toolkit widgets — TextView for the buffer, Statusbar for the mode + cursor + filename indicator, MenuBar for the chrome, and a Popover-wrapped SearchEntry for the command palette.
|
tui-editor is the reference loom-style interactive demo for tui.App: a modal (vi-inspired) text editor built on top of the existing toolkit widgets — TextView for the buffer, Statusbar for the mode + cursor + filename indicator, MenuBar for the chrome, and a Popover-wrapped SearchEntry for the command palette. |
|
tui-explorer
command
tui-explorer is the reference interactive demo for tui.App: a small k9s-style file-browser mockup composed from toolkit widgets.
|
tui-explorer is the reference interactive demo for tui.App: a small k9s-style file-browser mockup composed from toolkit widgets. |
|
tui-snapshot
command
tui-snapshot renders a sample widget tree to stdout as an ANSI stream.
|
tui-snapshot renders a sample widget tree to stdout as an ANSI stream. |
|
Package syntax is a tiny, dependency-free syntax highlighter for the TUI previews.
|
Package syntax is a tiny, dependency-free syntax highlighter for the TUI previews. |