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

Input: keys, mouse & actions

lib/input/tui_input.sh - key/mouse binding tables, dispatch, defaults, pass-through, and the built-in actions bindable from tui.bind, <bind action="…">, <button action="…"> or tui.cmd.add. Guide: ../guide/input-bindings.md. ← API index for the full module list and a task-oriented tour with examples.

Every key and mouse event is decoded into a name (ctrl+s, pgdn, wheel:up, mouse:right, paste) and looked up in three tables: user bindings (--user, saved per app), code bindings (your app and markup), and the defaults from share/defaults/keybinds.xml, grouped so whole groups can be switched off. Handlers read the event from the TUI_EVENT_* variables (Core). Functions return 0 unless their entry says otherwise.

Input and bindings

Function Summary
tui.bind Binds a key or mouse event to a command.
tui.unbind Removes a code binding, or with --user a user binding. The default for KEY applies again.
tui.bind.reset Removes every code binding, or with --user every user binding. Defaults are not affected.
tui.bind.list Prints every binding: user, then code, then defaults.
tui.bind.table Builds the same rows as tui.bind.list as an aligned, framed text table in the variable _TBL.
tui.bind.defaults Reloads the default bindings, replacing the current defaults.
tui.defaults.off Switches groups of default bindings off.
tui.defaults.on Switches default groups back on, both the app-wide and the page-only setting.
tui.defaults.list Prints each default group, sorted, as GROUP<TAB>on\|off<TAB>KEYS.

tui.bind

tui.bind KEY COMMAND [--pane ID] [--pass] [--always] [--page] [--user] [--desc TEXT]

Binds a key or mouse event to a command.

Parameters

  • KEY: a key name such as a, Q, ctrl+s, alt+enter, shift+tab, f5, pgdn, or a mouse name such as mouse:right, wheel:down, drag:left. Names are case-insensitive except single letters (Q is shift+q).
  • COMMAND: a function name with optional arguments, e.g. "tui.action.scroll down 10". Several commands can be chained with ;.

Options

  • --pane ID: only when ID is the event’s pane: the focused widget’s pane for keys, the pane under the pointer for mouse events.
  • --pass: after this command, keep going down the lookup order, so the default still runs too.
  • --always: also fire while a text widget has focus and would otherwise take the key.
  • --page: removed on the next page change. <bind> in markup uses this.
  • --user: a binding made by the person using the app. It beats code bindings and is saved with tui.bind.save.
  • --desc TEXT: description shown in binding lists and the Keybinds page.

Returns: 1 when KEY or COMMAND is missing.

Notes

  • Lookup order per event: pane-scoped user, pane-scoped code, global user, global code, then the built-in default. The first match stops the search unless it was bound with --pass.
  • COMMAND is split on ; and spaces, not evaluated: arguments can’t contain spaces or quotes. Wrap anything more complex in a function.
  • A command that is not defined when the key is pressed is skipped; the reason is left in TUI_LAST_BIND_ERROR.
  • Binding the same KEY (and pane) again replaces the command and its flags.
  • Unknown flags are ignored.
  • Bindings made while a plugin loads are removed when that plugin is disabled.

Example

tui.bind ctrl+e on_export --desc "Export"
tui.bind mouse:right on_ctx --pane output
tui.bind ctrl+s on_save --always
tui.bind q "log_quit; tui.action.quit"

See also: tui.unbind, tui.defaults.off, ../guide/input-bindings.md

tui.unbind

tui.unbind KEY [--pane ID] [--user]

Removes a code binding, or with --user a user binding. The default for KEY applies again.

Notes

  • --pane must match the scope the binding was made with.
  • Default bindings can’t be unbound one by one; switch their group off with tui.defaults.off or bind the key to something else.

tui.bind.reset

tui.bind.reset [--user]

Removes every code binding, or with --user every user binding. Defaults are not affected.

tui.bind.list

tui.bind.list

Prints every binding: user, then code, then defaults.

