Skip to content

Contextual Keybars

ContextualKeybar maps a focused panel, tab, or any other context value to a KeybarSpec.

from lazy_cuh import (
ActionBinding,
ActionDispatcher,
ActionHandlerSpec,
ActionId,
ActionMap,
ContextualKeybar,
HintVisibility,
Notice,
NoticeLevel,
hint_groups_from_actions,
keybar_spec_from_actions,
)
from lazy_cuh.widgets import KeybarWidget
actions = ActionMap(
(
ActionBinding.from_key(
"enter",
ActionId.SELECT,
label="Select",
contexts=("channels",),
visibility=HintVisibility.COMPACT,
group="Primary",
order=10,
),
ActionBinding.from_key("s", ActionId.SAVE, label="Save", visibility=HintVisibility.COMPACT, group="System", order=10),
ActionBinding.from_key("?", ActionId.HELP, label="Keybindings", visibility=HintVisibility.HELP),
)
)
keybar = ContextualKeybar(
by_context={
"channels": keybar_spec_from_actions(actions, context="channels"),
},
)
spec = keybar.spec_for("channels")
help_groups = hint_groups_from_actions(
actions,
context="channels",
)
widget = KeybarWidget(spec)
widget.set_notice(Notice("Saved.", level=NoticeLevel.SUCCESS), timeout=2.0)
widget.clear_notice()
dispatcher = ActionDispatcher(
{
ActionId.SELECT: ActionHandlerSpec.contextual(lambda context: context.count),
ActionId.SAVE: lambda: None,
}
)
dispatcher.dispatch(ActionId.SAVE)
dispatcher.dispatch(ActionId.SELECT, count=5)

Bindings with HintVisibility.COMPACT are projected into the compact footer. Bindings with HintVisibility.HELP can stay out of the footer while remaining available for expanded help views. keybar_spec_from_actions() is the compact footer adapter; hint_groups_from_actions() returns grouped neutral hints for help modals or expanded keybar rows. Use the same ActionMap for all three surfaces so labels, aliases, grouping, ordering, and right/left placement do not drift. group and order keep the projected hints deterministic and app-configurable.

ActionDispatcher is the matching app-side router. It stays pure Python: it does not know about Textual widgets, and it simply turns an action id into an optional handler call. Use plain no-argument callables for simple actions, or ActionHandlerSpec.contextual(...) when a handler needs metadata such as a vim count.

Notices are short-lived UI messages rendered in the keybar surface. Apps may clear them explicitly, or pass a timeout to KeybarWidget.set_notice() for Textual-managed auto-clear behavior. The pure Notice model has no timer.

KeybarWidget can also render grouped help rows below the compact footer. Set the groups with set_help_groups() and toggle the expanded state with toggle_expanded(). The same HintGroup data can later be reused by modal help views. Expanded rows keep the compact lazygit-style Label: key format while padding labels inside grouped rows for easier scanning.