use crate::ported::exec_hooks::dispatch_function_call;
use crate::ported::modules::zutil::{lookupstyle, testforstyle};
use crate::ported::params::{getaparam, getiparam, getsparam, setsparam};
use crate::ported::zle::compcore::{get_compstate_str, set_compstate_str};
pub fn _prefix() -> i32 {
let suffix = getsparam("SUFFIX").unwrap_or_default();
if getiparam("_matcher_num") > 1 || suffix.is_empty() {
return 1;
}
let saved_curcontext = getsparam("curcontext").unwrap_or_default();
let saved_isuffix = getsparam("ISUFFIX").unwrap_or_default();
let saved_suffix = suffix.clone();
let ctx = format!(":completion:{}:", saved_curcontext);
let comp_style = lookupstyle(&ctx, "completer");
let comp_list: Vec<String> = if !comp_style.is_empty() {
comp_style
} else {
let completers = getaparam("_completers").unwrap_or_default();
let comp_num = getiparam("_completer_num") as usize;
let upto = comp_num.saturating_sub(1).min(completers.len());
let slice = &completers[..upto];
let ind = slice.iter().position(|c| {
c == "_prefix" || c.starts_with("_prefix:")
});
match ind {
Some(i) => slice[i..].to_vec(),
None => slice.to_vec(),
}
};
if testforstyle(&ctx, "add-space") == 0 {
let _ = setsparam("ISUFFIX", &format!(" {}", suffix));
} else {
let _ = setsparam("ISUFFIX", &suffix);
}
let _ = setsparam("SUFFIX", "");
for tmp in &comp_list {
let bare = tmp.split(':').next().unwrap_or(tmp);
if bare == "_prefix" {
continue;
}
if dispatch_function_call(bare, &[]).unwrap_or(1) == 0 {
let old_list = get_compstate_str("old_list").unwrap_or_default();
let unambig = get_compstate_str("unambiguous").unwrap_or_default();
let unambig_no_suf = unambig.trim_end_matches(&saved_suffix as &str);
let prefix = getsparam("PREFIX").unwrap_or_default();
if !old_list.is_empty() || unambig_no_suf == prefix {
set_compstate_str("to_end", "match");
}
let _ = setsparam("curcontext", &saved_curcontext);
let _ = setsparam("ISUFFIX", &saved_isuffix);
let _ = setsparam("SUFFIX", &saved_suffix);
return 0;
}
}
let _ = setsparam("curcontext", &saved_curcontext);
let _ = setsparam("ISUFFIX", &saved_isuffix);
let _ = setsparam("SUFFIX", &saved_suffix);
1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_suffix_returns_one() {
let _g = crate::test_util::global_state_lock();
let _ = setsparam("SUFFIX", "");
assert_eq!(_prefix(), 1);
}
#[test]
fn returns_one_without_executor() {
let _g = crate::test_util::global_state_lock();
let _ = setsparam("SUFFIX", "rest");
crate::ported::params::setiparam("_matcher_num", 1);
assert_eq!(_prefix(), 1);
}
}