lnchr 0.2.2

A fuzzy terminal app launcher
use std::collections::HashMap;
use std::env;
use std::path::PathBuf;
use std::os::unix::process::CommandExt;
use std::process::{Command, Stdio};

use crate::path_ext::IsExecutable;
use crate::provider::{Provider, run_provider};

pub struct BinProvider;

impl Provider for BinProvider {
    type Item = PathBuf;

    fn title(&self) -> &str {
        "run"
    }

    fn collect(&self) -> HashMap<String, PathBuf> {
        let paths = env::var_os("PATH")
            .map(|p| env::split_paths(&p).collect::<Vec<_>>())
            .unwrap_or_default();
        let mut binaries = HashMap::new();
        for dir in &paths {
            let Ok(entries) = dir.read_dir() else {
                continue;
            };
            for entry in entries.flatten() {
                let path = entry.path();
                if path.is_executable()
                    && let Some(name) = path.file_name().and_then(|f| f.to_str())
                {
                    binaries.entry(name.to_string()).or_insert(path);
                }
            }
        }
        binaries
    }

    fn launch(&self, item: &PathBuf) {
        unsafe {
            Command::new(item)
                .stdin(Stdio::null())
                .stdout(Stdio::null())
                .stderr(Stdio::null())
                .pre_exec(|| {
                    libc::setsid();
                    Ok(())
                })
                .spawn().ok();
        }
    }
}

pub fn run() -> i32 {
    run_provider(BinProvider)
}