D.A.B.Tv0.0.17 Tutorial API DABT Tools ↗ GitHub ↗

Plugins & hooks

lib/plugin/tui_plugin.sh, lib/tui_home.sh - discovering, installing, enabling/disabling and reloading plugins, the hook system they use to extend the framework, and the per-app metadata file. Guide: ../guide/plugins.md. ← API index for the full module list and a task-oriented tour with examples.

Files live under ~/.config/DABT/ (TUI_HOME): plugins/ (TUI_PLUGINS_DIR) and apps/<TUI_APP_NAME>/ (TUI_APP_CONF: dabt.conf, keybinds.xml, settings.conf, app.meta, logs/). A plugin is a NAME.plugin.sh file or a NAME/plugin.sh folder; it defines plugin.NAME.on_enable, and optionally on_disable and on_remove. Plugins are trusted code: they run in the app’s shell with its permissions. Functions return 0 unless their entry says otherwise.

Plugins

Function Summary
tui.plugin.scan Discovers plugins (NAME.plugin.sh files and NAME/plugin.sh folders) and registers them, disabled.
tui.plugin.dir_add Adds a folder for tui.plugin.scan to search. Adding a folder twice is a no-op.
tui.plugin.add Registers one plugin file or folder, disabled.
tui.plugin.install Security-scans a plugin, copies it into ~/.config/DABT/plugins and registers it, disabled.
tui.plugin.remove Disables a plugin, runs its plugin.NAME.on_remove, unregisters it and forgets its saved state.
tui.plugin.enable Enables a plugin: enables its requirements first, sources its file and runs plugin.NAME.on_enable.
tui.plugin.disable Disables a plugin: disables plugins that require it first, runs plugin.NAME.on_disable, then undoes everything it registered, newest first.
tui.plugin.toggle Disables an enabled plugin, or enables any other. The choice is saved.
tui.plugin.reload Re-reads a plugin after its file changed: disables it, drops its plugin.NAME.* functions, re-reads the metadata, and enables it again if it was enabled. Returns 1 for an unknown plugin.
tui.plugin.startup Scans for plugins (once) and enables each one whose saved state, or # default: when never set, is on. Called by tui.init.
tui.plugin.list Prints every registered plugin in discovery order.
tui.plugin.info Prints a readable description: title, version, description, id, state (with the error), source, file, author and requirements. Returns 1 for an unknown plugin.
tui.plugin.get Prints one field of a plugin: title, version, description, author, requires, state, source, file or error. Returns 1 for any other field.
tui.plugin.enabled Returns 0 when the plugin is enabled, else 1.
tui.plugin.root Prints the plugin folder for a folder plugin, or the file for a single-file plugin. Returns 1 for an unknown plugin.
tui.plugin.dir Prints the folder that contains the plugin file. Use it to find assets shipped next to the plugin. Returns 1 for an unknown plugin.
tui.plugin.files Prints every file of the plugin, one per line (recursive for a folder plugin). Returns 1 for an unknown plugin.
tui.plugin.stats Prints size figures and what the plugin currently has registered.
tui.plugin.config Reads or writes a plugin’s own saved setting, stored as plugin.NAME.KEY in dabt.conf.
tui.plugin.own Adds something to what disabling the current plugin undoes. Only has an effect while a plugin is being enabled.

tui.plugin.scan

tui.plugin.scan

Discovers plugins (NAME.plugin.sh files and NAME/plugin.sh folders) and registers them, disabled.

Notes

  • Folders, in order: ~/.config/DABT/plugins (TUI_PLUGINS_DIR), the app’s plugins/, share/plugins (when DABT is not installed), then each folder in TUI_PLUGIN_DIRS (colon-separated). Add more with tui.plugin.dir_add first.
  • When two folders hold a plugin of the same name, the first one wins; the other fails to register.
  • tui.init runs it through tui.plugin.startup.

tui.plugin.dir_add

tui.plugin.dir_add DIR

Adds a folder for tui.plugin.scan to search. Adding a folder twice is a no-op.

Notes

  • Adding a folder before the first scan replaces the default folder list; add the defaults yourself if you still want them.

tui.plugin.add

