--- pacman-bash_completion-011410 2010-01-15 18:02:10.594242698 -0430 +++ /etc/bash_completion.d/pacman 2010-01-15 18:04:41.000000000 -0430 @@ -1,10 +1,11 @@ +#!/bin/bash # pacman/makepkg completion by Andres Perera # # Distributed under the terms of the GNU General Public License v3 or # later. # -# Local variables: common core cur list long m o prev query r remove s -# short sync upgrade w +# Local variables: common core cur glob list long m o prev query r +# remove s short sync upgrade w # # vim: ft=sh sts=2 sw=2: @@ -15,8 +16,8 @@ for (( w=0; w<${#COMP_WORDS[@]}-1; w++)); do # Don't touch operands [[ ${COMP_WORDS[w]} == -* ]] && continue - # Only deal with full matches for r in "${!COMPREPLY[@]}"; do + # Only deal with full matches if [[ ${COMP_WORDS[w]} == ${COMPREPLY[r]} ]]; then unset 'COMPREPLY[r]'; break fi @@ -24,11 +25,39 @@ done } -# makepkg completion +# makepkg purge functions +_makepkg_deselect() { + local o + + if [[ $1 == [l] ]]; then + for o in "${!long[@]}"; do + if [[ ${COMP_WORDS[w]} == ${long[o]} ]]; then + unset 'long[o]'; break + fi + done + else + for o in "${!short[@]}"; do + if [[ ${COMP_WORDS[w]} == -*([^- ])${short[o]}* ]]; then + unset 'short[o]' + fi + done + fi +} + +_makepkg_count_words() { + local w + + for (( w=0; w<${#COMP_WORDS[@]}; w++)); do + [[ ${COMP_WORDS[w]} == @(-*([^- ])[hC]*|--@(help|cleancache)) ]] && return 0 + _makepkg_deselect $1 + done +} + +# makepkg main _makepkg() { COMPREPLY=() - local prev cur short long w o + local prev cur short long parse glob prev=${COMP_WORDS[COMP_CWORD-1]} cur=`_get_cword` @@ -40,46 +69,41 @@ --noprogressbar --repackage --rmdeps --skipinteg --source --syncdeps ) - # First word check if (( COMP_CWORD == 1 )) && [[ $cur != -[^-]* ]]; then + # First word check COMPREPLY=($(compgen -W "$(echo "${short[@]/#/-}" "${long[@]}")" -- "$cur")) - return 0 - # Complete filenames for selected options elif [[ $prev == @(--config|-*([^- ])p*) ]]; then - _filedir; _arch_rem_selected; return 0 + # Complete filenames for selected options + _filedir; _arch_rem_selected else - for (( w=0; w<${#COMP_WORDS[@]}; w++)); do - [[ ${COMP_WORDS[w]} == @(--@(help|cleancache)|-*[hC]*) ]] && return 0 - for o in "${!long[@]}"; do - if [[ ${COMP_WORDS[w]} == ${long[o]} ]]; then - unset 'long[o]'; break - fi - done - for o in "${!short[@]}"; do - if [[ ${COMP_WORDS[w]} == -*([^- ])${short[o]}* ]]; then - unset 'short[o]' - fi - done - done - COMPREPLY=($(compgen -W "$(echo "${short[@]/#/-}" "${long[@]}")" -- "$cur")) - if [[ $cur == -[^-]* ]]; then - COMPREPLY=($(compgen -W "$(echo "${short[@]/#/$cur}")" -- "$cur")) - fi + # Generate the list depending on current word + case $cur in + -+($(IFS='|'; echo "${short[*]}"))) + _makepkg_count_words s + COMPREPLY=($(compgen -W "$(echo "${short[@]/#/$cur}")" -- "$cur")) + ;; + -*) + # If $cur isn't a combination option, fall back to displaying + # long options only. These are the prime target for completion + _makepkg_count_words l + COMPREPLY=($(compgen -W "$(echo "${long[@]}")" -- "$cur")) + ;; + esac fi } # pacman packages _pacman_pkg() { - COMPREPLY=($(compgen -W "$( if [[ $2 ]]; then - command pacman -"$1" |\ - command sed 's, .*,,' |\ - command sort -u - else - command pacman -"$1" - fi)" -- "$cur" )) + COMPREPLY=($(compgen -W "$(if [[ $2 ]]; then + command pacman -"$1" |\ + command sed 's, .*,,' |\ + command sort -u + else + command pacman -"$1" + fi)" -- "$cur" )) } -# pacman options +# pacman main _pacman() { COMPREPLY=() @@ -104,63 +128,71 @@ common=( '--cachedir --config --dbpath --debug --help --logfile --noconfirm --noprogressbar --noscriptlet --root --verbose' 'b d h r v' ) - core=( --help --query --remove --sync --upgrade --version -Q -R -S -U -V -h ) + core=( --query --remove --sync --upgrade --version -Q -R -S -U -V ) if (( COMP_CWORD == 1 )) && [[ $cur != -[^-]* ]]; then - COMPREPLY=($(compgen -W "$(echo "${core[@]}" '-h' '--help' )" -- "$cur")) + COMPREPLY=($(compgen -W "$(echo "${core[@]}" '--help' '-h')" -- "$cur")) return 0 elif [[ $prev == @(-*([^- ])[br]*|--@(config|logfile|root|dbpath|cachedir)) ]]; then - _filedir; _arch_rem_selected; return 0 - # Main option check + _filedir; _arch_rem_selected + return 0 else + # Main option check for m in 'Q query' 'R remove' 'S sync' 'U upgrade' 'null'; do - [[ $m == null ]] && return 0 + if [[ $m == null ]]; then + # Go back to core if null + COMPREPLY=($(compgen -W "$(echo "${core[@]}")" -- "$cur")) + return 0 + fi + # Break on match [[ $COMP_LINE == @(* -*([^- ])${m% *}*|* --${m#* } *) ]] && break done fi # See if $cur is an operand before calling _pacman_pkg case $cur in - --*) + + # Check if it's a combination option first + -"${m% *}"*) # Generate the list from the option arrays. eval is being using on # possible matches between query, remove, sync, upgrade and common # arrays; completely sanitized input - command eval "list=($(command sed 's,.*,\${&[0]},' <<<"${m#* }"; IFS=' '; echo ${common[0]}))" - # Parse previous options - for (( w=0; w<${#COMP_WORDS[@]}-1; w++)); do - if [[ ${COMP_WORDS[w]} == --@(help|version) ]]; then + eval "list=($(command sed 's,.*,\${&[1]},' <<<"${m#* }"; IFS=' '; echo ${common[1]}))" + # Parse previous arguments + for (( w=0; w<${#COMP_WORDS[@]}; w++)); do + if [[ ${COMP_WORDS[w]} == -*([^-])[hV]* ]]; then return 0 fi for o in "${!list[@]}"; do - if [[ ${COMP_WORDS[w]} == ${list[o]} ]]; then - unset 'list[o]'; break + if [[ ${COMP_WORDS[w]} == -*([^-])*${list[o]}* ]]; then + unset 'list[o]' fi done done + # Allow special double letters + case ${m% *} in + Q) [[ $cur == *([^i])i*([^i]) ]] && s+=(i) ;; + R) [[ $cur == *([^s])s*([^s]) ]] && s+=(s) ;; + S) [[ $cur == *([^c])c*([^c]) ]] && s+=(c) + [[ $cur == *([^u])u*([^u]) ]] && s+=(u) + [[ $cur == *([^y])y*([^y]) ]] && s+=(y) ;; + esac + list=("${list[@]/#/$cur}" "${s[@]/#/$cur}") ;; - - # Check if it's a short option instead + + # Use long array instead -*) - # Use the short array - command eval "list=($(command sed 's,.*,\${&[1]},' <<<"${m#* }"; IFS=' '; echo ${common[1]}))" - for (( w=0; w<${#COMP_WORDS[@]}; w++)); do - if [[ ${COMP_WORDS[w]} == -*([^- ])[hV]* ]]; then + eval "list=($(command sed 's,.*,\${&[0]},' <<<"${m#* }"; IFS=' '; echo ${common[0]}))" + for (( w=0; w<${#COMP_WORDS[@]}-1; w++)); do + if [[ ${COMP_WORDS[w]} == --@(help|version) ]]; then return 0 fi for o in "${!list[@]}"; do - if [[ ${COMP_WORDS[w]} == -*([^- ])${list[o]}* ]]; then - unset 'list[o]' + if [[ ${COMP_WORDS[w]} == ${list[o]} ]]; then + unset 'list[o]'; break fi done done - # Allow special double options - case ${m% *} in - Q) [[ $cur == *([^i ])i*([^i ]) ]] && s+=(i) ;; - R) [[ $cur == *([^d ])d*([^d ]) ]] && s+=(s) ;; - S) [[ $cur == *([^c ])c*([^u ]) ]] && s+=(c) - [[ $cur == *([^u ])u*([^u ]) ]] && s+=(u) ;; - esac - list=("${list[@]/#/$cur}" "${s[@]/#/$cur}") ;; # The word isn't an operand; use pacman or _filedir @@ -198,5 +230,5 @@ COMPREPLY=($(compgen -W "$(echo "${list[@]}")" -- "$cur")) } -complete -F _makepkg -o filenames makepkg -complete -F _pacman -o filenames pacman +complete -F _makepkg $default $filenames makepkg +complete -F _pacman $default $filenames pacman