Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

List

The List module builds the rows every command returns. Everything lives in corvo_ext::list.

ListItem

A row under construction:

#![allow(unused)]
fn main() {
use corvo_ext::list::ListItem;

ListItem::new("Camden Hells")
    .subtitle("0,5 Liter")
    .icon(Icon::Web)
    .accessory("4.6%")
    .section("Lager")
    .build("beer:open:camden-hells", 700)
}
MethodFieldNotes
new(title)titlethe row text
.subtitle(s)subtitleone line; truncates with …
.icon(i)iconsee Icons
.accessory(s)accessoryright-aligned hint
.section(s)sectiongroup header, see below
.build(id, score)—finishes the row

build takes the namespaced result id and the score. See the command contract for the id shapes.

Sections

Consecutive rows sharing a section render under one header. Two rules keep sections working:

  1. Keep sections contiguous. Sort by section first, then score:

    #![allow(unused)]
    fn main() {
    results.sort_by(|a, b| {
        a.section.cmp(&b.section)
            .then_with(|| b.score.cmp(&a.score))
            .then_with(|| a.title.cmp(&b.title))
    });
    }
  2. Name sections like the UI does: short, upper-case in rendering, plural nouns where natural (Formulae, Casks).

Rows without a section fall into the default group, rendered as Results.

open_entry

The standard opener row that exposes a command’s page:

#![allow(unused)]
fn main() {
let row = list::open_entry(
    "weather",
    "Weather",
    "Current conditions and forecast",
    Icon::Svg(phosphor_svgs::style::regular::CLOUD),
    1000,
);
// row.id == "weather:open"
}

The launcher intercepts {id}:open to open the page; execute’s open arm is the fallback.

empty_state

A quiet hint row for a page with nothing to show:

#![allow(unused)]
fn main() {
let hint = list::empty_state(ID, "No matches — add items in Settings");
}

It scores 1, so any real row outranks it, and it carries the {id}:empty id.

fuzzy_open

The shared fuzzy tail for root search. It scores the query against your aliases and answers with the opener row when they match:

#![allow(unused)]
fn main() {
list::fuzzy_open(
    trimmed_query,
    &["Weather", "weather forecast temperature clima"],
    &open_entry(0),
)
}

Score math: a fuzzy match yields match_score + 120; an exact keyword hit (routed before calling this) typically passes 1000.

Score conventions

ScoreMeaning
1000keyword-routed opener or quick command
1010live context row above the opener (now playing, timer state)
700rows on a dedicated page
score + 120fuzzy root matches
1empty-state hints