use crate::compsys::ported::_description::_description;
use crate::compsys::ported::_requested::_requested;
use crate::compsys::ported::_tags::_tags;
use crate::ported::exec_hooks::dispatch_function_call;
use crate::ported::modules::zutil::lookupstyle;
use crate::ported::params::{getaparam, getsparam, setsparam};
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 _match() -> i32 {
let opm = get_compstate_str("pattern_match").unwrap_or_default();
let oms = getsparam("_old_match_string").unwrap_or_default();
let _ocsi = get_compstate_str("insert").unwrap_or_default();
let _ocspi = get_compstate_str("pattern_insert").unwrap_or_default();
let mut ret: i32 = 1;
let prefix = getsparam("PREFIX").unwrap_or_default();
let suffix = getsparam("SUFFIX").unwrap_or_default();
let combined = format!("{}{}", prefix, suffix);
let stripped = combined.trim_start_matches(|c| c == '~' || c == '=');
if !stripped.chars().any(|c| matches!(c, '*' | '?' | '[')) {
return 1;
}
let histno = getsparam("HISTNO").unwrap_or_default();
let _ = setsparam(
"_old_match_string",
&format!("{}{}{}", prefix, suffix, histno),
);
let _ = _tags(&["matches".to_string(), "original".to_string()]);
let curcontext = getsparam("curcontext").unwrap_or_default();
let ctx = format!(":completion:{}:", curcontext);
let orig = lookupstyle(&ctx, "match-original")
.first()
.cloned()
.unwrap_or_default();
let ins = lookupstyle(&ctx, "insert-unambiguous")
.first()
.cloned()
.unwrap_or_default();
if !orig.is_empty() {
set_compstate_str("pattern_match", "-");
if dispatch_function_call("_complete", &[]).unwrap_or(1) == 0 {
ret = 0;
}
set_compstate_str("pattern_match", &opm);
if ret == 1 && orig == "only" {
return 1;
}
}
if ret != 0 {
set_compstate_str("pattern_match", "*");
if dispatch_function_call("_complete", &[]).unwrap_or(1) == 0 {
ret = 0;
}
set_compstate_str("pattern_match", &opm);
}
if ret == 0 {
let nm: i64 = get_compstate_str("nmatches")
.and_then(|s| s.parse().ok())
.unwrap_or(0);
if ins == "pattern" && nm > 1 {
let new_oms = format!("{}{}{}", prefix, suffix, histno);
let cur_insert = get_compstate_str("insert").unwrap_or_default();
if oms == new_oms && cur_insert == "automenu-unambiguous" {
set_compstate_str("insert", "automenu");
}
let cur_insert2 = get_compstate_str("insert").unwrap_or_default();
if !cur_insert2.ends_with("menu") {
set_compstate_str("pattern_insert", "");
set_compstate_str("insert", "");
}
}
let unambig = get_compstate_str("unambiguous").unwrap_or_default();
if matches!(ins.as_str(), "true" | "yes" | "on" | "1")
&& unambig.len() >= combined.len()
{
set_compstate_str("pattern_insert", "unambiguous");
} else if _requested(&["original".to_string()]) == 0 {
let orig_style_on =
lookupstyle(&ctx, "original").first().map(|v| {
matches!(v.as_str(), "yes" | "true" | "1" | "on")
}).unwrap_or(false);
if nm > 1 || orig_style_on {
let _ = _description(&[
"-V".to_string(),
"original".to_string(),
"expl".to_string(),
"original".to_string(),
]);
let expl = getaparam("expl").unwrap_or_default();
let mut compadd_argv = expl;
compadd_argv.push("-U".to_string());
compadd_argv.push("-Q".to_string());
compadd_argv.push("-".to_string());
compadd_argv.push(combined.clone());
let _ = bin_compadd("compadd", &compadd_argv, &make_ops(), 0);
}
}
}
ret
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_pattern_returns_one() {
let _g = crate::test_util::global_state_lock();
let _ = setsparam("PREFIX", "plain");
let _ = setsparam("SUFFIX", "");
assert_eq!(_match(), 1);
}
}