listary 0.0.1

A fast command-line file search utility inspired by Listary, with fuzzy search, application launching, and smart auto-open features
use std::fs;
use std::path::PathBuf;
use std::collections::VecDeque;

pub struct SearchHistory {
    history: VecDeque<String>,
    max_size: usize,
    history_file: PathBuf,
}

impl SearchHistory {
    pub fn new(max_size: usize) -> Self {
        let cache_dir = dirs::cache_dir()
            .unwrap_or_else(|| PathBuf::from("."))
            .join("listary");
        
        if !cache_dir.exists() {
            fs::create_dir_all(&cache_dir).ok();
        }
        
        let mut history = Self {
            history: VecDeque::new(),
            max_size,
            history_file: cache_dir.join("search_history.txt"),
        };
        
        history.load_history();
        history
    }

    pub fn add_query(&mut self, query: &str) {
        let query = query.trim().to_string();
        
        // Don't add empty queries or duplicates of the last query
        if query.is_empty() || self.history.front() == Some(&query) {
            return;
        }

        // Remove existing occurrence if present
        if let Some(pos) = self.history.iter().position(|x| x == &query) {
            self.history.remove(pos);
        }

        // Add to front
        self.history.push_front(query);

        // Maintain max size
        if self.history.len() > self.max_size {
            self.history.pop_back();
        }

        self.save_history();
    }

    pub fn get_history(&self) -> Vec<String> {
        self.history.iter().cloned().collect()
    }

    pub fn clear(&mut self) {
        self.history.clear();
        self.save_history();
    }

    pub fn load_history(&mut self) {
        if let Ok(content) = fs::read_to_string(&self.history_file) {
            self.history = content
                .lines()
                .take(self.max_size)
                .map(|s| s.to_string())
                .collect();
        }
    }

    fn save_history(&self) {
        let content = self.history
            .iter()
            .map(|s| s.as_str())
            .collect::<Vec<_>>()
            .join("\n");
        
        fs::write(&self.history_file, content).ok();
    }
}