1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/// A single keyboard shortcut entry displayed in the help popup.
/// A named group of shortcut entries, one per lib (Core, Redmine, …).
///
/// Each lib that registers shortcuts produces exactly one `ShortcutBlock`.
/// The orchestrator collects all blocks and renders them section by section
/// in the help popup, sorted by `priority` (lowest first).
/// A registered shortcut factory: a plain function pointer that produces a [`ShortcutBlock`].
///
/// # Why a function pointer and not `Box<dyn Trait>`?
///
/// `inventory` requires collected types to be `'static`. A `fn() -> ShortcutBlock` is
/// trivially `'static` and requires no heap allocation at registration time, making it
/// ideal for link-time auto-registration.
///
/// # How to register a new provider (e.g. Jira)
///
/// In `gitlab-tracker-jira/src/shortcuts.rs`, add:
/// ```rust
/// fn jira_shortcuts() -> ShortcutBlock { /* … */ }
/// inventory::submit!(ShortcutFactory(jira_shortcuts));
/// ```
/// That's it — no change to `main.rs` or any other existing file.
);
// Declare the global registry. Every `inventory::submit!(ShortcutFactory(…))` call
// anywhere in the dependency graph (including optional/feature-gated crates that are
// actually linked) will be collected here at startup.
collect!;
/// Collects all registered [`ShortcutBlock`]s from every linked crate,
/// sorted by `priority` (ascending) so Core always appears before plugins
/// regardless of link order.
///
/// Call this once at startup to populate `App::shortcut_providers`.