#compdef texdoc

__texdoc() {
  local options=(
    "(- : *)"{-h,--help}"[Print this help message.]"
    "(- : *)"{-V,--version}"[Print the version number.]"
    "(- : *)"{-f,--files}"[Print the list of configuration files used.]"
    "(- : *)"--just-view"[Display FILE, given with full path (no searching).]: :_files"
    "(- : *)"--print-completion"[Print SHELL completion.]:shell:(zsh)"
    + mode
    "(mode)"{-w,--view}"[Use view mode: start a viewer. (default)]"
    "(mode)"{-m,--mixed}"[Use mixed mode (view or list).]"
    "(mode)"{-l,--list}"[Use list mode: show a list of results.]"
    "(mode)"{-s,--showall}"[Use showall mode: show also "bad" results.]"
    + interaction
    "(interaction)"{-i,--interact}"[Use interactive menus. (default)]"
    "(interaction)"{-I,--nointeract}"[Use plain lists, no interaction required.]"
    "(interaction)"{-M,--machine}"[Machine-readable output for lists (implies -I).]"
    + debug
    "(debug)"{-q,--quiet}"[Suppress warnings and most error messages.]"
    "(debug)"{-v,--verbose}"[Print additional information (e.g., viewer command).]"
    "(debug)"-D"[Activate all debug output (equal to "--debug=all").]"
    "(debug)"{-d,--debug=-}"[Activate debug output restricted to LIST.]:list:(config docfile files score search texdocs tlpdb version view)"
    "(debug)"-c"[Set configuration item NAME to VALUE.]:name=value:(badbasename_list badext_list basename_list debug_list ext_list fuzzy_level interact_switch lang lastfile_switch machine_switch max_lines mode online_url rm_dir rm_file suffix_list texlive_tlpdb unzip_ verbosity_level viewer_ zipext_list)"
  )
  _arguments -C -A $options '*:document:__texdoc_argument'
}

__texdoc_argument() {
  _alternative \
    "files:local documents:$(__texdoc_massage __texdoc_localfiles)" \
    "aliases:aliases:$(__texdoc_massage __texdoc_aliases)" \
    "packages:packages:$(__texdoc_massage __texdoc_packages)" \
    "pdf:documents:$(__texdoc_massage __texdoc_lsr pdf)" \
}

# stdout of $@ is split at linebreaks, ordered, element-wise quoted, space joined, and ripped of empty words
__texdoc_massage() { echo \(${(j: :)${(@q)${(ou)${(f)"$($@ 2>/dev/null)"}}}:#"''"}\) }

__texdoc_localfiles() { find -L "$(kpsewhich -var-value TEXMFHOME)/doc" -type f -printf '%f\n' }
__texdoc_aliases() { sed -n 's/^alias[^ ]* \(.*\) = .*$/\1/p' "${(f@)"$(texdoc --files|sed -n 's/^\s\+active\s\+//p')"}" }
__texdoc_lsr() { grep -h "\\.$1$" "${(f@)"$(kpsewhich -all ls-R)"}" }
__texdoc_packages() { # Use texlive.tlpdb if it exists, otherwise fallback to texdoc's own data
  sed -n '/\./!s/^name //p' "${(f@)"$(kpsewhich -all -cnf-line='TEXINPUTS={$TEXMFROOT,$TEXMFHOME}/tlpkg' -format=tex texlive.tlpdb)"}" \
  || sed -n 's/^  \["\([^"]*\)"\] = {$/\1/p' "$(kpsewhich Data.tlpdb.lua)"
}

if [[ $zsh_eval_context[-1] == loadautofunc ]]; then
  # autoload from fpath, call function directly
  __texdoc "$@"
else
  # eval/source/. command, register function for later
  compdef __texdoc texdoc
fi

