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