$ timidity <tab><tab> broken iuse pause start usesme ineed needsme restart stop zap Expected: directories, and .midi files. This is because timidity installs /etc/init.d/timidity which gets picked up by the /etc/init.d/* completion: complete -W "start stop restart pause zap ineed needsme iuse usesme broken" \ $(for i in /etc/init.d/*; do echo ${i##*/}; done) I don't see why this can't just be complete -W "start stop restart pause zap ineed needsme iuse usesme broken" \ /etc/init.d/* after all you can't control an initscript just with its name, and completing with full path works for bash.
Oh, and the extra opts= stuff needs handling as well - I think something like # # completion for Gentoo style init # _gentoo_style_init() { local script="${COMP_WORDS[0]}" [[ -r "$script" ]] || return 1 COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; source "$script"; echo "$opts")) [[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap) return 0 } complete -F _gentoo_style_init /etc/init.d/* should work.
Oops. That should be: # # completion for Gentoo style init # _gentoo_style_init() { local script="${COMP_WORDS[0]}" [[ "$COMP_CWORD" -gt 1 ]] && return 1 [[ -r "$script" ]] || return 1 COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; source "$script"; echo "$opts")) [[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap) COMPREPLY=($(compgen -W "${COMPREPLY[*]}" ${COMP_WORDS[COMP_CWORD]})) return 0 } complete -F _gentoo_style_init /etc/init.d/*
Gah! That's wrong as well - luckily I wasn't running as root when I typed /etc/init.d/shutdown.sh <tab>... Perhaps sourcing /etc/init.d-scripts is a bad idea? I think it's probably OK if they're proper runscript-scripts: # # completion for Gentoo style init # _gentoo_style_init() { local script="${COMP_WORDS[0]}" local cur="${COMP_WORDS[$COMP_CWORD]}" [[ -r "$script" ]] || return 1 if [[ "$(head -n 1 "$script")" = "#!/sbin/runscript"* ]]; then [[ "$COMP_CWORD" -gt 1 ]] && return 1 COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; source "${script}"; echo "${opts}")) [[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap) COMPREPLY=($(compgen -W "${COMPREPLY[*]}" "${cur}")) else COMPREPLY=($(compgen -o default "${cur}")) fi return 0 } complete -F _gentoo_style_init /etc/init.d/*
Gah, thought I had already commented on this bug and CC'd upstream... Ed, can you think of a better way to do it w/o sourcing the rc scripts? just seems like an icky way to go about doing it.
(Sorry for the wait.) Hmm. Obviously we have to source something if we want to handle custom opts. It should work to replace in the above source "${script}" with eval "$(grep '^opts=' "${script}")" Admittedly this is a little brittle but we don't expect initscripts to be true bash scripts (read the monstrosity that is cachedepends.awk). # # completion for Gentoo style init # _gentoo_style_init() { local script="${COMP_WORDS[0]}" local cur="${COMP_WORDS[$COMP_CWORD]}" if [[ ( -f "$script" || -h "$script" ) && -r "$script" ]] \ && [[ "$script" != *.sh ]] \ && [[ "$(head -n 1 "$script")" = "#!/sbin/runscript" ]]; then [[ "$COMP_CWORD" -gt 1 ]] && return 1 COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; eval "$(grep '^opts=' "${script}")"; echo "${opts}")) [[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap) COMPREPLY=($(compgen -W "${COMPREPLY[*]}" "${cur}")) else COMPREPLY=($(compgen -o default "${cur}")) fi return 0 } complete -F _gentoo_style_init /etc/init.d/*
Bah ok. I didn't realize what you were originally attempting to do. Fixed.