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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! Palette events and interaction mode.
//!
//! These types are emitted by [`PaletteState`](crate::state::PaletteState) and
//! interpreted by the application:
//!
//! - [`PaletteMode`] tells renderers and input handlers whether rows represent actions or inputs.
//! - [`PaletteEvent`] is the application-facing result of lifecycle, preview, and accept actions.
//! - [`MoveSelection`] describes relative and absolute selection movement.
use ActionId;
use ActionInvocation;
/// Interaction mode for the command palette.
///
/// The mode tells renderers whether rows are actions or input choices, and
/// tells input handlers how to interpret selection and query edits. Read the
/// mode from [`PaletteState::mode`](crate::state::PaletteState::mode) or from a
/// rendered [`PaletteView`](crate::view::PaletteView).
///
/// # Examples
///
/// ```
/// use ratatui_action::id::ActionId;
/// use ratatui_command_palette::event::PaletteMode;
///
/// let mode = PaletteMode::CollectingInput {
/// action: ActionId::new("theme.switch"),
/// input_index: 0,
/// };
///
/// assert!(matches!(
/// mode,
/// PaletteMode::CollectingInput { input_index: 0, .. }
/// ));
/// ```
/// Event emitted by palette state transitions.
///
/// Applications should handle these events at their own boundary. The palette
/// never executes callbacks or mutates application state.
///
/// # Examples
///
/// ```
/// use ratatui_action::spec::ActionSpec;
/// use ratatui_command_palette::event::PaletteEvent;
/// use ratatui_command_palette::state::PaletteState;
///
/// let actions = vec![ActionSpec::new("document.open", "Open document")];
/// let mut palette = PaletteState::new();
/// palette.open(&actions);
///
/// match palette.accept(&actions) {
/// Some(PaletteEvent::Invoke(invocation)) => {
/// assert_eq!(invocation.id().as_str(), "document.open");
/// }
/// event => panic!("unexpected event: {event:?}"),
/// }
/// ```
/// Direction or distance for selection movement.
///
/// Relative movement wraps at the first and last visible row.
/// [`MoveSelection::First`] and [`MoveSelection::Last`] jump to absolute
/// boundaries.
///
/// # Examples
///
/// ```
/// use ratatui_action::spec::ActionSpec;
/// use ratatui_command_palette::event::MoveSelection;
/// use ratatui_command_palette::state::PaletteState;
///
/// let actions = vec![
/// ActionSpec::new("first", "First"),
/// ActionSpec::new("second", "Second"),
/// ];
/// let mut palette = PaletteState::new();
/// palette.open(&actions);
///
/// palette.move_selection(MoveSelection::Previous, &actions);
///
/// assert_eq!(palette.selected(), Some(1));
/// ```