reovim_plugin_microscope/microscope/picker/
mod.rs

1//! Picker trait and infrastructure
2//!
3//! This module provides the core picker infrastructure:
4//! - `Picker` trait for implementing custom pickers
5//! - `PickerContext` for picker operations
6//! - `MicroscopeAction` for actions on selection
7//! - `PickerRegistry` for dynamic picker registration
8//!
9//! Actual picker implementations are in the separate `reovim-plugin-pickers` crate.
10
11pub mod registry;
12
13pub use registry::PickerRegistry;
14
15use std::{future::Future, path::PathBuf, pin::Pin};
16
17use reovim_core::{command::CommandId, highlight::ThemeName};
18
19use super::{item::MicroscopeItem, state::PreviewContent};
20
21/// Buffer info passed from runtime for buffer picker
22#[derive(Debug, Clone)]
23pub struct BufferInfo {
24    /// Buffer ID
25    pub id: usize,
26    /// Buffer name/path
27    pub name: String,
28    /// Whether the buffer is modified
29    pub modified: bool,
30    /// Preview lines
31    pub preview_lines: Vec<String>,
32}
33
34/// Context for picker operations
35#[derive(Debug, Clone)]
36pub struct PickerContext {
37    /// Current search query
38    pub query: String,
39    /// Working directory
40    pub cwd: PathBuf,
41    /// Maximum items to fetch
42    pub max_items: usize,
43    /// Available buffers (for buffers picker)
44    pub buffers: Vec<BufferInfo>,
45}
46
47impl Default for PickerContext {
48    fn default() -> Self {
49        Self {
50            query: String::new(),
51            cwd: std::env::current_dir().unwrap_or_default(),
52            max_items: 1000,
53            buffers: Vec::new(),
54        }
55    }
56}
57
58/// Action to perform when an item is selected
59#[derive(Debug, Clone)]
60pub enum MicroscopeAction {
61    /// Open a file
62    OpenFile(PathBuf),
63    /// Switch to a buffer
64    SwitchBuffer(usize),
65    /// Execute a command
66    ExecuteCommand(CommandId),
67    /// Go to a specific location
68    GotoLocation {
69        path: PathBuf,
70        line: usize,
71        col: usize,
72    },
73    /// Show help for a tag
74    ShowHelp(String),
75    /// Apply a theme/colorscheme
76    ApplyTheme(ThemeName),
77    /// Switch to a configuration profile
78    SwitchProfile(String),
79    /// Close microscope without action
80    Close,
81    /// Do nothing
82    Nothing,
83}
84
85/// Trait for implementing microscope pickers
86///
87/// Pickers are responsible for:
88/// - Fetching items (files, buffers, commands, etc.)
89/// - Determining actions when an item is selected
90/// - Optionally providing preview content
91///
92/// # Example
93///
94/// ```ignore
95/// use reovim_plugin_microscope::{Picker, PickerContext, MicroscopeAction, MicroscopeItem};
96///
97/// pub struct MyPicker;
98///
99/// impl Picker for MyPicker {
100///     fn name(&self) -> &'static str { "my_picker" }
101///     fn title(&self) -> &'static str { "My Picker" }
102///
103///     fn fetch(&self, ctx: &PickerContext) -> Pin<Box<dyn Future<Output = Vec<MicroscopeItem>> + Send + '_>> {
104///         Box::pin(async { vec![] })
105///     }
106///
107///     fn on_select(&self, item: &MicroscopeItem) -> MicroscopeAction {
108///         MicroscopeAction::Nothing
109///     }
110/// }
111/// ```
112pub trait Picker: Send + Sync {
113    /// Unique identifier for this picker
114    fn name(&self) -> &'static str;
115
116    /// Human-readable title for the picker window
117    fn title(&self) -> &'static str;
118
119    /// Prompt string (shown before input)
120    fn prompt(&self) -> &'static str {
121        "> "
122    }
123
124    /// Fetch items asynchronously
125    fn fetch(
126        &self,
127        ctx: &PickerContext,
128    ) -> Pin<Box<dyn Future<Output = Vec<MicroscopeItem>> + Send + '_>>;
129
130    /// Handle selection of an item
131    fn on_select(&self, item: &MicroscopeItem) -> MicroscopeAction;
132
133    /// Optional: preview content for the selected item
134    fn preview(
135        &self,
136        _item: &MicroscopeItem,
137    ) -> Pin<Box<dyn Future<Output = Option<PreviewContent>> + Send + '_>> {
138        Box::pin(async { None })
139    }
140
141    /// Whether this picker supports live filtering vs full re-fetch
142    /// If true, the picker only needs to fetch once and nucleo handles filtering
143    /// If false, the picker needs to re-fetch on each query change (e.g., live grep)
144    fn supports_live_filter(&self) -> bool {
145        true
146    }
147}