use crate::compsys::ported::_description::_description;
use crate::ported::modules::zutil::lookupstyle;
use crate::ported::params::{getaparam, getsparam, setaparam, setsparam, unsetparam};
use crate::ported::zle::compcore::{get_compstate_str, set_compstate_str};
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,
}
}
pub fn _all_matches() -> i32 {
let curcontext = getsparam("curcontext").unwrap_or_default();
let ctx = format!(":completion:{}:", curcontext);
let old = lookupstyle(&ctx, "old-matches")
.first()
.cloned()
.unwrap_or_default();
if matches!(old.as_str(), "only" | "true" | "yes" | "1" | "on") {
let old_list = get_compstate_str("old_list").unwrap_or_default();
if !old_list.is_empty() {
set_compstate_str("insert", "all");
set_compstate_str("old_list", "keep");
return 0;
}
if old.contains("only") {
return 1;
}
}
let mut postfuncs = getaparam("comppostfuncs").unwrap_or_default();
if !postfuncs.iter().any(|f| f == "_all_matches_end") {
postfuncs.push("_all_matches_end".to_string());
setaparam("comppostfuncs", postfuncs);
}
let _ = setsparam("_all_matches_context", &ctx);
1
}
pub fn _all_matches_end() -> i32 {
let ctx = getsparam("_all_matches_context").unwrap_or_default();
let mut not = lookupstyle(&ctx, "avoid-completer");
if not.is_empty() {
not = vec![
"_expand".to_string(),
"_old_list".to_string(),
"_correct".to_string(),
"_approximate".to_string(),
];
}
let nmatches: i64 = get_compstate_str("nmatches")
.and_then(|s| s.parse().ok())
.unwrap_or(0);
let completer = getsparam("_completer").unwrap_or_default();
let completer_underscored = format!("_{}", completer);
let in_not = not
.iter()
.any(|n| n == &completer || n == &completer_underscored);
if nmatches > 1 && !in_not {
if lookupstyle(&ctx, "insert")
.first()
.map(|v| matches!(v.as_str(), "yes" | "true" | "1" | "on"))
.unwrap_or(false)
{
set_compstate_str("insert", "all");
} else {
let _ = _description(&[
"all-matches".to_string(),
"expl".to_string(),
"all matches".to_string(),
]);
let expl = getaparam("expl").unwrap_or_default();
let mut compadd_argv = expl;
compadd_argv.push("-C".to_string());
let _ = bin_compadd("compadd", &compadd_argv, &make_ops(), 0);
}
}
unsetparam("_all_matches_context");
0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn registers_postfunc_and_returns_one() {
let _g = crate::test_util::global_state_lock();
setaparam("comppostfuncs", Vec::new());
let r = _all_matches();
assert_eq!(r, 1);
let postfuncs = getaparam("comppostfuncs").unwrap_or_default();
assert!(postfuncs.iter().any(|f| f == "_all_matches_end"));
}
}