Skip to main content

Module command_palette

Module command_palette 

Source
Expand description

CommandPalette — type-to-run access to every command an app has registered.

The palette is application-agnostic: it holds no list of its own and knows nothing about any particular app. Its content is the tree’s ShortcutRegistry, which already carries everything a palette row needs — a localized name, an optional category to group by, an optional description, the effective keystroke (user rebinds merged in), and a live enabled verdict. Activating a row sends the command’s intent, which is the same path a menu row or the chord itself takes.

That has a consequence worth stating plainly, because it is the whole design: a command does not need a keystroke to appear here. iter_effective() yields every registered entry, bound or not, so an app makes a command searchable by registering it with a name and no chord:

// Reachable from the palette, and rebindable by the user later, without
// occupying a keystroke today.
ctx.register_shortcut_global(
    Shortcut::new("document.export")
        .name("Export…")
        .category("File")
        .build(),
);

§Presenting it

CommandPalette::present shows it centered, dismissed by Escape or a click outside:

ctx.register_action_global(Action::new("app.command_palette").on_invoke(|_, ctx| {
    CommandPalette::new().present(ctx);
}));

Presenting it as a window-level modal is deliberate, not incidental: a palette is routinely opened from a menu, and a menu is itself a transient overlay. Anchoring to the invoking widget would render the palette inside the menu that opened it, positioned against a surface that is about to disappear.

§Matching

Typing filters by subsequence, not substring, so ndw finds “New Window” and expdoc finds “Export document”. Matches score higher when the typed letters land consecutively and on word starts, so the most literal reading of a query sorts first. An empty query lists everything in the registry’s own deterministic (category, id) order. The category takes part in matching, so file new finds the New command filed under File.

§Keyboard

Focus stays in the search field throughout — that is what makes a palette feel like one. Arrow keys are not editing keys for the field, so they bubble to the palette’s own handler, which moves the highlight and scrolls it into view. Enter runs the highlighted command; Escape dismisses.

Structs§

CommandPalette
Type-to-run access to every registered command. See the module docs.
PaletteCommand
One command as the palette sees it.