reovim_plugin_microscope/microscope/
item.rs

1//! Microscope item types
2
3use std::path::PathBuf;
4
5use reovim_core::{command::CommandId, highlight::ThemeName};
6
7/// Data associated with a microscope item, determining the action on selection
8#[derive(Debug, Clone)]
9pub enum MicroscopeData {
10    /// A file path to open
11    FilePath(PathBuf),
12    /// A buffer ID to switch to
13    BufferId(usize),
14    /// A command to execute
15    Command(CommandId),
16    /// A help tag to display
17    HelpTag(String),
18    /// A keymap entry
19    Keymap {
20        mode: String,
21        key: String,
22        command: String,
23    },
24    /// A grep match with location
25    GrepMatch {
26        path: PathBuf,
27        line: usize,
28        col: usize,
29    },
30    /// A theme/colorscheme to apply
31    Theme(ThemeName),
32    /// A configuration profile to load
33    Profile(String),
34}
35
36/// Represents a single item in the microscope results list
37#[derive(Debug, Clone)]
38pub struct MicroscopeItem {
39    /// Unique identifier for this item
40    pub id: String,
41    /// Primary display text
42    pub display: String,
43    /// Secondary detail text (optional, shown grayed out)
44    pub detail: Option<String>,
45    /// Data for determining action on selection
46    pub data: MicroscopeData,
47    /// Fuzzy match score (higher = better match)
48    pub score: Option<u32>,
49    /// Icon/indicator character
50    pub icon: Option<char>,
51    /// Source picker name
52    pub source: &'static str,
53}
54
55impl MicroscopeItem {
56    /// Create a new microscope item
57    #[must_use]
58    pub fn new(
59        id: impl Into<String>,
60        display: impl Into<String>,
61        data: MicroscopeData,
62        source: &'static str,
63    ) -> Self {
64        Self {
65            id: id.into(),
66            display: display.into(),
67            detail: None,
68            data,
69            score: None,
70            icon: None,
71            source,
72        }
73    }
74
75    /// Set detail text
76    #[must_use]
77    pub fn with_detail(mut self, detail: impl Into<String>) -> Self {
78        self.detail = Some(detail.into());
79        self
80    }
81
82    /// Set match score
83    #[must_use]
84    pub const fn with_score(mut self, score: u32) -> Self {
85        self.score = Some(score);
86        self
87    }
88
89    /// Set icon
90    #[must_use]
91    pub const fn with_icon(mut self, icon: char) -> Self {
92        self.icon = Some(icon);
93        self
94    }
95
96    /// Get the text used for matching
97    #[must_use]
98    pub fn match_text(&self) -> &str {
99        &self.display
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106
107    #[test]
108    fn test_new_item() {
109        let item = MicroscopeItem::new(
110            "file1",
111            "src/main.rs",
112            MicroscopeData::FilePath(PathBuf::from("src/main.rs")),
113            "files",
114        );
115
116        assert_eq!(item.id, "file1");
117        assert_eq!(item.display, "src/main.rs");
118        assert_eq!(item.source, "files");
119        assert!(item.detail.is_none());
120        assert!(item.score.is_none());
121        assert!(item.icon.is_none());
122    }
123
124    #[test]
125    fn test_builder_methods() {
126        let item = MicroscopeItem::new("buf1", "buffer.rs", MicroscopeData::BufferId(1), "buffers")
127            .with_detail("modified")
128            .with_score(100)
129            .with_icon('*');
130
131        assert_eq!(item.detail.as_deref(), Some("modified"));
132        assert_eq!(item.score, Some(100));
133        assert_eq!(item.icon, Some('*'));
134    }
135}