use crate::compsys::ported::_arguments::_arguments;
use crate::compsys::ported::_wanted::_wanted;
use crate::ported::exec::dispatch_function_call;
use crate::ported::modules::zutil::bin_zstyle;
use crate::ported::params::getaparam;
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 zstyle_get(context: &str, style: &str) -> Vec<String> {
let scratch = "_azhw_zstyle_get";
bin_zstyle(
"zstyle",
&[
"-g".to_string(),
scratch.to_string(),
context.to_string(),
style.to_string(),
],
&make_ops(),
0,
);
getaparam(scratch).unwrap_or_default()
}
fn strip_num_colon(s: &str) -> String {
if let Some((head, rest)) = s.split_once(':') {
if !head.is_empty() && head.bytes().all(|b| b.is_ascii_digit()) {
return rest.to_string();
}
}
s.to_string()
}
pub fn _add_zle_hook_widget_types(args: &[String]) -> i32 {
let _ = dispatch_function_call("add-zle-hook-widget", &["-h".to_string()]);
let tmp = zstyle_get("zle-hook", "types");
let mut cadd: Vec<String> = args.to_vec();
cadd.push("-M".to_string());
cadd.push("L:|=zle-".to_string());
cadd.push("-M".to_string());
cadd.push("r:|-=* r:|=*".to_string());
cadd.push("--".to_string());
cadd.extend(tmp.iter().map(|t| format!("zle-{}", t)));
bin_compadd("compadd", &cadd, &make_ops(), 0)
}
pub fn _add_zle_hook_widget_widgets(_args: &[String]) -> i32 {
let opt_args = getaparam("opt_args").unwrap_or_default();
let has_d = opt_args
.chunks(2)
.any(|kv| kv.first().map(String::as_str) == Some("-d"));
if has_d {
let line = getaparam("line").unwrap_or_default();
let ctx = line.first().cloned().unwrap_or_default();
let tmp = zstyle_get(&ctx, "widgets");
let mut wargs: Vec<String> = vec![
"widgets".to_string(),
"expl".to_string(),
"installed hook".to_string(),
"compadd".to_string(),
"--".to_string(),
];
wargs.extend(tmp.iter().map(|t| strip_num_colon(t)));
if _wanted(&wargs) == 0 {
return 0; }
} else {
let wargs: Vec<String> = vec![
"widgets".to_string(),
"expl".to_string(),
"widget".to_string(),
"_widgets".to_string(),
"-g".to_string(),
"user:*".to_string(),
];
if _wanted(&wargs) == 0 {
return 0; }
}
1 }
pub fn _add_zle_hook_widget(args: &[String]) -> i32 {
let mut call: Vec<String> = vec![
"-s".to_string(),
"-w".to_string(),
"-S".to_string(),
":".to_string(),
"(-d -D -U -z -k)-L[output in form of 'zstyle' commands]".to_string(),
"(-L -D -U -z -k)-d[remove HOOK from the array]".to_string(),
"(-L -d -U -z -k)-D[interpret HOOK as pattern to remove from the array]".to_string(),
"(-L -d -D)-U[suppress alias expansion for functions]".to_string(),
"(-L -d -D -k)-z[mark function for zsh-style autoloading]".to_string(),
"(-L -d -D -z)-k[mark function for ksh-style autoloading]".to_string(),
":hook type:_add-zle-hook-widget_types".to_string(),
":widget:_add-zle-hook-widget_widgets".to_string(),
];
call.extend_from_slice(args);
crate::compsys::ported::shared::call_compfn("_arguments", &call, || _arguments(&call))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn strip_num_colon_removes_leading_index() {
assert_eq!(strip_num_colon("42:my-widget"), "my-widget");
assert_eq!(strip_num_colon("0:x"), "x");
assert_eq!(strip_num_colon("foo:bar"), "foo:bar");
assert_eq!(strip_num_colon("plain"), "plain");
assert_eq!(strip_num_colon(":x"), ":x");
}
#[test]
fn arguments_call_carries_full_spec_set() {
let mut call: Vec<String> = vec!["-s".into(), "-w".into(), "-S".into(), ":".into()];
let specs = 8;
for _ in 0..specs {
call.push("x".into());
}
assert_eq!(call.len(), 4 + specs);
}
#[test]
fn entry_returns_int_without_completion_context() {
let _g = crate::test_util::global_state_lock();
crate::ported::zle::complete::INCOMPFUNC.store(0, std::sync::atomic::Ordering::Relaxed);
let rc = _add_zle_hook_widget(&[]);
assert!((0..=300).contains(&rc));
}
}