use crate::{DetectionError, Terminal};
use configparser::ini::Ini;
use std::{env::var, process::Command};
trait StdoutStringify {
fn stdout_stringify(self)
-> Result<Result<String, std::string::FromUtf8Error>, DetectionError>;
}
impl StdoutStringify for std::io::Result<std::process::Child> {
fn stdout_stringify(
self,
) -> Result<Result<String, std::string::FromUtf8Error>, DetectionError> {
let child = self?;
let output = child.wait_with_output()?;
Ok(String::from_utf8(output.stdout))
}
}
fn get_home() -> String {
var("HOME").unwrap_or_default()
}
pub fn detect_terminal_desktop_cinnamon() -> Result<Terminal, DetectionError> {
let mut maybe_term = Command::new("gsettings")
.arg("get")
.arg("org.cinnamon.desktop.default-applications.terminal")
.arg("exec")
.stdout(std::process::Stdio::piped())
.spawn()
.stdout_stringify()?
.unwrap_or_default()
.trim()
.to_string();
if maybe_term.starts_with('\'') && maybe_term.ends_with('\'') && maybe_term.len() > 1 {
maybe_term = maybe_term[1..maybe_term.len() - 1].to_string();
}
if maybe_term.is_empty() {
Err(DetectionError::DEFindError)
} else {
Ok(maybe_term.into())
}
}
pub fn detect_terminal_desktop_deepin() -> Result<Terminal, DetectionError> {
let mut maybe_term = Command::new("gsettings")
.arg("get")
.arg("org.deepin.desktop.default-applications.terminal")
.arg("exec")
.stdout(std::process::Stdio::piped())
.spawn()
.stdout_stringify()?
.unwrap_or_default()
.trim()
.to_string();
if maybe_term.starts_with('\'') && maybe_term.ends_with('\'') && maybe_term.len() > 1 {
maybe_term = maybe_term[1..maybe_term.len() - 1].to_string();
}
if maybe_term.is_empty() {
Err(DetectionError::DEFindError)
} else {
Ok(maybe_term.into())
}
}
pub fn detect_terminal_desktop_gnome() -> Result<Terminal, DetectionError> {
let mut maybe_term = Command::new("gsettings")
.arg("get")
.arg("org.gnome.desktop.default-applications.terminal")
.arg("exec")
.stdout(std::process::Stdio::piped())
.spawn()
.stdout_stringify()?
.unwrap_or_default()
.trim()
.to_string();
if maybe_term.starts_with('\'') && maybe_term.ends_with('\'') && maybe_term.len() > 1 {
maybe_term = maybe_term[1..maybe_term.len() - 1].to_string();
}
if maybe_term.is_empty() {
Err(DetectionError::DEFindError)
} else {
Ok(maybe_term.into())
}
}
pub fn detect_terminal_desktop_kde() -> Result<Terminal, DetectionError> {
let maybe_term = Command::new("kreadconfig5")
.arg("--group")
.arg("General")
.arg("--key")
.arg("TerminalApplication")
.stdout(std::process::Stdio::piped())
.spawn()
.stdout_stringify()?
.unwrap_or_default()
.trim()
.to_string();
Ok(if maybe_term.is_empty() {
"konsole".into()
} else {
maybe_term.into()
})
}
pub fn detect_terminal_desktop_lxde() -> Result<Terminal, DetectionError> {
let filename = format!(
"{}/.config/lxsession/{}/desktop.conf",
get_home(),
var("XDG_SESSION_DESKTOP").unwrap_or("LXDE".to_string()),
);
let mut config = Ini::new_cs();
if let Err(e) = config.load(filename) {
return Err(DetectionError::IniParseError(e));
};
let Some(term) = config.get("Session", "terminal_manager/command") else {
return Err(DetectionError::DEFindError)
};
Ok(term.into())
}
pub fn detect_terminal_desktop_lxqt() -> Result<Terminal, DetectionError> {
if let Ok(term) = var("LXQT_TERMINAL_EMULATOR") {
return Ok(term.into());
}
let filename = format!("{}/.config/lxqt/session.conf", get_home());
let mut config = Ini::new_cs();
if let Err(e) = config.load(filename) {
return Err(DetectionError::IniParseError(e));
};
let Some(term) = config.get("Environment", "TERM") else {
return Err(DetectionError::DEFindError)
};
Ok(term.into())
}
pub fn detect_terminal_desktop_xfce() -> Result<Terminal, DetectionError> {
let filename = format!("{}/.config/xfce4/helpers.rc", get_home());
let mut config = Ini::new_cs();
if let Err(e) = config.load(filename) {
return Err(DetectionError::IniParseError(e));
};
Ok(config
.get("default", "TerminalEmulator")
.unwrap_or("xfce4-terminal".to_string())
.into())
}