use crate::compsys::ported::_comp_locale::_comp_locale;
use crate::ported::modules::zutil::lookupstyle;
use crate::ported::params::getsparam;
use std::env;
use std::process::Command;
pub fn _call_program(args: &[String]) -> i32 {
let mut argv: Vec<String> = args.to_vec();
let mut use_locale = true;
if let Some(first) = argv.first() {
if first == "-p" {
argv.remove(0);
} else if first == "-l" {
argv.remove(0);
use_locale = false;
}
}
if argv.is_empty() {
return 1;
}
let curcontext = getsparam("curcontext").unwrap_or_default();
let style_ctx = format!(":completion:{}:{}", curcontext, argv[0]);
let styled = lookupstyle(&style_ctx, "command")
.first()
.cloned()
.unwrap_or_default();
let cmdline: Vec<String> = if !styled.is_empty() {
if let Some(rest) = styled.strip_prefix('-') {
let mut v: Vec<String> = vec![rest.to_string()];
if argv.len() > 1 {
v.extend(argv[1..].iter().cloned());
}
v
} else {
vec![styled]
}
} else {
if argv.len() > 1 {
argv[1..].to_vec()
} else {
return 1;
}
};
let mut cmd = Command::new("sh");
cmd.arg("-c").arg(cmdline.join(" "));
cmd.env("COLUMNS", "999");
if use_locale {
let saved_lang = env::var("LANG").ok();
let saved_ctype = env::var("LC_CTYPE").ok();
let _ = _comp_locale();
cmd.env("LANG", env::var("LANG").unwrap_or_else(|_| "C".to_string()));
if let Some(ct) = env::var("LC_CTYPE").ok() {
cmd.env("LC_CTYPE", ct);
}
if let Some(v) = saved_lang {
env::set_var("LANG", v);
}
if let Some(v) = saved_ctype {
env::set_var("LC_CTYPE", v);
}
}
let output = match cmd.output() {
Ok(o) => o,
Err(_) => return 1,
};
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
let _ = crate::ported::params::setsparam("REPLY", &stdout);
if output.status.success() {
0
} else {
1
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_args_returns_one() {
let _g = crate::test_util::global_state_lock();
assert_eq!(_call_program(&[]), 1);
}
#[test]
fn invokes_true_command_successfully() {
let _g = crate::test_util::global_state_lock();
let r = _call_program(&["my-style-key".to_string(), "true".to_string()]);
assert_eq!(r, 0);
}
#[test]
fn invokes_false_command_returns_one() {
let _g = crate::test_util::global_state_lock();
let r = _call_program(&["my-style-key".to_string(), "false".to_string()]);
assert_eq!(r, 1);
}
#[test]
fn captures_stdout_into_reply() {
let _g = crate::test_util::global_state_lock();
let _ = _call_program(&[
"my-style-key".to_string(),
"printf".to_string(),
"hello".to_string(),
]);
assert_eq!(getsparam("REPLY").as_deref(), Some("hello"));
}
}