Output: one line per binding, SCOPE<TAB>KEY<TAB>COMMAND<TAB>NOTE. SCOPE is global, pane:ID or default. NOTE holds the description and markers such as (yours), (unsaved), (pass), (page), (overridden), (off).

tui.bind.table

tui.bind.table

Builds the same rows as tui.bind.list as an aligned, framed text table in the variable _TBL.

Notes

  • Fork-free; show it with tui.output PANE "$_TBL".

tui.bind.defaults

tui.bind.defaults [FILE]

Reloads the default bindings, replacing the current defaults.

Parameters

  • FILE: default $TUI_DEFAULTS_DIR/keybinds.xml: ~/.config/DABT/defaults/keybinds.xml when installed, else share/defaults/keybinds.xml.

Returns: 1 when FILE can’t be read; the app then has no defaults.

Notes

  • One <bind key="…" action="…" group="…" [desc="…"] [always="true"]/> per line. Bindings without group go into misc.

tui.defaults.off

tui.defaults.off GROUP... [--page]

Switches groups of default bindings off.

Parameters

  • GROUP: click, focus, help, pages, palette, pane, paste, quit, scroll, wheel (see tui.defaults.list).
  • --page: only until the page changes. <tui defaults="-quit,-scroll"> does this.

Notes

  • Without --page it lasts for the run. To persist it, set the defaults.off config key.

Example

tui.defaults.off quit          # this app handles q itself

tui.defaults.on

tui.defaults.on GROUP...

Switches default groups back on, both the app-wide and the page-only setting.

tui.defaults.list

tui.defaults.list

Prints each default group, sorted, as GROUP<TAB>on|off<TAB>KEYS.

Saved user bindings

Function Summary
tui.bind.save Writes the user bindings (--user) to disk; they load automatically on the next start.
tui.bind.load Replaces the user bindings with those in FILE (default: the saved file) and marks them saved.
tui.bind.discard Drops unsaved changes to the user bindings by reloading the saved file.
tui.bind.dirty Returns 0 while the user bindings differ from the saved file, else 1.
tui.bind.saved_file Prints the path of the saved user bindings (TUI_USER_KEYBINDS).

tui.bind.save

tui.bind.save [FILE]

Writes the user bindings (--user) to disk; they load automatically on the next start.

Parameters

Returns: 1 and a message on stderr when the file can’t be written.

Notes

  • With no user bindings the file is deleted.
  • Saving to another FILE does not change which file loads at start.

tui.bind.load

tui.bind.load [FILE]

Replaces the user bindings with those in FILE (default: the saved file) and marks them saved.

Notes

  • Runs automatically when the library is sourced.
  • Commands that are not defined yet are kept and skipped when pressed.

tui.bind.discard

tui.bind.discard

Drops unsaved changes to the user bindings by reloading the saved file.

tui.bind.dirty

tui.bind.dirty

Returns 0 while the user bindings differ from the saved file, else 1.

tui.bind.saved_file

tui.bind.saved_file

Prints the path of the saved user bindings (TUI_USER_KEYBINDS).

Kill switch, terminal mode, clipboard

Function Summary
tui.keys.suspend Kill switch: turns every keyboard binding off, user and default, and shows a warning box. Default: toggle.
tui.keys.suspend_key Changes the chord that toggles the keyboard kill switch. Default: ctrl+alt+k.
tui.keys.suspended Returns 0 while the keyboard kill switch is on.
tui.passthrough Terminal mode: hands mouse and keyboard back to the terminal so its native selection, copy, link clicking and scrolling work. Default: toggle.
tui.passthrough.key Changes the chord that toggles terminal mode. Default: ctrl+alt+p.
tui.passthrough.active Returns 0 while terminal mode is on.
tui.clipboard.copy Copies TEXT to the system clipboard through the terminal (OSC 52).
tui.clipboard.paste Prints the text of the last bracketed paste (no trailing newline).

tui.keys.suspend

tui.keys.suspend [on|off|toggle]

Kill switch: turns every keyboard binding off, user and default, and shows a warning box. Default: toggle.

