panty 0.2.0

Fast gVim summoner
Documentation


use inotify::INotify;
use inotify::ffi::*;
use std::collections::{HashSet, HashMap};
use std::path::Path;
use std::thread;

use collector;



const EVENTS: u32 = IN_CREATE | IN_MODIFY | IN_DELETE;


pub fn patrol(stocks: collector::Stocks, max_stocks: usize, targets: &Vec<String>) {
    let mut files: Vec<String> = vec![];
    let mut directories: Vec<String> = vec![];

    for target in targets {
        let path = Path::new(target);
        if path.is_file() {
            files.push(target.to_string());
        } else {
            directories.push(target.to_string());
        }
    }

    {
        let stocks = stocks.clone();
        thread::spawn(move || file_patrol(stocks, max_stocks, &files));
    }
    {
        let stocks = stocks.clone();
        thread::spawn(move || directory_patrol(stocks, max_stocks, &directories));
    }
}


fn file_patrol(stocks: collector::Stocks, max_stocks: usize, targets: &Vec<String>) {
    let mut ino = INotify::init().unwrap();
    let mut table: HashMap<i32, HashSet<String>> = HashMap::new();

    for target in targets {
        let path = Path::new(target);
        if let Some(dir) = path.parent() {
            let wd = ino.add_watch(dir, EVENTS).unwrap();
            let name = path.file_name().unwrap().to_str().unwrap().to_string();
            table.entry(wd).or_insert_with(|| HashSet::new()).insert(name);
        }
    }

    loop {
        let events = ino.wait_for_events().unwrap();

        for event in events.iter() {
            if !event.is_dir() {
                if let Some(set) = table.get(&event.wd) {
                    if set.contains(event.name.to_str().unwrap()) {
                        trace!("file_changes: name = {}, wd = {}", event.name.to_str().unwrap(), event.wd);
                        collector::renew(stocks.clone(), max_stocks)
                    }
                }
            }
        }
    }
}


fn directory_patrol(stocks: collector::Stocks, max_stocks: usize, targets: &Vec<String>) {
    let mut ino = INotify::init().unwrap();

    for target in targets {
        ino.add_watch(Path::new(target), EVENTS).unwrap();
    }

    loop {
        let events = ino.wait_for_events().unwrap();

        for event in events.iter() {
            if !event.is_dir() {
                trace!("file_changes: {}", event.name.to_str().unwrap());
                collector::renew(stocks.clone(), max_stocks)
            }
        }
    }
}