ratatui-which-key
A which-key popup widget + input handler for ratatui applications, inspired by folke's which-key.nvim.

All input can be routed to ratatui-which-key and it will return an application-specific action to perform based on the configured keybinds.
Check out the docs for more info.
There is also a sample application that you can run with cargo run --example demo which shows how to perform bindings and set up ratatui-which-key for usage in an app.
How It Works
ratatui-which-key requires three data types be defined in your application.
Scopes
The scope is what part of your application is currently "in focus":
// When changing focus to another pane/window/etc:
app.which_key.set_scope
Actions
ratatui-which-key returns an Action when a keybind is triggered:
// Must implement Display to show descriptions in the which-key popup.
// In your input handler:
if let Some = app.which_key.handle_key.action
Categories
The ratatui-which-key popup displays keybinds sorted by category:
Keymap Configuration
You'll need to put a WhichKeyState<CrosstermKey, Scope, Action, Category> at the top-level of your application (like in App). Then at program start, configure your keybinds by creating a new Keymap. The code comments explain the different ways of performing keybindings.
let mut keymap = new;
keymap
// "describe_group" is a way to set the name of a group explicitly
.describe_group
// keys can be bound individually
.bind
.bind
// control keys supported
.bind
// f-keys supported
.bind
// sequences supported
.bind
// sequences can start with any key
.bind
// group configuration by prefix. No need to use `describe_group` when using this method.
.group
// automated scope association. No need to specify scope for each binding.
.scope
// automated category association. No need to specify category for each binding.
.category
// automated scope + category association.
.scope_and_category;
// Create new state with a keymap and initial scope.
app.which_key = new;
Finally, to render:
// (in your top-level render function)
if app.which_key.active