Documentation
¶
Overview ¶
Package repl provides an interactive Read-Eval-Print Loop for Teal and Lua sources, wired to a caller-provided *lua.Environment.
The framework's `hex repl` CLI uses this against a bare environment. Scaffolded applications use it against their own container's shared environment, so every Lua module registered by framework providers (db, config, cache, log, events, queue, env, ai/agent, ...) and by consumer providers (domain services) is available at the prompt — the Tinker / Rails console / Phoenix IEx pattern for hex apps.
Teal mode uses a persistent tl.init_env so declarations on one line remain visible on subsequent lines (see hex/lua/teal.Session). Locals still die with their chunk (standard Lua semantics); use `global x: T = v` to declare persistent Teal variables.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Completer ¶
func Completer(env *hexlua.Environment) tuirepl.Completer
Completer returns a tuirepl.Completer that inspects the Lua state's globals table to enumerate candidates. Called on every Tab key press in the interactive REPL.
Recognised contexts (walked backwards from the cursor):
pri<TAB> bare identifier prefix "pri" \u2192 all globals
starting with "pri" (print, primary_db, ...)
db.q<TAB> member access: get _G.db, list keys starting
with "q" (query, queryOne).
obj.a.b<TAB> chained access: walk _G.obj.a, list keys.
Only string keys on the receiver table are candidates. Numeric keys, metatables, and special __index values are ignored (v1).
Exported so embedders of tui/components/repl.Model (e.g. an app's own Bubble Tea dashboard wanting the same completion the CLI REPL gets) can wire it up without reimplementing globals/member introspection.
func Eval ¶
func Eval(env *hexlua.Environment, mode Mode, line string) (output string, incomplete bool, err error)
Eval evaluates one line against env in mode, for hosts embedding a console — a TUI pane, a socket endpoint — without Run's interactive loop. Lua print() output and expression results (tables rendered via the same tabulate grid the REPL uses) land in output, in order. incomplete reports syntactically unfinished input (an unclosed block, paren, or table) that the host should buffer and resubmit joined with the next line; output and err are empty in that case. Errors come back trimmed of gopher-lua's stack traceback, one-liner style, matching the interactive loop.
Teal evaluates sessionless — declarations do not persist across lines. Hosts wanting Run-equivalent cross-line persistence use NewConsole instead.
func Run ¶
Run executes the read-eval-print loop with the given options and blocks until the user exits (Ctrl+D, "exit", "quit", ".exit", or ".quit") or an unrecoverable I/O error occurs.
Run does not close a caller-provided Env — that's the caller's responsibility, since the same env typically outlives many REPL sessions (or in the framework case, the whole app process).
Types ¶
type Console ¶
type Console struct {
// contains filtered or unexported fields
}
Console is a persistent embedded evaluation session: Eval with the same cross-line state Run's interactive loop keeps. Fennel and Lua persistence comes from the shared environment itself (globals survive, chunk-locals die — standard Lua semantics, identical to Run); Teal additionally gets a persistent tl session, with the environment's registered type stubs propagated and each typed module pre-declared as a global, exactly as Run sets up.
Close releases the Teal session. The environment is the caller's — Console never closes it.
func NewConsole ¶
func NewConsole(env *hexlua.Environment, mode Mode) (*Console, error)
NewConsole builds a Console over env in mode. Teal mode loads the tl compiler and mints the persistent session up front; Fennel and Lua need no extra state.
type Mode ¶
type Mode int
Mode selects the language the REPL evaluates.
const ( // ModeTeal evaluates input as Teal by default. This is the // framework default — Teal's type-checker catches typos and // mistakes in interactive sessions, and Teal source falls // through to Lua for expressions that don't need typing. ModeTeal Mode = iota // ModeLua evaluates input as plain Lua. Looser semantics; no // type-checker; implicit globals allowed. Prefer for quick // prototyping when Teal's strictness gets in the way. ModeLua // ModeFennel evaluates input as Fennel — the Lisp-flavoured Lua // dialect. Balanced parens, macros, no static type layer. ModeFennel )
type Options ¶
type Options struct {
// Mode selects Teal (default) or Lua.
Mode Mode
// In, Out, ErrOut are the REPL's I/O streams. Any zero value
// falls back to the process's os.Stdin/os.Stdout/os.Stderr via
// the caller; the package does not open OS fds on its own.
In io.Reader
Out io.Writer
ErrOut io.Writer
// AppName appears in the prompt: "<AppName>(teal)> ". Defaults
// to "hex". Set to your app's binary name (e.g. "myapp") for the
// scaffolded app REPL.
AppName string
// Banner is an optional extra line printed after the standard
// banner. Callers can use it to warn about the current
// environment ("connected to PRODUCTION") or advertise available
// modules.
Banner string
// Env, if non-nil, is the hex/lua.Environment the REPL should
// evaluate against. When nil, Run creates a bare environment.
// The framework CLI (`hex repl`) passes nil; app-scoped REPLs
// pass the container's shared environment so registered modules
// are available.
Env *hexlua.Environment
// Interactive selects between the two REPL loops:
//
// false (default) — bufio.Scanner over In/Out/ErrOut. No
// terminal features; suitable for pipes, tests, and any
// non-TTY caller.
//
// true — Bubble Tea program via hex/tui/components/repl,
// giving arrow-key editing, command history, styled
// output, and a scrollable viewport. Requires a real TTY;
// the caller is responsible for detecting one (typically
// via golang.org/x/term or mattn/go-isatty on os.Stdin).
Interactive bool
}
Options configures a REPL run.