4

I want to replace an existing zsh completion function and keep a reference to the original (from here). E.g. to make tab completion always suggest nice as first word in a command line:

eval "$(declare -f _normal | sed '1s/.*/_original&/')"
_normal() {
  if [[ $CURRENT == 1 ]] ; then
    # suggest only "nice" as first word
    _wanted commands expl "be nice" compadd nice
  else
    # do normal completion afterwards
    _original_normal
  fi
}

The problem, as far as I understand it right now, is that in a fresh zsh _normal is not loaded yet:

PROMPT> functions _normal
_normal () {
    # undefined
    builtin autoload -XUz
}

yet, after I hit ⇥ for the first time, it is loaded:

PROMPT> functions _normal
_normal () {
    local _comp_command1 _comp_command2 _comp_command skip
    if [[ "$1" = -s ]]
    then
        skip=(-s) 
    else
        skip=() 
        _compskip='' 
 <snap>

This means the above redefinition of _normal cannot be done in my .zshrc, as only the builtin autoload bit gets written to _original_normal which then cannot get loaded (no file _original_normal in the fpath).

Is there a way how I can force loading _normal?

PS: It appears doing the redefinition of _normal works if I do it in a shell after hitting tab before.

2 Answers 2

6

In zsh, you can pass the +X flag to autoload to load a function from $fpath without executing it.

Also, you can copy a function to a new name by manipulating the functions array.

autoload -Uz +X _normal
functions[_original_normal]=$functions[_normal]
_normal () {
  …
}
1
  • 1
    @GAD3R ??? “Zsh” isn't code, it's the name of a piece of software (a proper noun, but like many names of software, not normally capitalized). Commented Jan 9, 2017 at 1:17
0

for now I run

_normal &> /dev/null || true

_normal like other completions should usually not be called from the shell directly and (without the redirection) one gets an error message:

_default:compcall:12: can only be called from completion function

the || true seems unnecessary here, as _normal invoked like this doesn't return an error code.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .