Developer API
The public surface of D.A.B.T, one page per module - each mirrors a lib/ topic directory, the way a Javadoc package-summary page mirrors a Java package. Use the search in the header (or press /) to find a function by name across every page at once; it’s pre-scoped to “This section” when you’re already inside api/, with an “Everywhere” toggle to search the whole site. For how the pieces fit together see the documentation index.
| Module | Covers | Mirrors |
|---|---|---|
| Core | Lifecycle, layout (panes), tabs, factory widgets, content/output, tui.exec, live updates, getters, logging/perf, event & result variables |
lib/tui.sh, lib/tui_api.sh, lib/state.sh |
| Style | Themes | lib/style/ |
| Input | Key/mouse bindings, built-in actions | lib/input/ |
| Widgets | Widget constructors, richer widgets & text editing | lib/widgets/ |
| Chrome | Command palette, modal/overlay, dialogs & toasts, footer | lib/chrome/ |
| Markup | Pages & cache | lib/markup/ |
| Config | Persisted settings | lib/config/ |
| Plugins | Plugins & hooks | lib/plugin/ |
| Renderers | Standalone box/table/chart/banner renderers | lib/terminal_renderer.sh |
| Terminal controls | ~310 escape-sequence helpers (generated) | lib/terminal_controls.sh |
| this page | Task-oriented tour with examples, below |
Rules of the road: call only public functions (tui.*, renderers, cur.*/mode.*/…); never _tui.*, _exec_*, _tr_* or any leading-underscore name. Callbacks are plain bash functions that receive the widget id (action="on_save" → on_save btn_save).
1. Start an app
#!/usr/bin/env bash
TUI_APP_NAME=my_app # config namespace (~/.config/my_app/)
source /path/to/lib/tui.sh
tui.cmd.load "$APP/commands.xml" # optional: your commands in the command bar
tui.start "$APP/config/home.xml" # init + load + run + cleanup
tui.start_cached does the same after pre-warming every sibling page. Pages, includes and callbacks: ../guide/markup.md. → reference: Lifecycle.
2. Build layout in code (instead of, or next to, XML)
tui.hsplit root nav:1 main:3
tui.vsplit main top:2 bottom:1
tui.pane_title main "Dashboard"; tui.pane_border main double; tui.pane_pad main 1 1
tui.grid bottom 1 3 pack "" "" a b c # 1 row × 3 cols
tui.fixed keys 6 3 esc f1 f2 space:4 # every child 6×3 cells, space is 4 units wide
XML equivalents and the grid/tab details: ../guide/grid-layouts-and-tabs.md. → Layout.
3. Widgets and forms
tui.label lbl_name form 0 "Name"
tui.input inp_name form 1 "type here" "Name:" on_name_submit
tui.checkbox chk_a form 2 "Enable" 1 on_toggle # on_toggle chk_a 0|1
tui.button btn_go form 3 "[ Save ]" on_save
on_save() {
local name; name="$(tui.get inp_name)"
tui.set_label btn_go "[ Saved: $name ]"
}
Inputs keep focus after Enter by default (tui.input.retain ID false to drop it). Use tui.update ID VALUE to change a value and redraw. Runtime-built forms: tui.factory.* (tui.factory.grid demo grid_pane 6 3; tui.factory.button demo "$_TUI_FACTORY_LAST_ID"..., then tui.factory.clear demo). → Widgets, Factory, Tabs.
Text editing and data widgets
tui.textarea notes editor 0 "notes..." 0 # multi-line, fills its pane; click, drag-select, ctrl+arrows, cut/paste, undo
tui.on_change notes mark_dirty # after every edit
tui.password pw form 1 "password" "Pass:" do_login
tui.list files side 0 open_file 8; tui.list.set files a.txt b.txt c.txt
tui.table t data 0 "" 0; tui.table.set t "Name|Size" "a.txt|1k" "b.txt|2k"
tui.select mode form 3 "Mode:" mode_changed; tui.select.set mode fast balanced careful
tui.progress job form 5 "Job:"; tui.progress.set job 40
Key tables, mouse behaviour and the Markdown roadmap: ../guide/widgets.md. -> Richer widgets.
4. Put content in panes
tui.output log "line one" "line two" # replace
tui.output_append log "another line" # append
some_command | tui.output log # from stdin
tui.output stats "$(table_string 'A|B' '1|2')" # renderer output is just text with ANSI
tui.pane_scroll log v # wheel / j k / drag scrollbar
For anything updated in a loop use tui.set_text PANE TEXT (fork-free, redraws only on change). Long-running processes: tui.exec "ping -c3 host" out_pane ctl_pane streams live through a PTY; several can share a pane. Scrolling internals: ../design/viewport-scrolling.md, viewport tips: ../guide/callbacks-and-viewports.md. → Content, tui.exec.
5. Live, continuously updating things
tui.clock hdr_clock "%H:%M:%S" seg3 # big live clock
tui.every 2 refresh_stats # refresh_stats stats_id, every 2 s
tui.watch out "df -h /" 5 # run off-thread, show stdout
tui.monitor mon_pane 1 # CPU/MEM/SWAP/load dashboard
refresh_stats() {
tui.sys.cpu; tui.sys.mem
tui.set_text stats "CPU ${TUI_SYS_CPU}% MEM ${TUI_SYS_MEM_PCT}%"
}
Timers share one tick listener, cost no fork per update and are cleared on page change. Custom per-frame work: tui.tick.add my_fn (never overwrite _TUI_TICK_FN). → Live updates.
6. Read state
read -r rows cols <<< "$(tui.get.dimensions content_pane --content)"
tui.get.dimensions -c # terminal columns
tui.get.focused; tui.get.hovered pane; tui.get.scroll log
tui.get.class.style brand fg # theme value without a pane
Inside a handler TUI_EVENT_KEY, TUI_EVENT_X/Y, TUI_EVENT_PANE, TUI_EVENT_WIDGET describe the event. → Getters, Variables.
7. Style and themes
/* theme.css */
.nav_link { fg: cyan; }
.nav_link:focus { fg: BLACK; bg: #61afef; mods: bold; }
tui.class btn_go nav_link # or class="nav_link" in XML
tui.theme.set "$APP/themes/ocean.css" # app-wide overlay over every page's own theme
tui.class.sgr nav_link focus; printf '%s text\e[0m' "$TUI_SGR"
Reference of selectors and properties: ../guide/markup.md#styling. → Styling and themes.
8. Keys, mouse, actions
tui.bind ctrl+e on_export --desc "Export" # global
tui.bind mouse:right on_ctx --pane output # only in that pane
tui.bind ctrl+s on_save --always # fires even while typing in an input
tui.defaults.off wheel # opt out of a default group (whole app)
tui.keys.suspend_key ctrl+g # change the kill-switch key
tui.bind.save # persist user (--user) binds
Default bindings live in share/defaults/keybinds.xml, grouped and opt-out. Full model (lookup order, --pass, repeat coalescing, pass-through mode, paste): ../guide/input-bindings.md. → Input, Actions.
9. Command bar, modals, dialogs, footer
tui.cmd.add export "Export report" on_export --group App --desc "Write report.csv" --key ctrl+e
tui.cmd.provider my_page_commands # my_page_commands calls tui.cmd.add each time the palette opens
# a modal: draw fn + key fn
my_draw() { tui.overlay.box 5 10 40 "1;97;44" "Confirm" "Delete file?" "[y] yes [n] no"; }
my_keys() { case "$1" in y) do_delete; tui.modal.close ;; n|esc) tui.modal.close ;; esac; }
tui.modal.open confirm my_keys my_draw
<footer items="@tui.action.quit|Quit;@tui.palette.open|Command bar;ctrl+s|Save"/>
@ACTION items show whichever key is currently bound to the action. Defaults and the shipped Settings/Keybinds pages: ../guide/input-bindings.md. → Commands, Modal, Footer.
Dialogs and toasts
tui.confirm "Delete report.csv?" do_delete --danger --yes Delete --no Keep # do_delete runs only on Yes
tui.prompt "New name:" do_rename --value "$old" --validate name_ok # do_rename NEWNAME
tui.choose "Export as" do_export csv json yaml # do_export INDEX ITEM
tui.notify "Report saved" success # toast, gone after 5 s
name_ok() { [[ -n "$1" && "$1" != */* ]] || { TUI_DIALOG_ERROR="no slashes, not empty"; return 1; }; }
do_rename() { mv "$old" "$1" && tui.notify "Renamed to $1" success || tui.notify "Rename failed" error 6; }
Dialogs never block: they return at once and call your function afterwards, so a callback can open the next dialog (prompt then confirm). tui.config.set confirm.quit 1 makes every quit ask first. → Dialogs and notifications.
10. Pages, history, persisted settings
tui.goto "$APP/config/settings.xml" # switch page (history kept)
tui.action.back # previous page
tui.config.set my.option on # ~/.config/my_app/dabt.conf
tui.config.get my.option off # with default
tui.action.goto_default settings # DABT's shipped Settings page (also in the palette)
Pages are recorded and replayed from a cache keyed on file mtimes (page + includes); why and how: ../design/write-ahead-logging-and-replay.md. → Pages and cache, Config.
11. Plugins
tui.plugin.list # what was detected
tui.plugin.enable hello # sources ~/.config/DABT/plugins/hello.plugin.sh and runs plugin.hello.on_enable
tui.plugin.disable hello # its commands, keys, hooks and timers are removed again
tui.hook.on page my_page_hook # react to every page switch
A plugin file, where DABT keeps its files, hooks and the built-in terminal_shortcuts plugin: ../guide/plugins.md. -> Plugins.
12. Renderers without the TUI
source lib/terminal_renderer.sh gives you box, table, linechart, banner… in any script. See renderers.md and examples/csv-charts/.
