Documentation
¶
Overview ¶
Package radish is a small, open, testable terminal-interactivity library.
radish provides interactive terminal prompts - single-select (Select), multi-select (MultiSelect), and single-line text (Input) - built around a strict separation between a pure, deterministic Model and a thin I/O edge:
- A Model holds all state, logic, and rendering. It is pure: no I/O, no globals, no time. Update(Event) advances state; View() renders a frame.
- The I/O edge is two interfaces - EventSource (where input Events come from) and FrameSink (where rendered frames go) - that Run is parameterized by.
In production the edge is a real terminal in raw mode. In tests it is a scripted source of Events and a recording sink of frames. The same Model and View run in both, so the real rendering and logic are exercised directly in deterministic tests rather than mocked away.
radish is deliberately open where comparable libraries are closed: the match function, key bindings, styling, the event source, and the render target are all injectable, each with a sane default so the simple case stays a one-liner.
Index ¶
- Variables
- func DefaultMatcher(filter, label string) (bool, int)
- func Run(model Model, src EventSource, sink FrameSink) (Result, Model, error)
- func RunInput(m *InputModel, in *os.File, out io.Writer) (value string, ok bool, err error)
- func RunMultiSelect(m *MultiSelectModel, in *os.File, out io.Writer) (values []string, ok bool, err error)
- func RunSelect(m *SelectModel, in *os.File, out io.Writer) (value string, ok bool, err error)
- func RunTerminal(model Model, in *os.File, out io.Writer) (Result, Model, error)
- type Cmd
- type EchoMode
- type Event
- type EventSource
- type FrameSink
- type InputModel
- func (m *InputModel) Echo(mode EchoMode) *InputModel
- func (m *InputModel) KeyMap(k KeyMap) *InputModel
- func (m *InputModel) Placeholder(s string) *InputModel
- func (m *InputModel) Prompt(s string) *InputModel
- func (m *InputModel) Summary() string
- func (m *InputModel) SummaryFunc(fn func(value string) string) *InputModel
- func (m *InputModel) Theme(t *Theme) *InputModel
- func (m *InputModel) Title(s string) *InputModel
- func (m *InputModel) Update(e Event) (Model, Cmd)
- func (m *InputModel) Validate(fn func(string) error) *InputModel
- func (m *InputModel) Value() (string, bool)
- func (m *InputModel) View() string
- func (m *InputModel) Width(n int) *InputModel
- type KeyMap
- type KeyType
- type Matcher
- type Model
- type Modifier
- type MultiSelectModel
- func (m *MultiSelectModel) Height(n int) *MultiSelectModel
- func (m *MultiSelectModel) Hint(s string) *MultiSelectModel
- func (m *MultiSelectModel) KeyMap(k KeyMap) *MultiSelectModel
- func (m *MultiSelectModel) Matcher(fn Matcher) *MultiSelectModel
- func (m *MultiSelectModel) Max(n int) *MultiSelectModel
- func (m *MultiSelectModel) Min(n int) *MultiSelectModel
- func (m *MultiSelectModel) Options(opts ...string) *MultiSelectModel
- func (m *MultiSelectModel) Preselect(labels ...string) *MultiSelectModel
- func (m *MultiSelectModel) Selected() []string
- func (m *MultiSelectModel) Summary() string
- func (m *MultiSelectModel) SummaryFunc(fn func(selected []string) string) *MultiSelectModel
- func (m *MultiSelectModel) Theme(t *Theme) *MultiSelectModel
- func (m *MultiSelectModel) Title(s string) *MultiSelectModel
- func (m *MultiSelectModel) Update(e Event) (Model, Cmd)
- func (m *MultiSelectModel) View() string
- func (m *MultiSelectModel) Width(n int) *MultiSelectModel
- type Result
- type ScriptDriver
- type SelectModel
- func (m *SelectModel) Height(n int) *SelectModel
- func (m *SelectModel) KeyMap(k KeyMap) *SelectModel
- func (m *SelectModel) Matcher(fn Matcher) *SelectModel
- func (m *SelectModel) Options(opts ...string) *SelectModel
- func (m *SelectModel) Selected() (string, bool)
- func (m *SelectModel) Summary() string
- func (m *SelectModel) SummaryFunc(fn func(selected string) string) *SelectModel
- func (m *SelectModel) Theme(t *Theme) *SelectModel
- func (m *SelectModel) Title(s string) *SelectModel
- func (m *SelectModel) Update(e Event) (Model, Cmd)
- func (m *SelectModel) View() string
- func (m *SelectModel) Width(n int) *SelectModel
- type Summarizer
- type TermDriver
- type Theme
Constants ¶
This section is empty.
Variables ¶
var ErrNotInteractive = errors.New("radish: not an interactive terminal")
ErrNotInteractive is returned by RunTerminal when the input is not a TTY.
Functions ¶
func DefaultMatcher ¶
DefaultMatcher is a case-insensitive subsequence ("fuzzy") match: every rune of filter must appear in label, in order. Exact (case-insensitive) equality ranks best, then a prefix match, then everything else.
func Run ¶
Run drives a Model to completion against the given source and sink. It is the single place the event loop lives:
- render the initial frame
- read an event; on io.EOF, treat as cancel
- Update the model; on CmdSubmit/CmdCancel, collapse and return
- otherwise render the new frame and repeat
It returns the Result, the final Model (type-assert it to read a typed value, e.g. *SelectModel), and any I/O error from the sink/source.
func RunInput ¶
RunInput runs a single-line text prompt on a real terminal and returns the typed value. ok is false when the user canceled (Esc/Ctrl-C). It returns ErrNotInteractive when in is not a TTY. The convenient one-call form; for full control over the I/O edge (e.g. tests) use Run with a ScriptDriver.
func RunMultiSelect ¶
func RunMultiSelect(m *MultiSelectModel, in *os.File, out io.Writer) (values []string, ok bool, err error)
RunMultiSelect runs a multi-select prompt on a real terminal and returns the chosen values. ok is false when the user canceled (Esc/Ctrl-C). It returns ErrNotInteractive when in is not a TTY. The convenient one-call form; for full control over the I/O edge (e.g. tests) use Run with a ScriptDriver.
func RunSelect ¶
RunSelect runs a single-select prompt on a real terminal and returns the chosen value. ok is false when the user canceled (Esc/Ctrl-C). It returns ErrNotInteractive when in is not a TTY. This is the convenient one-call form; for full control over the I/O edge (e.g. tests) use Run with your own EventSource/FrameSink, or a ScriptDriver.
func RunTerminal ¶
RunTerminal drives a Model against a real terminal: in is put into raw mode and read for keystrokes, frames are rendered inline to out. It returns ErrNotInteractive (without touching the terminal) when in is not a TTY, so callers can fall back to non-interactive behavior. out is conventionally stderr, keeping stdout clean for a program's actual result.
Types ¶
type Cmd ¶
type Cmd int
Cmd is a control-flow signal returned by Update. It is a tiny synchronous enum, not an async command runtime: Run evaluates it inline.
type Event ¶
Event is one logical input. For KeyRune, Rune holds the character; for named keys, Rune is unused.
func Parse ¶
Parse converts raw terminal input bytes into high-level Events.
It returns the parsed events and the number of leading bytes consumed. A trailing *incomplete* escape sequence or partial UTF-8 rune is left unconsumed (consumed < len(b)), so a streaming caller can keep b[consumed:], append the next read, and call Parse again. Bytes that decode to nothing meaningful (e.g. unmapped control characters) are consumed but produce no event.
Parse is pure: no I/O, no state. It is the entire cross-platform input surface, which is why it is unit-tested exhaustively in isolation.
func ParseKeyName ¶
ParseKeyName returns the Event for a named key, the inverse of Event.String for named keys - e.g. "up", "enter", "ctrl-c", "shift-tab", or "space" for the space rune. It returns ok=false for an unknown name. Printable characters are not handled here; pass those as runes via RuneEvent. Sharing keyNames with Event.String keeps the display and parse vocabularies from drifting.
type EventSource ¶
EventSource yields input Events, blocking until one is available. It returns io.EOF when input is exhausted. In production this reads a real terminal; in tests it replays a scripted slice.
type FrameSink ¶
FrameSink consumes rendered frames. Render replaces the previously-shown frame; Finish performs the terminal "collapse" - clearing the interactive frame and emitting a final summary (or nothing). In production this drives a real terminal; in tests it records frames.
type InputModel ¶
type InputModel struct {
// contains filtered or unexported fields
}
InputModel is a single-line text prompt: an optional title heading, an inline prompt prefix, and an editable value with a visible cursor. Like the other components it is a pure Model - all state and rendering, no I/O - so it runs identically in production and under scripted test events.
Build one with the chained setters (NewInput().Prompt(...)), then hand it to Run. After Run, read the text with Value.
EchoNone renders nothing as the user types (the terminal convention for passwords): every keystroke produces a byte-identical frame and the typed runes never appear in any rendered frame, only in the returned Value. In EchoNone the cursor cannot be moved (append and backspace only), matching tools like sudo.
func NewInput ¶
func NewInput() *InputModel
NewInput returns an InputModel with default theme and keymap and normal echo.
func (*InputModel) Echo ¶
func (m *InputModel) Echo(mode EchoMode) *InputModel
Echo sets how typed text is displayed (EchoNormal, EchoNone, EchoMasked).
func (*InputModel) KeyMap ¶
func (m *InputModel) KeyMap(k KeyMap) *InputModel
KeyMap overrides the key bindings.
func (*InputModel) Placeholder ¶
func (m *InputModel) Placeholder(s string) *InputModel
Placeholder sets ghost/hint text shown (dimmed) while the field is empty. It is only shown in EchoNormal mode.
func (*InputModel) Prompt ¶
func (m *InputModel) Prompt(s string) *InputModel
Prompt sets the inline prefix rendered immediately before the editable field (e.g. "> " or "Confirm? Y/n > ").
func (*InputModel) Summary ¶
func (m *InputModel) Summary() string
Summary is the collapsed line shown after submit. It returns "" on cancel, and - crucially - never echoes a secret: EchoNone collapses to nothing and EchoMasked to dots. A SummaryFunc, when set, replaces all of this. Implements Summarizer.
func (*InputModel) SummaryFunc ¶ added in v0.2.0
func (m *InputModel) SummaryFunc(fn func(value string) string) *InputModel
SummaryFunc overrides the collapsed line shown after submit: fn receives the submitted value and its result replaces the default summary entirely (an empty result collapses to nothing). Cancel still collapses to nothing. Note fn receives the real value even in masked/secret echo modes - it is the caller's job not to leak it.
func (*InputModel) Theme ¶
func (m *InputModel) Theme(t *Theme) *InputModel
Theme overrides the styling. A nil argument is ignored.
func (*InputModel) Title ¶
func (m *InputModel) Title(s string) *InputModel
Title sets an optional heading line shown above the input field.
func (*InputModel) Update ¶
func (m *InputModel) Update(e Event) (Model, Cmd)
Update advances the model in response to one event. It implements Model. Printable runes and Backspace are intrinsic edits; cursor movement is bindable but disabled entirely in EchoNone (append + backspace only).
func (*InputModel) Validate ¶ added in v0.2.0
func (m *InputModel) Validate(fn func(string) error) *InputModel
Validate sets a submit gate: on Enter the current value is passed to fn, and a non-nil error blocks the submit, rendering the error message under the field until the value is next edited. A nil fn (the default) accepts everything.
func (*InputModel) Value ¶
func (m *InputModel) Value() (string, bool)
Value returns the typed text and true, or ("", false) if the prompt was canceled.
func (*InputModel) View ¶
func (m *InputModel) View() string
View renders the title (if any), the field line, and a pending validation error (if any) below it. No trailing newline.
func (*InputModel) Width ¶
func (m *InputModel) Width(n int) *InputModel
Width caps the rendered field to this terminal width (with an ellipsis). Zero disables truncation.
type KeyMap ¶
type KeyMap struct {
Up []KeyType
Down []KeyType
Left []KeyType // move the text cursor left (Input)
Right []KeyType // move the text cursor right (Input)
PageUp []KeyType
PageDown []KeyType
Home []KeyType
End []KeyType
Toggle []KeyType // toggle the row's selection (MultiSelect); Space also toggles
Submit []KeyType
Cancel []KeyType
ClearFilter []KeyType
}
KeyMap binds actions to one or more KeyTypes. Override any field to remap an action; a nil/empty binding means the action is unbound. Typing a printable rune and Backspace are the intrinsic text-input pair and are always filter edits (never remappable), which keeps "type to filter" unambiguous; higher-level editing commands like ClearFilter are bindable actions so they stay open to customization.
One KeyMap serves the whole prompt family, so a given component reads only the actions it supports and silently ignores the rest (e.g. Input ignores Up/Down/ Toggle; Select ignores Left/Right). MultiSelect also toggles on Space, which is a deliberate, non-remappable exception to "only runes and Backspace are intrinsic" (Space-to-toggle is a near-universal convention and Space is useless as a filter character).
func DefaultKeyMap ¶
func DefaultKeyMap() KeyMap
DefaultKeyMap is the conventional binding: arrows navigate (Up/Down) or move the text cursor (Left/Right), PageUp/PageDown jump a page, Home/End jump to the ends, Enter submits, Esc/Ctrl-C/Ctrl-D cancel, and Ctrl-U clears the filter.
type KeyType ¶
type KeyType int
KeyType identifies a logical key. Printable input is delivered as KeyRune (the character is in Event.Rune); everything else is a named key. The set is kept deliberately small - just what the interactive components need - and grows only as new components require it.
type Matcher ¶
Matcher reports whether an option label matches the current filter text, and a rank for ordering (lower sorts first; equal ranks keep original order). Components that don't reorder may ignore rank. By convention an empty filter matches everything.
Matcher is the primary openness hook: callers inject their own to control how typing narrows the list, while the built-in DefaultMatcher covers the common fuzzy case.
type Model ¶
Model is a pure, deterministic interactive component. Update advances state in response to one Event; View renders the current frame as a multi-line string with no trailing newline. A Model performs no I/O and holds no global state, so the same Model runs identically in production and in tests.
type Modifier ¶
type Modifier uint8
Modifier is a reserved bitfield for chord modifiers. The current parser never sets it (Ctrl-C / Ctrl-D have dedicated KeyTypes), but the field on Event keeps the type source-stable for when Alt/Ctrl chords are modelled later.
const ModNone Modifier = 0
type MultiSelectModel ¶
type MultiSelectModel struct {
// contains filtered or unexported fields
}
MultiSelectModel is a multi-select prompt: a title, a list of options with live type-to-filter and a moving cursor (all shared with Select via the embedded list), plus a per-option selection toggle and optional min/max bounds on how many may be chosen. It is a pure Model, driven identically in production and in tests.
Build one with the chained setters (NewMultiSelect().Title(...).Options(...)), then hand it to Run. After Run, read the chosen labels with Selected.
Tab or Space toggles the row under the cursor. With a Max set, toggling a new option on is blocked once Max are selected (deselect is always allowed). With a Min set, Enter does nothing until at least Min are selected.
func NewMultiSelect ¶
func NewMultiSelect() *MultiSelectModel
NewMultiSelect returns a MultiSelectModel with sane defaults (fuzzy matcher, default theme and keymap, 10 visible rows, no min/max). Customize via the setters.
func (*MultiSelectModel) Height ¶
func (m *MultiSelectModel) Height(n int) *MultiSelectModel
Height sets how many option rows are visible at once (the viewport size). Non-positive values are ignored.
func (*MultiSelectModel) Hint ¶ added in v0.2.0
func (m *MultiSelectModel) Hint(s string) *MultiSelectModel
Hint sets an interaction hint rendered as a faint footer line, e.g. "space to toggle, enter to confirm" for first-time users. Empty = no line.
func (*MultiSelectModel) KeyMap ¶
func (m *MultiSelectModel) KeyMap(k KeyMap) *MultiSelectModel
KeyMap overrides the key bindings.
func (*MultiSelectModel) Matcher ¶
func (m *MultiSelectModel) Matcher(fn Matcher) *MultiSelectModel
Matcher overrides the filter-matching function. A nil argument is ignored.
func (*MultiSelectModel) Max ¶
func (m *MultiSelectModel) Max(n int) *MultiSelectModel
Max sets the maximum number of options that may be selected (0 = unlimited). Negative values are ignored.
func (*MultiSelectModel) Min ¶
func (m *MultiSelectModel) Min(n int) *MultiSelectModel
Min sets the minimum number of options that must be selected before Enter submits. Negative values are ignored.
func (*MultiSelectModel) Options ¶
func (m *MultiSelectModel) Options(opts ...string) *MultiSelectModel
Options sets the selectable options (in display order).
func (*MultiSelectModel) Preselect ¶ added in v0.2.0
func (m *MultiSelectModel) Preselect(labels ...string) *MultiSelectModel
Preselect marks the options with the given labels as already selected, so the prompt opens with them checked (e.g. reflecting defaults). Labels that match no option are ignored. Order-independent with Options: labels are remembered and reapplied whenever the options change.
func (*MultiSelectModel) Selected ¶
func (m *MultiSelectModel) Selected() []string
Selected returns the chosen option labels in original option order.
func (*MultiSelectModel) Summary ¶
func (m *MultiSelectModel) Summary() string
Summary is the collapsed line shown after submit: title plus the chosen values. Returns "" on cancel. A SummaryFunc, when set, replaces the default rendering. Implements Summarizer.
func (*MultiSelectModel) SummaryFunc ¶ added in v0.2.0
func (m *MultiSelectModel) SummaryFunc(fn func(selected []string) string) *MultiSelectModel
SummaryFunc overrides the collapsed line shown after submit: fn receives the selected labels (in option order) and its result replaces the default summary entirely (an empty result collapses to nothing). Cancel still collapses to nothing.
func (*MultiSelectModel) Theme ¶
func (m *MultiSelectModel) Theme(t *Theme) *MultiSelectModel
Theme overrides the styling. A nil argument is ignored.
func (*MultiSelectModel) Title ¶
func (m *MultiSelectModel) Title(s string) *MultiSelectModel
Title sets the line shown above the options (the question being asked).
func (*MultiSelectModel) Update ¶
func (m *MultiSelectModel) Update(e Event) (Model, Cmd)
Update advances the model in response to one event. It implements Model.
func (*MultiSelectModel) View ¶
func (m *MultiSelectModel) View() string
View renders the title, optional filter line, the visible window of options with checkboxes and the cursor row marked, scroll hints, and a min hint while under the minimum. No trailing newline; line count is fully data-driven.
func (*MultiSelectModel) Width ¶
func (m *MultiSelectModel) Width(n int) *MultiSelectModel
Width caps each option row to this terminal width (with an ellipsis). Zero disables truncation.
type Result ¶
type Result struct {
Canceled bool
}
Result reports how an interaction ended. A run that returns a nil error ended in exactly one of two ways: the user submitted (Canceled == false) or aborted (Canceled == true, via Esc/Ctrl-C/Ctrl-D or EOF). The chosen value, if any, lives on the component (e.g. SelectModel.Selected) or is returned by the typed runners (RunSelect).
type ScriptDriver ¶
type ScriptDriver struct {
// contains filtered or unexported fields
}
ScriptDriver replays a fixed sequence of Events through one or more Models and records every frame the Models render. It fills the same role as the production terminal driver, but with no terminal: the real Model and View run unchanged - only the I/O edge is scripted. This is what makes deterministic, end-to-end snapshot tests of the real interactive UI possible.
The event source is consumed across Run calls: a second Run continues from wherever the first stopped, mirroring how sequential prompts share one real terminal. Frames likewise accumulate across Runs.
func NewScriptDriver ¶
func NewScriptDriver(events []Event) *ScriptDriver
NewScriptDriver creates a driver that will feed events in order, then EOF.
func (*ScriptDriver) Events ¶
func (d *ScriptDriver) Events() []Event
Events returns the scripted events, for callers that label frames by their triggering keystroke.
func (*ScriptDriver) FrameEventIdx ¶ added in v0.2.0
func (d *ScriptDriver) FrameEventIdx() []int
FrameEventIdx returns, for each recorded frame, the index into Events() of the event that triggered it, or -1 for a frame rendered without consuming an event (a prompt's initial render). Aligned with Frames().
func (*ScriptDriver) Frames ¶
func (d *ScriptDriver) Frames() []string
Frames returns the recorded frames in order across all Runs: each prompt's initial render, the render after each consumed event, and (on submit) the final collapsed summary. Use FrameEventIdx to map a frame back to the event that produced it.
type SelectModel ¶
type SelectModel struct {
// contains filtered or unexported fields
}
SelectModel is a single-select prompt: a title, a list of options, live type-to-filter, and a moving cursor. It is a pure Model - all state, logic, and rendering, no I/O - so it is driven identically by the production terminal and by scripted test events.
Build one with the chained setters (NewSelect().Title(...).Options(...)), then hand it to Run. After Run, read the choice with Selected. The option set, filter, cursor, and viewport live in the embedded list, shared with MultiSelect.
func NewSelect ¶
func NewSelect() *SelectModel
NewSelect returns a SelectModel with sane defaults (fuzzy matcher, default theme and keymap, 10 visible rows). Customize via the chained setters.
func (*SelectModel) Height ¶
func (m *SelectModel) Height(n int) *SelectModel
Height sets how many option rows are visible at once (the viewport size). Non-positive values are ignored.
func (*SelectModel) KeyMap ¶
func (m *SelectModel) KeyMap(k KeyMap) *SelectModel
KeyMap overrides the key bindings.
func (*SelectModel) Matcher ¶
func (m *SelectModel) Matcher(fn Matcher) *SelectModel
Matcher overrides the filter-matching function. A nil argument is ignored.
func (*SelectModel) Options ¶
func (m *SelectModel) Options(opts ...string) *SelectModel
Options sets the selectable options (in display order).
func (*SelectModel) Selected ¶
func (m *SelectModel) Selected() (string, bool)
Selected returns the chosen option and true, or ("", false) if the prompt was canceled or nothing matched. Whether a run was canceled is reported by Result.Canceled from Run; this reports the value.
func (*SelectModel) Summary ¶
func (m *SelectModel) Summary() string
Summary is the collapsed line shown after submit: prompt plus chosen value. It returns "" on cancel so nothing is left behind. Implements Summarizer.
func (*SelectModel) SummaryFunc ¶ added in v0.2.0
func (m *SelectModel) SummaryFunc(fn func(selected string) string) *SelectModel
SummaryFunc overrides the collapsed line shown after submit: fn receives the selected option and its result replaces the default summary entirely (an empty result collapses to nothing). Cancel still collapses to nothing.
func (*SelectModel) Theme ¶
func (m *SelectModel) Theme(t *Theme) *SelectModel
Theme overrides the styling. A nil argument is ignored.
func (*SelectModel) Title ¶
func (m *SelectModel) Title(s string) *SelectModel
Title sets the line shown above the options (the question being asked).
func (*SelectModel) Update ¶
func (m *SelectModel) Update(e Event) (Model, Cmd)
Update advances the model in response to one event. It implements Model.
func (*SelectModel) View ¶
func (m *SelectModel) View() string
View renders the current frame: title, optional filter line, the visible window of options with the cursor row marked, and scroll hints. No trailing newline. Line count is fully data-driven so the renderer's redraw accounting stays exact.
func (*SelectModel) Width ¶
func (m *SelectModel) Width(n int) *SelectModel
Width caps each option row to this terminal width (with an ellipsis). Zero disables truncation.
type Summarizer ¶
type Summarizer interface {
Summary() string
}
Summarizer is an optional Model capability: the collapsed line shown after the interaction ends (e.g. "Pick a food: Pizza"). Models that don't implement it collapse to nothing.
type TermDriver ¶
type TermDriver struct {
// contains filtered or unexported fields
}
TermDriver reads raw keystrokes from a terminal and renders frames to it. It implements both EventSource and FrameSink. The escape-sequence accounting lives in inlineRenderer (pure, unit-tested); TermDriver only adds the raw-mode lifecycle and the byte reads, which inherently need a real terminal.
func NewTermDriver ¶
NewTermDriver puts in into raw mode and returns a driver writing to out. It returns ErrNotInteractive if in is not a terminal.
func (*TermDriver) Close ¶
func (d *TermDriver) Close() error
Close restores the terminal. It is safe to call more than once (Run defers it for both the source and the sink role).
func (*TermDriver) Finish ¶
func (d *TermDriver) Finish(final string) error
func (*TermDriver) Next ¶
func (d *TermDriver) Next() (Event, error)
Next returns the next key event, reading and parsing more bytes as needed. A partial escape sequence at the end of a read is retained and completed by the following read.
func (*TermDriver) Render ¶
func (d *TermDriver) Render(frame string) error
type Theme ¶
type Theme struct {
Title *color.Color // prompt / title line
Cursor *color.Color // the "> " pointer on the active row, or the text cursor
Selected *color.Color // the active row's label
Normal *color.Color // inactive rows / typed text (nil = plain)
Filter *color.Color // the typed filter line
Placeholder *color.Color // an input's ghost/hint text shown while empty
ScrollHint *color.Color // "↑/↓ N more" and "(no matches)"
Error *color.Color // an input's validation error line
}
Theme holds the styles applied while rendering. Each field is an amterp/color Color (or nil for "no styling"). Because color.Sprint returns plain text when color is disabled (color.NoColor / NO_COLOR), themed output collapses to clean plain text automatically - which is what makes rendered frames stable in tests with no special handling.
One Theme serves the whole prompt family; a component uses only the fields it renders and ignores the rest (e.g. Placeholder is Input-only; Filter/ScrollHint are used by the list-based prompts).
func DefaultTheme ¶
func DefaultTheme() *Theme
DefaultTheme is a tasteful default: bold title, green cursor/selection, faint filter, placeholder, and scroll hints, red validation errors.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
input
command
Command input is a tiny manual smoke test for radish's text-input prompt.
|
Command input is a tiny manual smoke test for radish's text-input prompt. |
|
multiselect
command
Command multiselect is a tiny manual smoke test for radish's multi-select prompt.
|
Command multiselect is a tiny manual smoke test for radish's multi-select prompt. |
|
pick
command
Command pick is a tiny manual smoke test for radish's single-select prompt.
|
Command pick is a tiny manual smoke test for radish's single-select prompt. |