reovim_picker_options/
lib.rs1#![cfg_attr(coverage_nightly, allow(unused_features))]
2#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
3use std::sync::Arc;
11
12use {
13 reovim_driver_picker::{
14 Picker, PickerAction, PickerContext, PickerData, PickerItem, PickerRegistry, PreviewContent,
15 },
16 reovim_kernel::api::v1::{Module, ModuleContext, ModuleError, ModuleId, ProbeResult, Version},
17};
18
19pub struct OptionsPicker;
29
30impl OptionsPicker {
31 #[must_use]
33 pub const fn new() -> Self {
34 Self
35 }
36}
37
38impl Default for OptionsPicker {
39 fn default() -> Self {
40 Self::new()
41 }
42}
43
44impl Picker for OptionsPicker {
45 fn name(&self) -> &'static str {
46 "options"
47 }
48
49 fn title(&self) -> &'static str {
50 "Options"
51 }
52
53 fn items(
54 &self,
55 ctx: &PickerContext,
56 _services: &reovim_kernel::api::v1::ServiceRegistry,
57 ) -> Vec<PickerItem> {
58 ctx.options
59 .iter()
60 .map(|opt| {
61 let display = opt
62 .owner
63 .as_ref()
64 .map_or_else(|| opt.name.clone(), |owner| format!("[{owner}] {}", opt.name));
65 let detail = format!("{} = {}", opt.type_name, opt.current_value);
66 let data = build_preview_data(opt);
68 PickerItem {
69 display,
70 detail: Some(detail),
71 data: PickerData::Text(data),
72 icon: None,
73 }
74 })
75 .collect()
76 }
77
78 fn on_select(&self, _item: &PickerItem) -> PickerAction {
79 PickerAction::Close
80 }
81
82 #[cfg_attr(coverage_nightly, coverage(off))]
83 fn preview(
84 &self,
85 item: &PickerItem,
86 _services: &reovim_kernel::api::v1::ServiceRegistry,
87 ) -> Option<PreviewContent> {
88 let PickerData::Text(ref data) = item.data else {
89 return None;
90 };
91
92 let lines: Vec<String> = data.lines().map(String::from).collect();
93 if lines.is_empty() {
94 return None;
95 }
96
97 Some(PreviewContent {
98 lines,
99 highlight_line: Some(0),
100 file_path: None,
101 ..Default::default()
102 })
103 }
104}
105
106fn build_preview_data(opt: &reovim_driver_picker::OptionInfo) -> String {
116 let mut lines = Vec::with_capacity(10);
117
118 lines.push(format!(" {}", opt.name));
119 if let Some(ref short) = opt.short_form {
120 lines.push(format!(" alias: {short}"));
121 }
122 lines.push(String::new());
123 lines.push(format!(" {}", opt.description));
124 lines.push(String::new());
125 lines.push(format!(" Type: {}", opt.type_name));
126 lines.push(format!(" Value: {}", opt.current_value));
127 lines.push(format!(" Default: {}", opt.default_value));
128 lines.push(format!(" Scope: {}", opt.scope));
129
130 if let Some(ref constraint) = opt.constraint {
131 lines.push(format!(" Range: {constraint}"));
132 }
133
134 if let Some(ref owner) = opt.owner {
135 lines.push(format!(" Module: {owner}"));
136 }
137
138 if let Some(ref choices) = opt.choices {
139 lines.push(format!(" Choices: {}", choices.join(", ")));
140 }
141
142 lines.join("\n")
143}
144
145pub struct PickerOptionsModule;
153
154impl PickerOptionsModule {
155 #[must_use]
157 pub const fn new() -> Self {
158 Self
159 }
160}
161
162impl Default for PickerOptionsModule {
163 fn default() -> Self {
164 Self::new()
165 }
166}
167
168impl Module for PickerOptionsModule {
169 fn id(&self) -> ModuleId {
170 ModuleId::new("picker-options")
171 }
172
173 fn name(&self) -> &'static str {
174 "Option Picker"
175 }
176
177 fn version(&self) -> Version {
178 Version::new(0, 1, 0)
179 }
180
181 fn init(&mut self, ctx: &ModuleContext) -> ProbeResult {
182 let registry = ctx.services.get_or_create::<PickerRegistry>();
183 registry.register(Arc::new(OptionsPicker));
184 ProbeResult::Success
185 }
186
187 fn exit(&mut self) -> Result<(), ModuleError> {
188 Ok(())
189 }
190}
191
192#[cfg(feature = "dynamic")]
193reovim_module_macros::declare_module!(PickerOptionsModule);
194
195#[cfg(test)]
196#[path = "lib_tests.rs"]
197mod tests;