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
//! Interactive multi-row picker used by `zenops import` and (eventually)
//! every other command that needs the user to weigh in on each item of a
//! plan before it lands.
//!
//! The trait, [`Picker`], deliberately mirrors [`crate::prompt::Prompter`]:
//! both take a borrowed view of the work the command wants to do and let
//! the user shape it before any filesystem effect runs. The difference is
//! scope — [`Prompter`](crate::prompt::Prompter) confirms one change at a
//! time; [`Picker`] presents the whole set at once and lets the user
//! cursor through it, cycling each row's chosen action.
//!
//! Choices are indexed into a per-item `&[ChoiceLabel]` slice rather than
//! parameterised on a caller enum. That keeps the trait `dyn`-safe and
//! lets a single picker session render rows whose intrinsic shapes differ
//! (e.g. `import` reconcile mode mixes "move-and-symlink" rows with
//! "remove from repo" rows). Callers map [`PickItem::choice`] back to
//! their own enum at the boundary via [`ChoiceLabel::key`].
//!
//! Rows whose `choices` slice has length 1 are *disabled*: the cursor
//! still lands on them so the user can read the explanation in
//! [`PickItem::note`], but `space` is a no-op. This is intentional UX —
//! a hidden row reads as a bug ("why didn't `.git` show up?"); a visible
//! disabled row with a "vcs directory" note explains itself.
pub use Error as PickerError;
pub use ;
pub use TerminalPicker;
use Cow;
use SmolStr;
use crateError;
/// One row in a picker session.
///
/// The picker mutates [`Self::choice`] in place — callers read it back to
/// learn which action the user selected.
/// One choice on a picker row's action cycle.
///
/// [`Self::key`] is a stable identifier callers match on after the
/// picker returns; [`Self::label`] is the human-readable string shown
/// inside `[ ]` on the row. They're distinct so the displayed text can
/// be tuned for the user without breaking the call-site dispatch logic.
/// What the user chose to do at the end of a picker session.
/// How a command consults the user before acting on a multi-item plan.
///
/// Borrowed mutably because real impls hold terminal state (raw mode,
/// alt-screen) and test impls hold a script of canned actions.