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