Documentation
¶
Overview ¶
Package repl is a Bubble Tea REPL component: a prompt line with arrow-key editing, up/down command history, styled output, and a caller-supplied evaluator callback.
The component renders ONLY the input line via View(). Everything else — banner, echoed input, evaluator output, errors — is pushed into the terminal's scrollback via tea.Println. This matches how native REPLs (psql, iex, python) behave: the prompt stays at the bottom, output flows above it, and the terminal handles scroll, selection, and history natively.
m := repl.New(repl.Options{
Prompt: "myapp(teal)> ",
Banner: "hex repl — teal mode. Ctrl+D or \"exit\" to quit.",
Evaluator: func(line string) repl.Result {
return repl.Result{Output: "hi"}
},
})
if _, err := tea.NewProgram(m).Run(); err != nil { ... }
The evaluator runs synchronously inside Update, so slow operations block the render loop — acceptable for the REPL case where users wait on each line anyway.
Index ¶
- type Candidate
- type Completer
- type Evaluator
- type Mode
- type Model
- func (m Model) CurrentMode() string
- func (m Model) Echoes() []string
- func (m Model) History() []string
- func (m Model) InContinuation() bool
- func (m Model) Init() tea.Cmd
- func (m Model) SetHistory(h []string) Model
- func (m Model) SetStyles(s Styles) Model
- func (m Model) Styles() Styles
- func (m Model) Submissions() []string
- func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m Model) View() string
- type Options
- type Result
- type Styles
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Candidate ¶
type Candidate struct {
// Text is the full text that should replace the range from
// PrefixStart to the cursor when this candidate is chosen.
Text string
// Display is an optional label shown in a completion popup.
// v1 doesn't render a popup; Text is used everywhere. Reserved
// for future use.
Display string
// Kind is an optional semantic tag ("function", "table",
// "module", ...). Currently informational only.
Kind string
}
Candidate is a single tab-completion suggestion.
type Completer ¶
Completer produces tab-completion candidates for the given input.
input the full current input line cursorPos the byte position of the cursor within input
Returns the candidates and the byte offset at which the current prefix begins. The REPL replaces input[prefixStart:cursorPos] with the chosen candidate's Text.
Empty candidates means "no completion available here"; the Tab key falls through to whatever textinput does with it (usually nothing, since Tab is not a typing character).
type Evaluator ¶
Evaluator is the callback invoked for every submitted line. Mode carries the name of the active Mode at submission time, letting callers dispatch to different runtimes (e.g. Teal vs Lua) without juggling closures per mode.
type Mode ¶
type Mode struct {
// Name is what gets passed to the Evaluator. Required and
// unique within Options.Modes.
Name string
// Activator is the rune that switches TO this mode when typed
// on an empty prompt. Zero means the mode is not
// user-selectable (e.g. a default that only reachable via
// backspace).
Activator rune
// Prompt is the string rendered before the input line while
// this mode is active, e.g. "myapp(teal)> ".
Prompt string
// ContinuationPrompt is rendered when the previous submission
// returned Result.Incomplete, so the user sees that their input
// is being buffered. When empty, defaults to Prompt — typically
// callers pass a same-width variant that swaps "> " for ". "
// or "... " so column alignment is preserved.
ContinuationPrompt string
// PromptColor, when non-nil, overrides the base Styles.Prompt's
// foreground for this mode. Any nil defers to the base style.
PromptColor lipgloss.TerminalColor
}
Mode describes a REPL mode — a language or command surface the user can switch to. Julia's REPL popularised this pattern with `?` (help), `;` (shell), `]` (pkg); we generalise it: any rune pressed at an empty prompt swaps modes, and backspace at an empty prompt in a non-default mode reverts to the default.
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the bubble tea model for the REPL.
func (Model) CurrentMode ¶
CurrentMode returns the active mode's Name. Useful for tests and callers that want to observe or persist the mode across sessions.
func (Model) Echoes ¶
Echoes returns every line the model would push into the terminal via tea.Println: banner, echoed prompts+input, evaluator output, evaluator errors — in order. Used by tests.
func (Model) History ¶
History returns a copy of the current in-memory command history. Useful for persisting between sessions.
func (Model) InContinuation ¶
InContinuation reports whether the REPL is currently waiting for the user to finish a multi-line input.
func (Model) Init ¶
Init satisfies tea.Model. Emits the banner (if any) into scrollback and starts the cursor blink.
func (Model) SetHistory ¶
SetHistory replaces the in-memory history. Useful for restoring a previous session's log on startup.
func (Model) SetStyles ¶
SetStyles replaces the style set. Return the modified model — Bubble Tea models are value types.
func (Model) Submissions ¶
Submissions returns lines that were submitted to the evaluator (empty lines excluded). Used by tests to assert behaviour without intercepting tea.Cmd streams.
type Options ¶
type Options struct {
// Prompt is the string shown before the input line when Modes
// is empty (single-mode REPL). Defaults to "> ". Ignored when
// Modes is set — each mode carries its own prompt.
Prompt string
// ContinuationPrompt is used in single-mode configurations when
// the previous submission returned Result.Incomplete. Defaults
// to Prompt (so continuation is visually indistinguishable
// unless the caller sets this to something like "... ").
ContinuationPrompt string
// Completer, when non-nil, is called on Tab to compute
// completions for the current input line. See Completer's
// godoc for the contract.
Completer Completer
// Banner is optional multi-line text printed above the first
// prompt. Newlines are respected.
Banner string
// Evaluator is called for each submitted line. Required.
Evaluator Evaluator
// Modes are the switchable modes. The first mode is the
// default; users switch to another mode by typing its
// Activator rune on an empty prompt, and return to the default
// by pressing Backspace on an empty prompt.
//
// Empty means single-mode: the evaluator sees mode="" and
// Prompt/Banner behave as before.
Modes []Mode
// HistoryLimit caps the in-memory command history. 0 or
// negative means unlimited.
HistoryLimit int
}
Options configures a new Model.
type Result ¶
type Result struct {
// Output is normal (stdout-like) content, rendered in the
// default style.
Output string
// Err is error-like content, rendered in the error style
// (a subdued red by default).
Err string
// Exit requests the REPL loop to terminate cleanly.
Exit bool
// Incomplete signals that the submitted input is syntactically
// incomplete — e.g. an unclosed function block or table literal.
// The REPL switches to a continuation prompt and buffers the
// user's next line onto the current one instead of evaluating.
// Output and Err are ignored when Incomplete is true.
Incomplete bool
}
Result is what the evaluator returns for one submitted line.
type Styles ¶
type Styles struct {
Prompt lipgloss.Style
Input lipgloss.Style
Output lipgloss.Style
Error lipgloss.Style
Banner lipgloss.Style
}
Styles groups the lipgloss styles the component uses.
func DefaultStyles ¶
func DefaultStyles() Styles
DefaultStyles returns hex's default palette, tuned for readability against both light and dark terminals via AdaptiveColor.
Prompt: a calm cyan-blue (bold), matching the charm accent line. Error: a muted red (not the alarming bright red). Banner: dim gray.