use crate::ported::params::{getaparam, getsparam, setaparam};
use crate::ported::zle::complete::bin_compadd;
use crate::ported::zsh_h::{options, MAX_OPS};
fn make_ops() -> options {
options {
ind: [0u8; MAX_OPS],
args: Vec::new(),
argscount: 0,
argsalloc: 0,
}
}
fn resolve_array_arg(s: &str) -> Vec<String> {
if s.starts_with('(') && s.ends_with(')') {
s[1..s.len() - 1]
.split_whitespace()
.map(|w| w.to_string())
.collect()
} else {
getaparam(s).unwrap_or_default()
}
}
pub fn _multi_parts(args: &[String]) -> i32 {
let mut idx = 0usize;
while idx < args.len() {
let a = &args[idx];
if a.starts_with('-') && a.len() > 1 {
if matches!(
a.as_str(),
"-J" | "-V" | "-P" | "-S" | "-M" | "-X" | "-F" | "-r" | "-R"
) && idx + 1 < args.len()
{
idx += 2;
} else {
idx += 1;
}
} else {
break;
}
}
if idx + 1 >= args.len() {
return 1;
}
let sep = args[idx].clone();
let arr = resolve_array_arg(&args[idx + 1]);
let prefix = getsparam("PREFIX").unwrap_or_default();
let suffix = getsparam("SUFFIX").unwrap_or_default();
let combined = format!("{}{}", prefix, suffix);
let parts: Vec<&str> = combined.split(&sep as &str).collect();
let current = parts.last().copied().unwrap_or("");
let completed_prefix = parts[..parts.len().saturating_sub(1)].join(&sep);
let completed_prefix = if completed_prefix.is_empty() {
String::new()
} else {
format!("{}{}", completed_prefix, sep)
};
let matches: Vec<String> = arr
.iter()
.filter_map(|entry| {
let parts: Vec<&str> = entry.split(&sep as &str).collect();
let p_idx = combined.matches(&sep as &str).count();
parts.get(p_idx).and_then(|p| {
if p.starts_with(current) {
Some(p.to_string())
} else {
None
}
})
})
.collect();
if matches.is_empty() {
return 1;
}
setaparam("_multi_parts_arr", matches);
let compadd_argv: Vec<String> = vec![
"-P".to_string(),
completed_prefix,
"-a".to_string(),
"_multi_parts_arr".to_string(),
];
bin_compadd("compadd", &compadd_argv, &make_ops(), 0)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ported::params::setsparam;
#[test]
fn returns_one_with_no_matches() {
let _g = crate::test_util::global_state_lock();
let _ = setsparam("PREFIX", "xyz");
let _ = setsparam("SUFFIX", "");
let _r = _multi_parts(&["/".to_string(), "(foo/bar baz/qux)".to_string()]);
}
}