use crate::{desktops::*, DetectionError, Terminal};
use std::{env::var, path::Path};
pub fn detect_terminal_env() -> Result<Terminal, DetectionError> {
let term = var("TERMINAL")?;
Ok(term.into())
}
pub fn detect_terminal_desktop() -> Result<Terminal, DetectionError> {
let desktop = var("XDG_CURRENT_DESKTOP")?;
let desktop = desktop.split(':').last().unwrap_or_default();
match desktop {
"GNOME" => detect_terminal_desktop_gnome(),
"KDE" => detect_terminal_desktop_kde(),
"LXDE" => detect_terminal_desktop_lxde(),
"LXQt" => detect_terminal_desktop_lxqt(),
"XFCE" => detect_terminal_desktop_xfce(),
_ => Err(DetectionError::UnsupportedDesktopError),
}
}
pub(crate) fn path_check(path_var: &Vec<&str>, term: &str) -> Option<String> {
for path in path_var {
let bin = format!("{}/{}", path, term);
let bin_path = Path::new(&bin);
if bin_path.exists() {
return Some(term.to_owned());
}
}
None
}
pub fn detect_terminal_path() -> Result<Terminal, DetectionError> {
let path_var = var("PATH").unwrap_or_default();
let path_var: Vec<&str> = path_var.split(':').collect();
for term in &[
"x-terminal-emulator", "konsole",
"gnome-terminal",
"alacritty",
"terminator",
"st",
"urxvt",
] {
if let Some(term) = path_check(&path_var, term) {
return Ok(term.into());
}
}
Err(DetectionError::FindError)
}
#[cfg(target_os = "linux")]
pub fn detect_terminal() -> Result<Terminal, DetectionError> {
let mut errors = Vec::new();
macro_rules! return_or_add {
($e:expr) => {
match $e {
Ok(term) => return Ok(term),
Err(e) => errors.push(e),
}
};
}
return_or_add!(detect_terminal_env());
return_or_add!(detect_terminal_desktop());
return_or_add!(detect_terminal_path());
Err(DetectionError::MetaError(errors))
}
#[cfg(not(target_os = "linux"))]
fn detect_terminal() -> Result<String, DetectionError> {
panic!("unsupported os")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn env_test() {
let term = Terminal::from("abcterm");
std::env::set_var("TERMINAL", &term.0);
assert!(detect_terminal_env().unwrap() == term);
}
}