Notes

  • Mouse input keeps working. A focused text input still takes typing and Enter.
  • The toggle chord (ctrl+alt+k by default) always works; change it with tui.keys.suspend_key.
  • Survives page changes.

tui.keys.suspend_key

tui.keys.suspend_key KEY

Changes the chord that toggles the keyboard kill switch. Default: ctrl+alt+k.

tui.keys.suspended

tui.keys.suspended

Returns 0 while the keyboard kill switch is on.

tui.passthrough

tui.passthrough [on|off|toggle]

Terminal mode: hands mouse and keyboard back to the terminal so its native selection, copy, link clicking and scrolling work. Default: toggle.

Notes

  • The screen is frozen while on: no timers, repaints or resize layouts. Background jobs keep running and their output appears when you leave.
  • Every key except the toggle chord (ctrl+alt+p by default) is ignored.
  • Independent of the keyboard kill switch.

See also: tui.passthrough.key

tui.passthrough.key

tui.passthrough.key KEY

Changes the chord that toggles terminal mode. Default: ctrl+alt+p.

tui.passthrough.active

tui.passthrough.active

Returns 0 while terminal mode is on.

tui.clipboard.copy

tui.clipboard.copy TEXT

Copies TEXT to the system clipboard through the terminal (OSC 52).

Notes

  • Works in kitty, foot, WezTerm, Alacritty, iTerm2 and tmux (with set-clipboard on). GNOME Terminal and other VTE terminals ignore it silently.
  • Some terminals cap the size of an OSC 52 payload.

tui.clipboard.paste

tui.clipboard.paste

Prints the text of the last bracketed paste (no trailing newline).

Notes

  • There is no way to read the system clipboard from a terminal; this is only what the user pasted into the app.

Built-in actions

Use as COMMAND in tui.bind, <bind action="…">, <button action="…"> or tui.cmd.add. All are bound by default and rebindable. More actions live with their modules: tui.action.text_keys, tui.action.update, tui.palette.open.

Function Summary
tui.action.quit Quits the app. Asks for confirmation first when the confirm.quit config key is 1.
tui.action.quit_now Quits the app without asking, regardless of confirm.quit.
tui.action.focus_next Moves focus to the next focusable widget in creation order, wrapping around (tab).
tui.action.focus_prev Moves focus to the previous focusable widget (shift+tab).
tui.action.focus_dir Moves focus to the widget you would expect in that direction on screen.
tui.action.unfocus Removes focus from the focused widget (esc).
tui.action.activate Acts on the focused widget as Enter does: presses a button, toggles a checkbox, submits a text widget, opens a select, or runs a list/table action.
tui.action.click Handles a left press or drag: jumps a scrollbar, else acts on the widget under the pointer, else removes focus.
tui.action.scroll Scrolls the target pane by N lines (up/down, default 3) or columns (left/right, default 5).
tui.action.page Scrolls the target pane by one screen (its height minus 3 rows).
tui.action.scroll_top Scrolls the target pane to the top left.
tui.action.scroll_bottom Scrolls the target pane to the end.
tui.action.pane_next Moves keyboard focus to the next pane worth visiting: scrollable panes and panes with two or more widgets.
tui.action.pane_prev Moves keyboard focus to the previous such pane.
tui.action.pane_dir Moves keyboard focus to the nearest such pane in that direction.
tui.action.focus_pane Moves keyboard focus into PANE: to the widget that last had focus there, else its first widget, else the pane itself becomes the scroll target.
tui.action.scroll_or_pane Scrolls the target pane when it can scroll that way, else moves to the neighbouring pane (alt+arrows).
tui.action.paste Inserts the pasted text (TUI_EVENT_PASTE) into the focused text widget, replacing the selection.
tui.action.goto Opens a page, like tui.goto. Does nothing without an argument.
tui.action.goto_default Opens a page shipped with DABT ($TUI_DEFAULTS_DIR/pages/NAME.xml). Also reachable from the palette.
tui.action.back Returns to the previous page. Does nothing when there is no history.
tui.action.reload_page Reloads the current page. Its on_visit runs again.
tui.action.redraw Recomputes the layout and repaints everything, like tui.relayout.