tui.plugin.add PATH [SOURCE]

Registers one plugin file or folder, disabled.

Parameters

  • PATH: a NAME.plugin.sh file or a folder containing plugin.sh.
  • SOURCE: builtin, app or user (default), shown in lists.

Returns: 1 when the file can’t be read or another plugin already has the name.

Sets: TUI_PLUGIN_NAME on success, TUI_PLUGIN_ERROR on failure.

Notes

  • Reads only the metadata comments in the first 40 lines (# plugin:, # title:, # version:, # description:, # author:, # requires:, # default: on|off). The file is sourced only when enabled.
  • The name is lowercased, with characters other than a-z 0-9 _ turned into _.

tui.plugin.install

tui.plugin.install PATH [--force] [--strict] [--no-scan]

Security-scans a plugin, copies it into ~/.config/DABT/plugins and registers it, disabled.

Options

  • --force: replace an installed plugin of the same name; with --strict, install despite high-risk findings.
  • --strict: refuse when the scan finds high-risk issues.
  • --no-scan: skip the scan.

Returns: 1 on failure, with the reason in TUI_PLUGIN_ERROR.

Sets: TUI_PLUGIN_WARNING to a one-line scan summary when there were findings; the full report is in TUI_SCAN_REPORT.

Notes

  • Plugins run in the app’s shell with its permissions. The scan flags risky patterns; it is not a sandbox.

See also: tui.scan.run

tui.plugin.remove

tui.plugin.remove NAME

Disables a plugin, runs its plugin.NAME.on_remove, unregisters it and forgets its saved state.

Returns: 1 for an unknown plugin.

Notes

  • Files are deleted only for user plugins inside ~/.config/DABT/plugins. Built-in and app plugins are only unregistered and come back on the next scan.

tui.plugin.enable

tui.plugin.enable NAME [--no-save]

Enables a plugin: enables its requirements first, sources its file and runs plugin.NAME.on_enable.

Returns: 1 when the plugin is unknown, a requirement fails, the requirements are circular, or sourcing or on_enable fails. The reason is in TUI_PLUGIN_ERROR.

Notes

  • Commands, bindings, hooks, timers, tick listeners, overlays and palette providers registered while it loads are recorded, so disabling undoes them.
  • The state is saved as config plugin.NAME.enabled=1 unless --no-save is given.
  • Fires the plugin_enabled hook.
  • On failure, what the plugin registered so far is undone and its state becomes error.

tui.plugin.disable

tui.plugin.disable NAME [--no-save]

Disables a plugin: disables plugins that require it first, runs plugin.NAME.on_disable, then undoes everything it registered, newest first.

Returns: 1 for an unknown plugin.

Notes

  • The state is saved as plugin.NAME.enabled=0 unless --no-save is given.
  • Its functions stay defined until it is removed or reloaded.
  • Fires the plugin_disabled hook.

tui.plugin.toggle

tui.plugin.toggle NAME

Disables an enabled plugin, or enables any other. The choice is saved.

tui.plugin.reload

tui.plugin.reload NAME

Re-reads a plugin after its file changed: disables it, drops its plugin.NAME.* functions, re-reads the metadata, and enables it again if it was enabled. Returns 1 for an unknown plugin.

Notes

  • The saved state is not changed.

tui.plugin.startup

tui.plugin.startup

Scans for plugins (once) and enables each one whose saved state, or # default: when never set, is on. Called by tui.init.

Notes

  • Set TUI_NO_PLUGINS=1 to skip plugins entirely.
  • A plugin that fails prints plugin NAME: REASON on stderr and stays disabled.

tui.plugin.list

tui.plugin.list

Prints every registered plugin in discovery order.

Output: NAME<TAB>STATE<TAB>VERSION<TAB>SOURCE<TAB>TITLE. STATE is enabled, disabled or error; SOURCE is builtin, app or user.

tui.plugin.info

tui.plugin.info NAME

Prints a readable description: title, version, description, id, state (with the error), source, file, author and requirements. Returns 1 for an unknown plugin.

tui.plugin.get

tui.plugin.get NAME FIELD

Prints one field of a plugin: title, version, description, author, requires, state, source, file or error. Returns 1 for any other field.

tui.plugin.enabled

tui.plugin.enabled NAME

Returns 0 when the plugin is enabled, else 1.

tui.plugin.root

tui.plugin.root NAME

Prints the plugin folder for a folder plugin, or the file for a single-file plugin. Returns 1 for an unknown plugin.

tui.plugin.dir

tui.plugin.dir NAME

Prints the folder that contains the plugin file. Use it to find assets shipped next to the plugin. Returns 1 for an unknown plugin.

tui.plugin.files

tui.plugin.files NAME

Prints every file of the plugin, one per line (recursive for a folder plugin). Returns 1 for an unknown plugin.

tui.plugin.stats

tui.plugin.stats NAME

Prints size figures and what the plugin currently has registered.

Output: key=value lines: files, dirs, bytes, lines, functions, commands, binds, hooks, timers, ticks, overlays, providers.

Returns: 1 for an unknown plugin.

tui.plugin.config

tui.plugin.config NAME KEY [VALUE]

Reads or writes a plugin’s own saved setting, stored as plugin.NAME.KEY in dabt.conf.

Notes

  • With VALUE: saves it. Without: prints the stored value (no newline).
  • To read with a default, use tui.config.get plugin.NAME.KEY DEFAULT; the third argument here always means “set”.

Example

interval=$(tui.plugin.config clock interval); interval=${interval:-5}
tui.plugin.config clock interval 10

tui.plugin.own

tui.plugin.own TYPE VALUE

Adds something to what disabling the current plugin undoes. Only has an effect while a plugin is being enabled.

Parameters

  • TYPE: cmd (command id), bind (key spec, plus --pane ID), hook (EVENT FN), every (timer id), tick (function), overlay (draw function), provider (function), or run (shell code that is evaled on disable).

Notes

  • Registrations made through the regular tui.* calls are recorded automatically; use this for things they don’t cover.

Example

plugin.myplug.on_enable() {
    stty -ixon
    tui.plugin.own run "stty ixon"
}

Hooks

Function Summary
tui.hook.on Registers FN to run when the framework fires EVENT.
tui.hook.off Removes a hook handler.
tui.hook.fire Calls every handler of EVENT with the arguments. Returns 0 when at least one handler returned 0, else 1.

tui.hook.on

tui.hook.on EVENT FN

Registers FN to run when the framework fires EVENT.

Events

  • init (after tui.init), ready (before the first frame), page FILE (after every page switch), resize ROWS COLS, quit (tui.stop), exit (terminal being restored: give back terminal settings and files here), plugin_enabled NAME, plugin_disabled NAME.
  • key NAME: before bindings; a handler that returns 0 consumes the key.

Notes

  • Adding the same FN twice for one event is a no-op. Handlers run in registration order.
  • Available to apps too, not only plugins.

Example

on_page() { tui.log "visited $1"; }
tui.hook.on page on_page

tui.hook.off

tui.hook.off EVENT FN

Removes a hook handler.

tui.hook.fire

tui.hook.fire EVENT [ARG...]

Calls every handler of EVENT with the arguments. Returns 0 when at least one handler returned 0, else 1.

Notes

  • Handlers whose function no longer exists are skipped.
  • Apps may fire their own events for their plugins.

App metadata

Function Summary
tui.app.meta_get Prints a value from the app’s app.meta (no newline), or DEFAULT.
tui.app.meta_set Stores a key in the app’s app.meta and writes the file.
tui.app.dir Prints the app’s config folder, TUI_APP_CONF (~/.config/DABT/apps/<TUI_APP_NAME>).

tui.app.meta_get

tui.app.meta_get KEY [DEFAULT]

Prints a value from the app’s app.meta (no newline), or DEFAULT.

Notes

  • Keys written by tui.init: name, title, description, dabt_version, app_dir, entry, first_run, last_run, runs.

tui.app.meta_set

tui.app.meta_set KEY VALUE

Stores a key in the app’s app.meta and writes the file.

tui.app.dir

tui.app.dir

Prints the app’s config folder, TUI_APP_CONF (~/.config/DABT/apps/<TUI_APP_NAME>).