#autoload # This completer function is intended to be used as the first completer # function and allows one to say more explicitly when and how the word # from the line should be expanded than expand-or-complete. # This function will allow other completer functions to be called if # the expansions done produce no result or do not change the original # word from the line. local exp word="$PREFIX$SUFFIX" group=-V expl expl2 disp orig menu prompt local curcontext="${curcontext}:expand" expr descr # First, see if we should insert all *completions*. if _style -s '' completions expr && [[ "${(e):-\$[$expr]}" -eq 1 ]]; then compstate[insert]=all return 1 fi # Do this only for the first global matcher. [[ "$compstate[matcher]" -le 1 ]] || return 1 # In exp we will collect the expansion. exp=("$word") # First try substitution. That weird thing spanning multiple lines # changes quoted spaces, tabs, and newlines into spaces. _style -s '' substitute expr && [[ "${(e):-\$[$expr]}" -eq 1 ]] && exp=( "${(e)exp//\\[ ]/ }" ) # If the array is empty, store the original string again. [[ -z "$exp" ]] && exp=("$word") # Now try globbing. _style -s '' glob expr && [[ "${(e):-\$[$expr]}" -eq 1 ]] && exp=( ${~exp}(N) ) # If we don't have any expansions or only one and that is the same # as the original string, we let other completers run. [[ $#exp -eq 0 || ( $#exp -eq 1 && "$exp[1]" = "$word"(|\(N\)) ) ]] && return 1 # Get the options for adding the original string and `all'-string. _style -s '' original orig _style -s '' menu menu _style -s '' prompt prompt _style -s descriptions format descr if [[ "$orig" = *show* ]]; then if [[ -n "$descr" ]]; then expl=(-X "${descr//\\%d/original}") else expl=() fi else expl=(-n) fi if [[ -n "$menu" && "$menu" != *only* && "$menu" = *show-all* ]]; then if [[ -n "$descr" ]]; then expl2=(-ld disp -X "${descr//\\%d/all words}") else expl2=(-ld disp ) fi disp=( "$exp" ) if [[ ${#disp[1]} -gt COLUMNS-5 ]]; then disp=( "${disp[1][1,COLUMNS-5]}..." ) fi else expl2=(-n) fi # Quote the results and remove unnecessary quotes before `='s. exp=( "${(@)${(@)${(@q)exp}//\\\\=/=}/#=/\\=}" ) # We have expansions, should we menucomplete them? if [[ -z "$menu" ]]; then # No, so if the user only wants a list, we add the strings # separately. Otherwise we add the whole array as one string, # probably also adding the original string. if [[ -z "$compstate[insert]" ]]; then compadd -U -V _expand -Q - "$exp[@]" else [[ -n "$orig" && "$orig" != *last* ]] && compadd "$expl[@]" -UQ -V _expand_original - "$word" compadd -UQ -V _expand - "$exp" [[ -n "$orig" && "$orig" = *last* ]] && compadd "$expl[@]" -UQ -V _expand_original - "$word" compstate[insert]=menu fi else # Sorting? We just use a different group type then. [[ "$menu" = *sort* ]] && group=-J # Now add the expansion string, probably also adding the original # and/or the string containing all expanded string. [[ -n "$orig" && "$orig" != *last* ]] && compadd "$expl[@]" -UQ -V _expand_original - "$word" [[ $#exp -ne 1 && "$menu" = *last* && "$menu" != *only* ]] && compadd "$expl2[@]" -UQ -V _expand_all - "$exp" if [[ -z "$prompt" ]]; then compadd -UQ $group _expand - "$exp[@]" else compadd -UQ -X "${prompt//\\%o/$word}" \ $group _expand - "$exp[@]" fi [[ $#exp -ne 1 && "$menu" != *last* && "$menu" != *only* ]] && compadd "$expl2[@]" -UQ -V _expand_all - "$exp" [[ -n "$orig" && "$orig" = *last* ]] && compadd "$expl[@]" -UQ -V _expand_original - "$word" compstate[insert]=menu fi return 0