tui.action.quit

tui.action.quit

Quits the app. Asks for confirmation first when the confirm.quit config key is 1.

Notes

  • tui.action.quit_now quits without asking.

tui.action.quit_now

tui.action.quit_now

Quits the app without asking, regardless of confirm.quit.

tui.action.focus_next

tui.action.focus_next

Moves focus to the next focusable widget in creation order, wrapping around (tab).

tui.action.focus_prev

tui.action.focus_prev

Moves focus to the previous focusable widget (shift+tab).

tui.action.focus_dir

tui.action.focus_dir up|down|left|right

Moves focus to the widget you would expect in that direction on screen.

Notes

  • Left/right only consider widgets on the same screen row; up/down only widgets whose columns overlap the current one. When nothing is there, focus stays.
  • With nothing focused, down/right focus the first widget and up/left the last.

tui.action.unfocus

tui.action.unfocus

Removes focus from the focused widget (esc).

tui.action.activate

tui.action.activate

Acts on the focused widget as Enter does: presses a button, toggles a checkbox, submits a text widget, opens a select, or runs a list/table action.

tui.action.click

tui.action.click

Handles a left press or drag: jumps a scrollbar, else acts on the widget under the pointer, else removes focus.

Notes

  • Clicking a scrollable pane also makes it the keyboard pane. A sticky input keeps focus.

tui.action.scroll

tui.action.scroll up|down|left|right [N]

Scrolls the target pane by N lines (up/down, default 3) or columns (left/right, default 5).

Notes

  • Target: for mouse events the pane under the pointer; for keys the keyboard pane, else the pane under the pointer, else the focused widget’s pane, else the first scrollable pane.
  • The wheel over a textarea, list or table scrolls that widget instead.
  • Merged repeats (TUI_EVENT_COUNT) multiply the distance.

tui.action.page

tui.action.page up|down

Scrolls the target pane by one screen (its height minus 3 rows).

tui.action.scroll_top

tui.action.scroll_top

Scrolls the target pane to the top left.

tui.action.scroll_bottom

tui.action.scroll_bottom

Scrolls the target pane to the end.

tui.action.pane_next

tui.action.pane_next

Moves keyboard focus to the next pane worth visiting: scrollable panes and panes with two or more widgets.

tui.action.pane_prev

tui.action.pane_prev

Moves keyboard focus to the previous such pane.

tui.action.pane_dir

tui.action.pane_dir up|down|left|right

Moves keyboard focus to the nearest such pane in that direction.

tui.action.focus_pane

tui.action.focus_pane PANE

Moves keyboard focus into PANE: to the widget that last had focus there, else its first widget, else the pane itself becomes the scroll target.

Returns: 1 for an unknown pane.

tui.action.scroll_or_pane

tui.action.scroll_or_pane up|down|left|right

Scrolls the target pane when it can scroll that way, else moves to the neighbouring pane (alt+arrows).

tui.action.paste

tui.action.paste

Inserts the pasted text (TUI_EVENT_PASTE) into the focused text widget, replacing the selection.

Notes

  • Single-line widgets turn newlines into spaces.

tui.action.goto

tui.action.goto PAGE_FILE

Opens a page, like tui.goto. Does nothing without an argument.

tui.action.goto_default

tui.action.goto_default settings|keybinds|plugins

Opens a page shipped with DABT ($TUI_DEFAULTS_DIR/pages/NAME.xml). Also reachable from the palette.

tui.action.back

tui.action.back

Returns to the previous page. Does nothing when there is no history.

Notes

  • History holds the last 30 pages; reloading the same page does not add to it.

tui.action.reload_page

tui.action.reload_page

Reloads the current page. Its on_visit runs again.

tui.action.redraw

tui.action.redraw

Recomputes the layout and repaints everything, like tui.relayout.