Here are two patches for bash completion.

The first one provides those mighty improvments for urpmi (and friends) 
completion:
 - ligthning-fast package completion using latest urpmi pre-generated package 
lists
 - avoid querying database when word to complete is clearly a file
 - up-to-date option list
 - some minor forgotten completion fixed

The second one fixes some problems with service completion, such as trying to 
complete past the 3rd word, or completing to non-service files as 
/etc/init.d/function.

Please test, and if no serious bug is found, i'll happily commit those patches 
to bash-completion package.
-- 
Guillaume Rousse
When a customer has a large number of specialty locks , thast lock will 
require very expensive service and pin kits. 
When you buy the kits, you only get to use them one time, or you find that 
something you already have can be used instead. 
When you don't buy the kits, nothing else that you have will work instead, and 
you will have constant problems that would have been avoided by buying the 
kits. 
By the time you finally buy the kits your lost time will exceed the cost of 
the kits by ten fold. Then your customer will go elsewhere. 
                -- Murphy's Laws of Locksmithing n°21
--- /etc/bash_completion	2003-08-25 01:51:22.000000000 +0200
+++ bash_completion	2003-09-10 02:25:37.000000000 +0200
@@ -3604,36 +3604,55 @@
 # urpmi media function required by other urpmi functions
 #
 have urpmq && {
-_urpmi_media()
+_urpmi_get_medias()
+{
+	medias=$( awk '/{/ {print $0}' /etc/urpmi/urpmi.cfg 2>/dev/null | sed -e 's/ [^ ]\+ {$//' )
+}
+
+_urpmi_medias()
 {
-	local IFS=$'\t\n'
 	# return list of available media
-	COMPREPLY=( $( awk '/{/ {print $0}' /etc/urpmi/urpmi.cfg 2>/dev/null \
-	 | sed -e "s/\( \(file\|removable\|ftp\|http\|rsync\|ssh\):\/\/.*\)\? {$//"\
-		| grep "^${cur//\\\\/\\\\}" ) )
+	local medias
+	# get medias list
+	_urpmi_get_medias
+	# return matching ones
+	COMPREPLY=( $( compgen -W "$medias" -- ${cur//\\\\/\\\\} ) )
 }
 
 _urpmi_packages()
 {
-	local options
+	# return list of available packages
+	local medias
 	# find media selection options
 	for (( i=1; i < COMP_CWORD; i++ )); do
-		if [[ "${COMP_WORDS[i]}" == --@(excludemedia|media) ]]; then
-			options="$options ${COMP_WORDS[i]} ${COMP_WORDS[i+1]}"
+		if [[ "${COMP_WORDS[i]}" == --excludemedia ]]; then
+			_urpmi_get_medias
+			for media in ${COMP_WORDS[i+1]//,/ }; do 
+				medias=${medias//$media/}
+			done
+			i=$(($i+1))
+		fi
+		if [[ "${COMP_WORDS[i]}" == --media ]]; then
+			medias=${COMP_WORDS[i+1]//,/ }
 			i=$(($i+1))
 		fi
 		if [[ "${COMP_WORDS[i]}" == --update ]]; then
-			options="$options ${COMP_WORDS[i]}"
+			COMPREPLY=( $( urpmq --update --list 2>/dev/null | grep "^$cur" ) )
+			return 0
 		fi
 	done
 
-	# return list of available packages
-	COMPREPLY=( $( urpmq $options --list 2>/dev/null | grep "^$cur" ) )
+	# get medias list if still empty
+	[ -z "$medias" ] && _urpmi_get_medias
+
+	# get matching packages
+	for media in $medias; do
+		COMPREPLY=( [EMAIL PROTECTED]:-} $( cat /var/lib/urpmi/names.$media 2>/dev/null | grep "^$cur" ) )
+	done
 }
 
 _urpmi_aliases()
 {
-	local IFS=$'\t\n'
 	# return list of available aliases
 	COMPREPLY=( $( awk -F: '{print $1}' /etc/urpmi/parallel.cfg 2>/dev/null | grep "^${cur//\\\\/\\\\}" ) )
 }
@@ -3651,8 +3670,8 @@
 	prev=${COMP_WORDS[COMP_CWORD-1]}
 
 	case "$prev" in
-		--media)
-			_urpmi_media
+		--@(media|excludemedia|sortmedia))
+			_urpmi_medias
 			return 0
 			;;
 		--parallel)
@@ -3664,16 +3683,18 @@
 	if [[ "$cur" == -* ]]; then
 		# return list of available options
 		COMPREPLY=( $( compgen -W '-a -p -P -y -s -q -v -h --help \
-			--update --media --excludemedia --sortmedia \
-			--synthesis --auto --auto-select --fuzzy --src \
-			--install-src --clean --noclean --force \
-			--allow-nodeps --allow-force --parallel --wget --curl \
-			--limit-rate --proxy --proxy-user --bug --env \
-			--X --best-output --verify-rpm --test --excludepath' \
-			-- $cur ) )
+			--update --media --excludemedia --sortmedia --synthesis \
+			--auto --auto-select --no-uninstall --keep --split-level \
+			--split-length --fuzzy --src --install-src --clean \
+			--noclean --force --allow-nodeps --allow-force --parallel \
+			--wget --curl --limit-rate --proxy --proxy-user --bug \
+			--env --X --best-output --verify-rpm --test --excludepath \
+			--excludedocs ' -- $cur ) )
 	else
-		# return rpm files and available packages
-		_urpmi_packages
+		# return available packages (unless it is clearly a file) and rpm files
+		if [[ "$cur" != */* ]]; then
+			_urpmi_packages
+		fi
 		_filedir rpm
 	fi
 }
@@ -3691,8 +3712,8 @@
 	prev=${COMP_WORDS[COMP_CWORD-1]}
 
 	case "$prev" in
-		--media)
-			_urpmi_media
+		--@(media|excludemedia|sortmedia))
+			_urpmi_medias
 			return 0
 			;;
 		--parallel)
@@ -3703,15 +3724,17 @@
 
 	if [[ "$cur" == -* ]]; then
 		# return list of available options
-		COMPREPLY=( $( compgen -W '-h -v -d -u -c -P -R -y -s -i -g \
-			-r -f --help --update --media --excludemedia \
-			--sortmedia --synthesis --auto-select --fuzzy --list \
-			--list-media --list-nodes --list-aliases --src \
+		COMPREPLY=( $( compgen -W '-v -d -u -a -c -P -R -y -s -i -g \
+			-r -f -h --help --update --media --excludemedia \
+			--sortmedia --synthesis --auto-select --fuzzy --keep \
+			--list --list-media --list-nodes --list-aliases --src \
 			--headers --sources --force --parallel --wget --curl \
-			--proxy --proxy-user' -- $cur))
+			--proxy --proxy-user --env ' -- $cur))
 	else
-		# return rpm files and available packages
-		_urpmi_packages
+		# return available packages (unless it is clearly a file) and rpm files
+		if [[ "$cur" != */* ]]; then
+			_urpmi_packages
+		fi
 		_filedir rpm
 	fi
 }
@@ -3729,7 +3752,7 @@
 
 	if [[ "$cur" == -* ]]; then
 		# return list of available options
-		COMPREPLY=( $( compgen -W '-a -h --help --auto --test \
+		COMPREPLY=( $( compgen -W '-v -a -h --help --auto --test \
 			--parallel' -- $cur ) )
 	else
 		# return list of available packages
@@ -3747,6 +3770,14 @@
 
 	COMPREPLY=()
 	cur=${COMP_WORDS[COMP_CWORD]}
+	prev=${COMP_WORDS[COMP_CWORD-1]}
+
+	case "$prev" in
+		--@(media|excludemedia|sortmedia))
+			_urpmi_medias
+			return 0
+			;;
+	esac
 
 	if [[ "$cur" == -* ]]; then
 		# return list of available options
@@ -3755,7 +3786,7 @@
 			--verbose --quiet --uniq --all --name --group --size \
 			--epoch --summary --description --sourcerpm --packager\
 			--buildhost --url --provides --requires --files \
-			--conflicts --obsoletes ' -- $cur ) )
+			--conflicts --obsoletes --env ' -- $cur ) )
 	else
 		# return available files
 		_filedir
@@ -3775,12 +3806,12 @@
 
 	if [[ "$cur" == -* ]]; then
 		# return list of available options
-		COMPREPLY=( $( compgen -W '-a -c -d -f -h --help --curl \
-			--wget --limit-rate --proxy --proxy-user --update' \
+		COMPREPLY=( $( compgen -W '-a -c -f -h --help --wget \
+			--curl --limit-rate --proxy --proxy-user --update' \
 			-- $cur))
 	else
 		# return list of available media
-		_urpmi_media
+		_urpmi_medias
 	fi
 }
 [ -n "${have:-}" ] && complete -F _urpmi_update urpmi.update
@@ -3800,7 +3831,7 @@
 		COMPREPLY=( $( compgen -W '-c -f -h --help --wget --curl \
 			--limit-rate --proxy --proxy-user --update \
 			--probe-synthesis --probe-hdlist --no-probe --distrib \
-			--env --version --arch' -- $cur ) )
+			--env --version --arch --virtual' -- $cur ) )
 	else
 		# count number of mandatory args given sofar
 		args=$COMP_CWORD
@@ -3812,7 +3843,7 @@
 		case $args in
 			1)
 				# return list of available media
-				_urpmi_media
+				_urpmi_medias
 				;;
 			2)
 				# return list of available protocols
@@ -3841,10 +3872,10 @@
 
 	if [[ "$cur" == -* ]]; then
 		# if word begins with a dash, return list of available options
-		COMPREPLY=( $( compgen -W '-a -c --help' -- $cur ) )
+		COMPREPLY=( $( compgen -W '-a -c -h --help' -- $cur ) )
 	else
 		# elsewhere, return list of available media
-		_urpmi_media
+		_urpmi_medias
 	fi
 
 }
--- /etc/bash_completion	2003-08-21 12:57:48.000000000 +0200
+++ bash_completion	2003-08-25 02:48:55.000000000 +0200
@@ -423,6 +423,17 @@
 # that script's available commands
 #
 { have service || [ -d /etc/init.d/ ]; } &&
+_service_services()
+{
+	COMPREPLY=( $( compgen -W '`echo $sysvdir/!(*.rpmsave|*.rpmorig*|~|functions)`' ) )
+	COMPREPLY=( $( compgen -W '[EMAIL PROTECTED]/}' -- $cur ) )
+}
+_service_commands()
+{
+	COMPREPLY=( $( compgen -W '`sed -ne "y/|/ /; \
+		s/^.*Usage.*{\(.*\)}.*$/\1/p" \
+		$sysvdir/${prev##*/}`' -- $cur ) )
+}
 _service()
 {
 	local cur sysvdir
@@ -438,15 +449,19 @@
 	[ -d /etc/rc.d/init.d ] && sysvdir=/etc/rc.d/init.d \
 				|| sysvdir=/etc/init.d
 
-	if [[ $COMP_CWORD -eq 1 ]] && [[ $prev == "service" ]]; then
-		COMPREPLY=( $( compgen -W '`echo $sysvdir/!(*.rpmsave|*.rpmorig)`' ) )
-		COMPREPLY=( $( compgen -W '[EMAIL PROTECTED]/}' -- \
-			       $cur ) )
+	if [[ ${COMP_WORDS[0]} == "service" ]]; then
+		case $COMP_CWORD in
+		1)
+			_service_services
+			;;
+		2)
+			_service_commands
+			;;
+		esac
 	else
-		COMPREPLY=( $( compgen -W '`sed -ne "y/|/ /; \
-					    s/^.*Usage.*{\(.*\)}.*$/\1/p" \
-					    $sysvdir/${prev##*/}`' -- \
-			       $cur ) )
+		if [[ $COMP_CWORD -eq 1 ]]; then
+			_service_commands
+		fi
 	fi
 
 	return 0

Reply via email to