[pacman-dev] [PATCH] database/print options, fix dirs, other
* add -D --database options and --print (shining) * fix dirs showing up when they shouldn't in completions The 5 month old log of fixes still applies: http://www.mail-archive.com/pacman-dev@archlinux.org/msg04121.html This is now down to 106 lines. The original one (master) is 365 lines long, yet this one retains all functionality. --- contrib/bash_completion | 430 +++++++++-------------------------------------- 1 files changed, 83 insertions(+), 347 deletions(-) diff --git a/contrib/bash_completion b/contrib/bash_completion index f0b5f9c..216c664 100644 --- a/contrib/bash_completion +++ b/contrib/bash_completion @@ -1,370 +1,106 @@ -# vim: set ft=sh ts=2 sw=2 et: -# file: /etc/bash_completion.d/pacman - -# Bash completion for pacman -# Original: Manolis Tzanidakis <mtzanidakis@freemail.gr> -# -# Distributed under the terms of the GNU General Public License, v2 or later. -# - -## initial functions - -rem_selected () -{ - # (Adapted from bash_completion by Ian Macdonald <ian@caliban.org>) - # This removes any options from the list of completions that have - # already been specified on the command line. - COMPREPLY=($(\echo "${COMP_WORDS[@]}" | \ - (while read -d ' ' i; do - [ "${i}" == "" ] && continue - # flatten array with spaces on either side, - # otherwise we cannot grep on word boundaries of - # first and last word - COMPREPLY=" ${COMPREPLY[@]} " - # remove word from list of completions - COMPREPLY=(${COMPREPLY/ ${i%% *} / }) +# This file is in the public domain. + +_arch_compgen() { + local i r + COMPREPLY=($(compgen -W '$list' -- $cur)) + for ((i=1; i < ${#COMP_WORDS[@]}-1; i++)); do + for r in ${!COMPREPLY[@]}; do + if [[ ${COMP_WORDS[i]} == ${COMPREPLY[r]} ]]; then + unset 'COMPREPLY[r]'; break + fi done - \echo ${COMPREPLY[@]}))) - return 0 -} - -_available_repos () -{ - COMPREPLY=( $( compgen -W "$(\grep '\[' /etc/pacman.conf | \grep -v -e 'options' -e '^#' | \tr -d '[]' )" -- $cur ) ) -} - -_installed_pkgs () -{ - local installed_pkgs - installed_pkgs=$( \ls /var/lib/pacman/local/ ) - COMPREPLY=( $( compgen -W "$( for i in $installed_pkgs; do \echo ${i%-*-*}; done )" -- $cur ) ) -} - -_available_pkgs () -{ - #find balks easilly on a find /foo/*/* type dir, especially one like - # /var/lib/pacman/*/* - # This little change-up removes the find *and* only uses enabled repos - local available_pkgs - local enabled_repos - enabled_repos=$( \grep '\[' /etc/pacman.conf | \grep -v -e 'options' -e '^#' | \tr -d '[]' ) - available_pkgs=$( for r in $enabled_repos; do \echo /var/lib/pacman/sync/$r/*; done ) - COMPREPLY=( $( compgen -W "$( for i in $available_pkgs; do j=${i##*/}; echo ${j%-*-*}; done )" -- $cur ) ) + done } -_installed_groups () -{ - local installed_groups - installed_groups=$( \find /var/lib/pacman/local -name desc -exec \sed -ne '/%GROUPS%/,/^$/{//d; p}' {} \; | \sort -u ) - COMPREPLY=( $( compgen -W "$( for i in $installed_groups; do \echo ${i%-*-*}; done )" -- $cur ) ) +_arch_ptr2comp() { + local list= x y + for x; do + for y in '0 --' '1 -'; do + eval 'set -- ${'"$x"'[${y% *}]}' + list+=\ ${@/#/${y#* }} + done + done + _arch_compgen } -_available_groups () -{ - #find balks easilly on a find /foo/*/* type dir, especially one like - # /var/lib/pacman/*/* - # This little change-up removes the find *and* only uses enabled repos - local available_groups - local enabled_repos - enabled_repos=$( \grep '\[' /etc/pacman.conf | \grep -v -e 'options' -e '^#' | tr -d '[]' ) - available_groups=$( for r in $enabled_repos; do \sed '/%GROUPS%/,/^$/{//d; p}' /var/lib/pacman/sync/$r/*/desc | \sort -u; done ) - COMPREPLY=( $( compgen -W "$( for i in $available_groups; do \echo ${i%-*-*}; done )" -- $cur ) ) +_arch_incomp() { + local regex="\s-(-${1#* }\s|${1% *})"; [[ $COMP_LINE =~ $regex ]] } -## makepkg completion - -_makepkg () -{ - local cur prev +_makepkg() { + local cur opts prev COMPREPLY=() - cur=${COMP_WORDS[COMP_CWORD]} + cur=$(_get_cword) prev=${COMP_WORDS[COMP_CWORD-1]} - - case "$prev" in - -p) - _filedir - return 0 - ;; - --help|--cleancache) - COMPREPLY='' - return 0 - ;; - esac - - if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '\ - -A --ignorearch \ - -b --builddeps \ - -c --clean \ - -C --cleancache \ - -d --nodeps \ - -e --noextract \ - -f --force \ - -g --geninteg \ - -h --help \ - -i --install \ - -L --log \ - -m --nocolor \ - -o --nobuild \ - -p \ - -r --rmdeps \ - -s --syncdeps \ - --asroot \ - --source \ - --noconfirm \ - --noprogressbar' -- $cur ) ) + if [[ $cur == -* && $prev != @(--@(cleancache|config|help)|-@(C|h|p)) ]]; then + opts=('allsource asroot clean cleancache config force geninteg help + holdver ignorearch install log nobuild nocolor noconfirm nodeps + noextract noprogressbar pkg repackage rmdeps skipinteg source + syncdeps' 'A C L R c d e f g h i m o p r s') + _arch_ptr2comp opts fi - - rem_selected + true } -complete -o default -F _makepkg makepkg -## pacman completion - -_instring () -{ - str="${1}" - shift 1 - for c in "${@}"; do - if [ $(\expr index "${str}" "${c}") -gt 0 ]; then - return 0 +_pacman_pkg() { + local list=$( + if [[ $2 ]]; then + \pacman -$1 | \cut -d' ' -f1 | \sort -u + else + \pacman -$1 fi - done - return 1 + ) + _arch_compgen } -_pacman () -{ - local a arg toparse op mod cur +_pacman() { + local common core cur prev query remove sync upgrade o COMPREPLY=() - - # This argument parsing is done so we can check for flag existance later - # right now it's a tad crappy, but does the job - for (( i=1; i < ${#COMP_WORDS[@]}-1; i++ )); do - a=${COMP_WORDS[i]} - arg="${a:0:2}" - toparse="${a:2}" - - case "${arg}" in - -@(U|R|S|Q|h|V)) - op="${arg/-}" - mod="${mod}${a:2}" - ;; - --) - arg="${a:2}" - case "${arg}" in - remove) op="R" ;; - upgrade) op="U" ;; - query) op="Q" ;; - sync) op="S" ;; - help) op="h" ;; - version) op="V" ;; - verbose) mod="${mod}v" ;; - root) mod="${mod}r" ;; - dbpath) mod="${mod}b" ;; - nodeps) mod="${mod}d" ;; - force) mod="${mod}f" ;; - groups) mod="${mod}g" ;; - info) mod="${mod}i" ;; - list) mod="${mod}l" ;; - print) mod="${mod}p" ;; - search) mod="${mod}s" ;; - sysupgrade) mod="${mod}u" ;; - upgrades) mod="${mod}u" ;; - downloadonly) mod="${mod}w" ;; - refresh) mod="${mod}y" ;; - changelog) mod="${mod}c" ;; - deps) mod="${mod}d" ;; - explicit) mod="${mod}e" ;; - unrequired) mod="${mod}t" ;; - foreign) mod="${mod}m" ;; - owns) mod="${mod}o" ;; - file) mod="${mod}p" ;; - search) mod="${mod}s" ;; - upgrades) mod="${mod}u" ;; - cascade) mod="${mod}c" ;; - check) mod="${mod}k" ;; - dbonly) mod="${mod}k" ;; - nosave) mod="${mod}n" ;; - recursive) mod="${mod}s" ;; - unneeded) mod="${mod}u" ;; - esac ;; - *) toparse="${a}" ;; - esac - - arglen=$(( ${#toparse}-1 )) - for c in $(\seq 0 "${arglen}"); do - arg=${toparse:$c:1} - [ "${arg}" != "-" ] && mod="${mod}${arg}" - done + cur=$(_get_cword) + prev=${COMP_WORDS[COMP_CWORD-1]} + database=('asdeps asexplicit') + query=('changelog check deps explicit file foreign groups info + list owns quiet search unrequired upgrades' 'c e g i k l m o p q s t u') + remove=('cascade dbonly nodeps nosave print recursive unneeded' 'c k n p s u') + sync=('asdeps asexplicit clean downloadonly force groups ignore + ignoregroup info list needed nodeps print quiet refresh search + sysupgrade' 'c f g i l p q s u w y') + upgrade=('asdeps asexplicit force nodeps print' 'f p') + common=('arch cachedir config dbpath debug help logfile noconfirm + noprogressbar noscriptlet root verbose' 'b d h r v') + core=('database help query remove sync upgrade version' 'D Q R S U V h') + + for o in 'D database' 'Q query' 'R remove' 'S sync' 'U upgrade'; do + _arch_incomp "$o" && break done - cur=${COMP_WORDS[COMP_CWORD]} - - if [ $COMP_CWORD -eq 1 ] && [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '\ - -h --help \ - -Q --query \ - -R --remove \ - -S --sync \ - -U --upgrade \ - -V --version \ - ' -- $cur ) ) - rem_selected - return 0 - fi - - if [[ "$cur" == -* ]]; then - case "${op}" in - U) - COMPREPLY=( $( compgen -W '\ - --asdeps \ - --asexplicit \ - -d --nodeps \ - -f --force \ - -h --help \ - --config \ - --logfile \ - --noconfirm \ - --noprogressbar \ - --noscriptlet \ - -v --verbose \ - -r --root \ - -b --dbpath \ - -p --print \ - --print-format \ - --cachedir \ - ' -- $cur ) ) - return 0 - ;; - R) - COMPREPLY=( $( compgen -W '\ - -c --cascade \ - -d --nodeps \ - -h --help \ - -k --dbonly \ - -n --nosave \ - -s --recursive \ - -u --unneeded \ - --config \ - --logfile \ - --noconfirm \ - --noprogressbar \ - --noscriptlet \ - -v --verbose \ - -r --root \ - -b --dbpath \ - -p --print \ - --print-format \ - --cachedir \ - ' -- $cur ) ) - return 0 - ;; - S) - COMPREPLY=( $( compgen -W '\ - --asdeps \ - --asexplicit \ - -c --clean \ - -d --nodeps \ - -f --force \ - -g --groups \ - -h --help \ - -i --info \ - -l --list \ - -s --search \ - -u --sysupgrade \ - -w --downloadonly \ - -y --refresh \ - --needed \ - --ignore \ - --ignoregroup \ - --config \ - --logfile \ - --noconfirm \ - --noprogressbar \ - --noscriptlet \ - -v --verbose \ - -r --root \ - -b --dbpath \ - -p --print \ - --print-format \ - --cachedir \ - ' -- $cur ) ) - return 0 - ;; - Q) - COMPREPLY=( $( compgen -W '\ - -c --changelog \ - -d --deps \ - -e --explicit \ - -g --groups \ - -h --help \ - -i --info \ - -k --check \ - -l --list \ - -m --foreign \ - -o --owns \ - -p --file \ - -s --search \ - -t --unrequired \ - -u --upgrades \ - --config \ - --logfile \ - --noconfirm \ - --noprogressbar \ - --noscriptlet \ - -v --verbose \ - -r --root \ - -b --dbpath \ - --cachedir \ - ' -- $cur ) ) - return 0 - ;; - esac - rem_selected + if [[ $? != 0 ]]; then + _arch_ptr2comp core + elif [[ $prev != @(V|b|h|o|r) && $cur == -* && + $prev != --@(cachedir|config|dbpath|file|help|logfile|owns|root|version) ]] + then + _arch_ptr2comp ${o#* } common else - case "${op}" in - U) - COMPREPLY=( $( compgen -d -- "$cur" ) \ - $( compgen -f -X '!*.pkg.tar.*' -- "$cur" ) ) - return 0 - ;; - h|V) - COMPREPLY='' - return 0 - ;; - Q) - if _instring $mod g; then - _installed_groups - elif _instring $mod o; then - COMPREPLY=( $( compgen -d -- "$cur" ) \ - $( compgen -f -- "$cur" ) ) - elif _instring $mod p; then - COMPREPLY=( $( compgen -d -- "$cur" ) \ - $( compgen -f -X '!*.pkg.tar.*' -- "$cur" ) ) - elif _instring $mod u; then - COMPREPLY='' - return 0 - else - _installed_pkgs - fi - return 0 - ;; - R) - _installed_pkgs - return 0 - ;; - S) - if _instring $mod l; then - _available_repos - else - _available_pkgs - fi - return 0 - ;; + case ${o% *} in + D|R) + _pacman_pkg Qq;; + Q) + _arch_incomp 'g groups' && _pacman_pkg Qg sort || + _arch_incomp 'p file' && _filedir 'pkg.tar.*' || + _arch_incomp 'o owns' || _arch_incomp 'u upgrades' || + _pacman_pkg Qq;; + S) + _arch_incomp 'g groups' && _pacman_pkg Sg || + _arch_incomp 'l list' && _pacman_pkg Sl sort || + _pacman_pkg Slq;; + U) + _filedir 'pkg.tar.*';; esac fi - - rem_selected + true } + +complete -o default -F _makepkg makepkg complete -o filenames -F _pacman pacman + +# ex:et ts=2 sw=2 ft=sh -- 1.7.1
On Sun, May 9, 2010 at 6:41 PM, Andres P <stderr@mail.com> wrote:
* add -D --database options and --print (shining) * fix dirs showing up when they shouldn't in completions
The 5 month old log of fixes still applies: http://www.mail-archive.com/pacman-dev@archlinux.org/msg04121.html
This is now down to 106 lines. The original one (master) is 365 lines long, yet this one retains all functionality.
What did you use to send this patch ? Can you please use git send-email if you didn't ? And if you cannot do that, an attachment would be better. Otherwise, the commit log should always describe the full changes of the patch, even for a resubmit. We don't want to rely on mail-archive.com for keeping the link valid forever, or any other mail archives. There is also an interesting practive on dri-devel about versioning resubmitted patches : http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg49816.html You simply use v2, v3 etc, and always keeping the original description, and adding what changed in each version / resubmit.
On Sun, May 9, 2010 at 4:33 PM, Xavier Chantry <chantry.xavier@gmail.com> wrote:
What did you use to send this patch ? Can you please use git send-email if you didn't ? And if you cannot do that, an attachment would be better.
Good because I messed some stuff up attached, Andres
On Mon, May 10, 2010 at 1:27 AM, Andres P <stderr@mail.com> wrote:
On Sun, May 9, 2010 at 4:33 PM, Xavier Chantry <chantry.xavier@gmail.com> wrote:
What did you use to send this patch ? Can you please use git send-email if you didn't ? And if you cannot do that, an attachment would be better.
Good because I messed some stuff up
Thanks, that last patch looks good and has everything I asked :) Just two comments : 1) Dan is still not happy about license change, even if this is a full rewrite. He would like to have all files in pacman project licensed with GPL2. But if you put this in public domain, I believe Dan could just relicense it in GPL2 himself. Anyway I don't like acting as an intermediary here, hopefully Dan and you can resolve this together. 2) Related to the directory completion I mentioned earlier : you restored old behavior, which is good. But the old behavior has a bug. It's not a regression in your patch, so not a show stopper, just wondering if you might have an idea. When there is both a directory and a package with the same name, the completion only sees the directory, and thus adds a trailing slash. $ mkdir acpitool $ pacman -S acpi<tab> acpi acpid acpitool/ $ pacman -S acpit<tab> $ pacman -S acpitool/ error: repository 'acpitool' not found error: 'acpitool/': no such repository
On Thu, May 13, 2010 at 9:12 AM, Xavier Chantry <chantry.xavier@gmail.com> wrote:
1) Dan is still not happy about license change, even if this is a full rewrite. He would like to have all files in pacman project licensed with GPL2. But if you put this in public domain, I believe Dan could just relicense it in GPL2 himself. Anyway I don't like acting as an intermediary here, hopefully Dan and you can resolve this together.
As you said, my script is under the public domain so everyone is entitled to change and use it as they see fit. ;)
2) Related to the directory completion I mentioned earlier : you restored old behavior, which is good. But the old behavior has a bug. It's not a regression in your patch, so not a show stopper, just wondering if you might have an idea. When there is both a directory and a package with the same name, the completion only sees the directory, and thus adds a trailing slash.
$ mkdir acpitool $ pacman -S acpi<tab> acpi acpid acpitool/ $ pacman -S acpit<tab> $ pacman -S acpitool/ error: repository 'acpitool' not found error: 'acpitool/': no such repository
This is because -o filenames, which is needed for the 'pkg.tar.*' glob. I have a fix for this that only sets -o filenames when needed. Patch attached, Andres
On Wed, May 19, 2010 at 12:48 AM, Andres P <stderr@mail.com> wrote:
On Thu, May 13, 2010 at 9:12 AM, Xavier Chantry <chantry.xavier@gmail.com> wrote:
1) Dan is still not happy about license change, even if this is a full rewrite. He would like to have all files in pacman project licensed with GPL2. But if you put this in public domain, I believe Dan could just relicense it in GPL2 himself. Anyway I don't like acting as an intermediary here, hopefully Dan and you can resolve this together.
As you said, my script is under the public domain so everyone is entitled to change and use it as they see fit. ;)
2) Related to the directory completion I mentioned earlier : you restored old behavior, which is good. But the old behavior has a bug. It's not a regression in your patch, so not a show stopper, just wondering if you might have an idea. When there is both a directory and a package with the same name, the completion only sees the directory, and thus adds a trailing slash.
$ mkdir acpitool $ pacman -S acpi<tab> acpi acpid acpitool/ $ pacman -S acpit<tab> $ pacman -S acpitool/ error: repository 'acpitool' not found error: 'acpitool/': no such repository
This is because -o filenames, which is needed for the 'pkg.tar.*' glob. I have a fix for this that only sets -o filenames when needed.
Patch attached, Andres
Thanks, works for me ! It's a great work you did, that bash completion file was desperately looking for love :) IMO it would be a nice addition to the next release and definitely worth mentioning in the changelog.
participants (2)
-
Andres P
-
Xavier Chantry