Repository navigation
usage g completion-init zsh (still) breaks default completion with _files (followup of #692) #712
Description
Something still isn't quite right. With the fix, I don't get the error message anymore, for sure. But:
$ source <(usage g completion-init zsh) $ emacs --<TAB>[completion inserts "\*" here] $ source <(usage g completion-init zsh | sed -e 's/emulate -L zsh//') $ emacs --<TAB>[bell, nothing is inserted]I asked the AI again:
That confirms the diagnosis:
emulate -L zshis clobbering the completion system’s expected option state.The
*insertion is a second symptom of the same thing. Addingnonomatchonly suppresses the error; it lets the bad fallback proceed, so_filestreats the internal*pattern as a literal candidate and inserts it.Better fix
Do not call
_filesafteremulate -L zsh.Instead, preserve the caller’s completion options around the generated code, or only use
emulatein the branch that callsusage.Try this structure:
_usage_default_complete() { local cmd cmdpath cmd="${words[1]}" if [[ "$cmd" == */* ]]; then cmdpath="$cmd" elif (( ${+commands[$cmd]} )); then cmdpath="${commands[$cmd]}" fi if [[ -n "$cmdpath" && -f "$cmdpath" ]]; then local first if IFS= read -r first < "$cmdpath" 2>/dev/null && [[ "$first" == "#!"*"usage"* ]]; then if (( ${+commands[usage]} )); then emulate -L zsh local -a values=() descs=() inserts=() local needs_menu=0 line while IFS= read -r line; do local -a parts=("${(@ps:\t:)line}") values+=("${parts[1]}") descs+=("${parts[2]}") inserts+=("${parts[3]}") [[ "${parts[3]}" == "'"* ]] && needs_menu=1 done < <(command usage complete-word --shell zsh -f "$cmdpath" --cword=$((CURRENT - 1)) -- "${(Q)words[@]}") (( needs_menu )) && compstate[insert]=menu if (( ${#inserts[@]} )); then local -a _usage_display=() local _usage_i _usage_max=0 _usage_v _usage_pad for _usage_v in "${values[@]}"; do (( ${#_usage_v} > _usage_max )) && _usage_max=${#_usage_v} done for ((_usage_i=1; _usage_i<=${#values[@]}; _usage_i++)); do if [[ -n "${descs[_usage_i]}" ]]; then _usage_pad=$(( _usage_max - ${#values[_usage_i]} )) _usage_display+=("${values[_usage_i]}${(l:_usage_pad:: :)} -- ${descs[_usage_i]}") else _usage_display+=("${values[_usage_i]}") fi done compadd -l -d _usage_display -U -Q -S '' -a inserts fi return $? fi fi fi _files }Smaller patch
Move:
emulate -L zshfrom the top of the function to inside this branch:
if (( ${+commands[usage]} )); then emulate -L zsh ... fiThat way
_filesruns in the original completion environment.Why deleting it works
Completion functions are already called in a special context.
_filesexpects that context. Top-levelemulate -L zshresets options too broadly, so fallback completion breaks.
setopt nonomatchmasks the exception but leaves the completion semantics wrong, hence literal*insertion.
Activity
fix(zsh): stop the completion-init handler from breaking file complet…