[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

intelligent rpm command completion in bash



Hi,

I posted a version of this shell script to this list a year or so ago
and thought that many people may find the updated version useful. It
contains several bug-fixes since the last version.

If you're using a version of bash that is 2.04 or later, source this
script and then try hitting <Tab> at various places in your rpm
command line. It's really easier to try it out and get a feel for it
than it is to try to explain what it does.

The full version of the script, which contains programmable completion
functions for many more command Linux commands, can be had from:

	  http://freshmeat.net/projects/bashcompletion/

or from my bash page at:

	  http://www.caliban.org/bash/index.shtml#completion

There was some talk of having this put into the Red Hat distribution,
but for whatever reason, it never came to pass.

Anyway, the script is attached. I hope you find it useful.

Ian
-- 
Ian Macdonald               | Hokey religions and ancient weapons are no 
ian@caliban.org             | substitute for a good blaster at your side.
                            | - Han Solo 
                            | 
                            | 
_rpm()
{
	dashify()
	{
		local i

		for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
			if [ ${#COMPREPLY[i]} -le 2 ]; then
				COMPREPLY[i]=-${COMPREPLY[i]}
			else
				COMPREPLY[i]=--${COMPREPLY[i]}
			fi
		done
	}

	add_package_list()
	{
		if [ -f /var/log/rpmpkgs ]; then
			# using RHL 7.2 - this is quicker than querying the DB
			COMPREPLY=( ${COMPREPLY[@]}
			$( sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9a-z.]\+.*\.rpm$/\1/p' /var/log/rpmpkgs ) )
		else
			COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
			sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9a-z.]\+$/\1/p' ) )
		fi
	}

	file_glob()
	{
		local suffix

		# get extension of current word, if relevant
		suffix=${cur##*.}
		# nullify it if it's not a substring of the extension we're
		# completing on
		[ "$suffix" != "${1:0:${#suffix}}" ] && suffix=""
		COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*${1:${#suffix}} ) )
		# directory completion if all else fails and current word
		# contains a slash
		if [ ${#COMPREPLY[@]} = 0 ] && [[ $cur == */* ]]; then
	    		COMPREPLY=( $( compgen -d $cur ) )
		fi
	}

	local cur cur_nodash prev

	COMPREPLY=()
	cur=${COMP_WORDS[COMP_CWORD]}
	cur_nodash=${cur#-}
	prev=${COMP_WORDS[COMP_CWORD-1]}

	if [ $COMP_CWORD = 1 ]; then
		# first parameter on line
		case "$cur" in
		-b*)
			COMPREPLY=( $( compgen -W 'ba bb bc bi bl bp bs' \
				       $cur_nodash ) )
			dashify
			return 0
			;;
		-t*)
			COMPREPLY=( $( compgen -W 'ta tb tc ti tl tp ts' \
				       $cur_nodash ) )
			dashify
			return 0
			;;
		--*)
			COMPREPLY=( $( compgen -W 'help version initdb \
			checksig recompile rebuild resign addsign rebuilddb \
			showrc setperms setugids tarbuild eval install \
			upgrade query freshen erase verify querytags rmsource' \
			${cur_nodash#-} ) )
			dashify
			return 0
			;;
		*)
			COMPREPLY=( $( compgen -W 'b e F i q t U V' \
				       $cur_nodash ) )
			dashify
			return 0
			;;
		esac
	fi

	case "$prev" in
	--@(db|exclude)path|prefix|relocate|root)
		COMPREPLY=( $( compgen -d $cur ) )
		return 0
		;;
	--eval)
		# get a list of macros
		COMPREPLY=( $( sed -ne 's/^\(%'${cur#\%}'[^ '$'\t'']*\).*$/\1/p' \
			       /usr/lib/rpm/macros ) )
		return 0
		;;
	--pipe)
		COMPREPLY=( $( compgen -c $cur ) )
		return 0
		;;
	--rcfile)
		COMPREPLY=( $( compgen -f $cur ) )
		return 0
		;;
	--specfile)
		# complete on .spec files
		file_glob spec
		return 0
		;;
	--whatprovides)
		# complete on capabilities
		COMPREPLY=( $( rpm -qa --queryformat '%{providename}\n' | grep ^$cur ) )
		return 0
		;;
	--whatrequires)
		# complete on capabilities
		COMPREPLY=( $( rpm -qa --queryformat '%{requirename}\n' | grep ^$cur ) )
		return 0
		;;
	esac

	case "${COMP_WORDS[1]}" in
	-@([iFU]*|-install|-freshen|-upgrade))
		# complete on list of relevant options
		COMPREPLY=( $( compgen -W 'percent force test replacepkgs \
		replacefiles root excludedocs includedocs noscripts rcfile \
		ignorearch dbpath prefix ignoreos nodeps allfiles ftpproxy \
		ftpport justdb httpproxy httpport noorder relocate badreloc \
		notriggers excludepath ignoresize oldpackage define eval \
		pipe queryformat repackage' ${cur_nodash#-} ))
		dashify
		# return if $cur is an option
		[[ "$cur" == -* ]] && return 0
		# add a list of RPMS to possible completions
		file_glob rpm
		return 0
		;;
	-qp*)
		# complete on list of relevant options
		COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \
		whatrequires requires triggeredby ftpport ftpproxy httpproxy \
		httpport provides triggers dump changelog dbpath filesbypkg \
		define eval pipe showrc info list state docfiles \
		configfiles queryformat conflicts obsoletes' ${cur_nodash#-} ) )
		dashify
		# return if $cur is an option
		[[ "$cur" == -* ]] && return 0
		# add a list of RPMS to possible completions
		file_glob rpm
		return 0
		;;
	-*f)
		# standard filename completion
		COMPREPLY=( $( compgen -f $cur ) )
		return 0
		;;
	-@(e|-erase))
		# complete on list of relevant options
		COMPREPLY=( $( compgen -W 'allmatches noscripts notriggers \
		nodeps test repackage' ${cur_nodash#-} ) )
		dashify
		# return if $cur is an option
		[[ "$cur" == -* ]] && return 0
		add_package_list
		return 0
		;;
	-q*)
		# complete on list of relevant options
		COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \
		whatrequires requires triggeredby ftpport ftpproxy httpproxy \
		httpport provides triggers dump changelog dbpath specfile \
		querybynumber last filesbypkg define eval pipe showrc info \
		list state docfiles configfiles queryformat conflicts \
		obsoletes' ${cur_nodash#-} ) )
		dashify
		# return if $cur is an option
		[[ "$cur" == -* ]] && return 0
		# don't complete on packages if we are querying all packages
		[[ ${COMP_WORDS[1]} == -qa* ]] && return 0
		add_package_list
		return 0
		;;
	-@(K|-checksig))
		# complete on list of relevant options
		COMPREPLY=( $( compgen -W 'nopgp nogpg nomd5' \
		${cur_nodash#-} ) )
		dashify
		# return if $cur is an option
		[[ "$cur" == -* ]] && return 0
		# add a list of RPMS to possible completions
		file_glob rpm
		return 0
		;;
	-@([Vy]*|-verify))
		# complete on list of relevant options
		COMPREPLY=( $( compgen -W 'root rcfile dbpath nodeps nofiles \
		noscripts nomd5' ${cur_nodash#-} ) )
		dashify
		# return if $cur is an option
		[[ "$cur" == -* ]] && return 0
		add_package_list
		return 0
		;;
	-[bt]*)
		# complete on list of relevant options
		COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \
		rmsource test sign buildroot target buildarch buildos \
		nobuild' ${cur_nodash#-} ) )
		dashify
		# return if $cur is an option
		[[ "$cur" == -* ]] && return 0
		if [[ ${COMP_WORDS[1]} == -b* ]]; then
			# complete on .spec files
			file_glob spec
		else
			# complete on .tar files
			COMPREPLY=( $( compgen -G $cur\*.+(tgz|tar.+(gz|bz2)) ) )
		fi
		return 0
		;;
	--re@(build|compile))
		# complete on source RPMs
		COMPREPLY=( $( compgen -G $cur\*.src.rpm ) )
		return 0
		;;
	--tarbuild)
		# complete on tarred sources
		COMPREPLY=( $( compgen -G $cur\*.+(tgz|tar.+(gz|bz2)) ) )
		return 0
		;;
	--@(re|add)sign)
		# complete on RPMs
		file_glob rpm
		return 0
		;;
	--set@(perms|gids))
		add_package_list
		return 0
		;;
	--rmsource)
		file_glob spec
		return 0
		;;
	-*g)
		# package group completion
		local IFS=$'\t'
		# remove trailing backslash, or grep will complain
		cur=${cur%'\'}
		COMPREPLY=( $( rpm -qa --queryformat '%{group}\n' | \
			       grep ^$cur ) )
		# backslash escape spaces and translate newlines to tabs
		COMPREPLY=( $( echo ${COMPREPLY[@]} | sed 's/ /\\ /g' | \
			       tr '\n' '\t' ) )
		return 0
		;;
	esac

	return 0
}
# delete the '-o filenames' if using bash 2.04 only
complete -F _rpm -o filenames rpm

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] []