reovim_plugin_pickers/
commands.rs

1//! Command palette picker implementation
2
3use std::{future::Future, pin::Pin};
4
5use {
6    reovim_core::command::CommandId,
7    reovim_plugin_microscope::{
8        MicroscopeAction, MicroscopeData, MicroscopeItem, Picker, PickerContext, PreviewContent,
9    },
10};
11
12/// Command info for the command palette
13#[derive(Debug, Clone)]
14pub struct CommandInfo {
15    /// Command ID
16    pub id: CommandId,
17    /// Command description
18    pub description: String,
19}
20
21/// Picker for the command palette
22pub struct CommandsPicker {
23    /// Available commands (set by runtime from registry)
24    commands: Vec<CommandInfo>,
25}
26
27impl CommandsPicker {
28    /// Create a new commands picker
29    #[must_use]
30    pub const fn new() -> Self {
31        Self {
32            commands: Vec::new(),
33        }
34    }
35
36    /// Set available commands
37    pub fn set_commands(&mut self, commands: Vec<CommandInfo>) {
38        self.commands = commands;
39    }
40}
41
42impl Default for CommandsPicker {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48impl Picker for CommandsPicker {
49    fn name(&self) -> &'static str {
50        "commands"
51    }
52
53    fn title(&self) -> &'static str {
54        "Command Palette"
55    }
56
57    fn prompt(&self) -> &'static str {
58        "Commands> "
59    }
60
61    fn fetch(
62        &self,
63        _ctx: &PickerContext,
64    ) -> Pin<Box<dyn Future<Output = Vec<MicroscopeItem>> + Send + '_>> {
65        Box::pin(async move {
66            self.commands
67                .iter()
68                .map(|cmd| {
69                    MicroscopeItem::new(
70                        cmd.id.as_str(),
71                        cmd.id.as_str(),
72                        MicroscopeData::Command(cmd.id.clone()),
73                        "commands",
74                    )
75                    .with_detail(&cmd.description)
76                })
77                .collect()
78        })
79    }
80
81    fn on_select(&self, item: &MicroscopeItem) -> MicroscopeAction {
82        match &item.data {
83            MicroscopeData::Command(id) => MicroscopeAction::ExecuteCommand(id.clone()),
84            _ => MicroscopeAction::Nothing,
85        }
86    }
87
88    fn preview(
89        &self,
90        item: &MicroscopeItem,
91        _ctx: &PickerContext,
92    ) -> Pin<Box<dyn Future<Output = Option<PreviewContent>> + Send + '_>> {
93        let description = item.detail.clone();
94        let display = item.display.clone();
95
96        Box::pin(async move {
97            description.map(|desc| {
98                PreviewContent::new(vec![
99                    format!("Command: {}", display),
100                    String::new(),
101                    format!("Description: {}", desc),
102                ])
103            })
104        })
105    }
106}