Skip to content

smelt.dialog

Tier: Host — Available in every runtime, including headless mode.

Modal overlay builders. Compose a dialog from one or more panels of smelt.dialog.content(...) leaves, then call smelt.dialog.open(...) to push it; convenience entry points (smelt.dialog.input, .options, .list, .picker, .markdown) wrap the common shapes. UiHost-only.

smelt.dialog.content

fun(opts: table?): smelt.win.Win, smelt.buf.Buf

Types: smelt.win.Win, smelt.buf.Buf

General-purpose body leaf. Pass opts.buf to wrap an existing buffer or opts.text to spin up a fresh read-only one. opts.interactive enables focus + vim keymaps (when the user has vim mode on); opts.wrap mirrors smelt.win.new. Returns (leaf, buf).

smelt.dialog.current

fun(): table | nil

Return the topmost active dialog ctx (the same shape passed to on_submit/keymap handlers: { resolve, close, win, panels, focused_leaf }), or nil if no dialog is open. Use it inside leaf:key(...) callbacks — those normally lack a path to the dialog's resolve handle.

smelt.dialog.input

fun(placeholder: string?, opts: table?): smelt.win.Win, smelt.buf.Buf

Types: smelt.win.Win, smelt.buf.Buf

Build a single-line text-input leaf with a fresh buffer. placeholder shows when the buffer is empty; opts.pad_left / opts.pad_right override the dialog gutter. Returns (leaf, buf) so the caller can read the entered text via buf:source() from the dialog keymaps.

smelt.dialog.list

fun(buf: smelt.buf.Buf, opts: table?): smelt.win.Win

Types: smelt.buf.Buf, smelt.win.Win

Wrap an existing buf as a selectable list leaf. Use when the buffer contents need to be mutated live (vs. the snapshot supplied to smelt.dialog.menu). opts.focusable defaults true; opts.selected (0-based) sets the initial cursor row.

smelt.dialog.markdown

fun(text: string): smelt.win.Win, smelt.buf.Buf

Types: smelt.win.Win, smelt.buf.Buf

Render text as a non-focusable markdown leaf. Convenience wrapper around smelt.dialog.content for static narrative panels (notes, summaries, intros). Returns (leaf, buf).

smelt.dialog.menu

fun(items: (string|smelt.dialog.MenuItem)[], opts: smelt.dialog.MenuOpts?): smelt.win.Win, table

Types: smelt.dialog.MenuItem, smelt.dialog.MenuOpts, smelt.win.Win

smelt.dialog.open

fun(opts: smelt.dialog.Opts): any

Types: smelt.dialog.Opts

Coroutine-blocking dialog opener. Builds the overlay from opts.panels (each { leaf, height }), wires opts.keymaps, then yields the caller until a handler calls ctx.resolve(value). Must run inside a smelt.spawn (or tool execute) frame; returns the resolved value or nil on dismiss.

smelt.dialog.open_handle

fun(opts: smelt.dialog.Opts): table

Types: smelt.dialog.Opts

Non-coroutine open. Returns { win, panels, close() } synchronously. The consumer drives the lifecycle via on_submit / on_dismiss callbacks and tears down with handle:close(). No value flows back — use smelt.dialog.open when you need to read the result.

smelt.dialog.picker

fun(opts: smelt.dialog.PickerOpts): any

Types: smelt.dialog.PickerOpts

Coroutine-blocking Telescope-style picker. Stacks a single-line input on top of a list driven by smelt.list.new; navigation forwards from input to list, Enter resolves with the selected item. See the doc block above NAV_KEYS for every accepted opts field. Returns the value resolved from on_submit (defaults to the highlighted item) or nil on dismiss.