lnchr 0.2.0

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

use crate::path_ext::IsExecutable;

const TERMINALS: &[&str] = &[
    "foot",
    "kitty",
    "alacritty",
    "wezterm",
    "ghostty",
    "gnome-terminal",
    "konsole",
];

fn terminal_args(term: &str) -> &[&str] {
    match term {
        "wezterm" => &["start", "--"],
        "gnome-terminal" => &["--"],
        _ => &["-e"],
    }
}

pub fn find() -> Option<String> {
    if let Ok(term) = env::var("TERMINAL") {
        return Some(term);
    }
    let paths = env::var_os("PATH")
        .map(|p| env::split_paths(&p).collect::<Vec<_>>())
        .unwrap_or_default();

    for term in TERMINALS {
        for dir in &paths {
            if dir.join(term).is_executable() {
                return Some(term.to_string());
            }
        }
    }
    None
}

pub fn exec(command: &[String]) -> bool {
    let Some(term) = find() else {
        return false;
    };
    unsafe {
        Command::new(&term)
            .args(terminal_args(&term))
            .args(command)
            .stdin(Stdio::null())
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .pre_exec(|| {
                libc::setsid();
                Ok(())
            })
            .spawn()
            .is_ok()
    }
}