[arch-projects] rc.d bash_completion

Dave Reisner d at falconindy.com
Wed Jun 8 08:58:00 EDT 2011


On Wed, Jun 08, 2011 at 01:32:36PM +0200, Andrwe wrote:
> Hi,
> 
> I've improved the bash-completion of rc.d.
> I created a patch for latest git
> (https://github.com/seblu/arch-initscripts/tree/).
> 
> The patched version extracts all actions of an initscript and adds
> them to the list of possible actions and only list initscripts
> supporting the given action.
> 
> 
> Kind regards,
> Andrwe

> diff --git a/bash-completion b/bash-completion
> index 5151972..03ce0e6 100644
> --- a/bash-completion
> +++ b/bash-completion
> @@ -1,22 +1,50 @@
> -# rc.d bash completion by Seblu <seblu at seblu.net>
> -
> -_rc.d ()
> +# rc.d completion
> +#
> +#  Author: Andrwe Lord Weber
> +#  Mail: lord-weber-andrwe <at> andrwe <dot> org
> +#

Ouch. Really? Not going to leave _any_ credit behind for the original
author?

> +which rc.d >/dev/null 2>&1 &&

'type -P', never which.

> +_rc_d()
>  {
> -	local action="help list start stop reload restart"
> -	local cur="${COMP_WORDS[COMP_CWORD]}"
> -	local caction="${COMP_WORDS[1]}"
> -	if ((${COMP_CWORD} == 1)); then
> -		COMPREPLY=($(compgen -W "${action}" -- "$cur"))
> -	elif [[ "$caction" =~ help|list ]]; then
> -		COMPREPLY=()
> -	elif [[ "$caction" == start ]]; then
> -		COMPREPLY=($(comm -23 <(cd /etc/rc.d && compgen -f -X 'functions*' "$cur"|sort) <(cd /run/daemons/ && compgen -f "$cur"|sort)))
> -	elif [[ "$caction" =~ stop|restart|reload ]]; then
> -		COMPREPLY=($(cd /run/daemons/ && compgen -f "$cur"|sort))
> -	elif ((${COMP_CWORD} > 1)); then
> -		COMPREPLY=($(cd /etc/rc.d && compgen -f -X 'functions*' "$cur"|sort))
> +	local cur prev initdir long_opts cmds shoptExtglob
> +
> +	shoptExtglob="$(shopt -p | grep extglob)"

No grep needed here:

  shopt -p extglob

We don't use camel case, either.

> +	shopt -s extglob
> +
> +	long_opts='list help'
> +	initdir=/etc/rc.d
> +	cmds="$(sed '/#.*sh/,/^.*case\s*"*\${*1}*"*.*/ { /^.*case\s*"*\${*1}*"*.*/!d };s/^.*case\s*"*\${*1}*"*.*/;;/g;/;;/,/^\s*.*)\s*$/ !d;/^\s*.*)\s*$/ !d;/\*/d;/;;/d;s/\s*//g;s/)//g;s/|/ /g' ${initdir}/!(*functions*) | LANG=C sort -u | tr '\n' ' ')"

The default IFS is '\n\t ', so the final tr isn't needed here. This
really should be an array, too.

> +
> +	_get_comp_words_by_ref cur prev
> +
> +	cmd="${COMP_WORDS[1]}"
> +
> +	if [[ "${cmd}" =~ ^(${cmds// /|}|${long_opts// /|})$ ]] && [ -n "${cmd}" ]; then
> +		daemons="$(ls -1 /run/daemons/ | tr '\n' '|')"

Never parse ls. The need for the pipe delimiter isn't obvious either.

  pushd /run/daemons &>/dev/null && { daemons=(*); popd &>/dev/null; }

If you really need the pipe delimiter, you can then later:

  ( IFS='|'; echo "${daemons[*]}" )

> +		case "${cmd}" in
> +			start)
> +		                COMPREPLY+=( $( compgen -W '`grep -El "^[ ]*[^ ]*${cmd}[|\)][^ ]*\)*[ ]*$" ${initdir}/* | sed 's#${initdir}/##' | grep -vE "^(${daemons})$"`' -- "$cur" ) )
> +				;;
> +			stop|restart|reload)
> +		                COMPREPLY+=( $( compgen -W '`grep -El "^[ ]*[^ ]*${cmd}[|\)][^ ]*\)*[ ]*$" ${initdir}/* | sed 's#${initdir}/##' | grep -E "^(${daemons})$"`' -- "$cur" ) )
> +				;;
> +			*)
> +		                COMPREPLY+=( $( compgen -W '`grep -El "^[ ]*[^ ]*${cmd}[|\)][^ ]*\)*[ ]*$" ${initdir}/* | sed 's#${initdir}/##'`' -- "$cur" ) )

We use $() for command substitution, not backticks.

> +				;;
> +		esac
> +	else 
> +		COMPREPLY=( $( compgen -W '${long_opts} ${cmds}' -- "$cur" ) )
>  	fi
> -}
> -complete -F _rc.d rc.d
>  
> -# vim: set ts=2 sw=2 ft=sh noet:
> +	${shoptExtglob}
> +	return 0
> +} &&
> +complete -F _rc_d rc.d
> +
> +# Local variables:
> +# mode: shell-script
> +# sh-basic-offset: 4
> +# sh-indent-comment: t
> +# indent-tabs-mode: nil
> +# End:
> +# vim: ts=2 sw=2 et filetype=sh

A general lack of commenting and an overbearing sense of overcomplicating
things gets a NACK from me.

d



More information about the arch-projects mailing list