]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
bash-completion: handle comma-separated options
authorBoris Egorov <egorov@linux.com>
Tue, 2 Jun 2015 17:59:01 +0000 (23:59 +0600)
committerKarel Zak <kzak@redhat.com>
Mon, 8 Jun 2015 10:09:48 +0000 (12:09 +0200)
This solution can become messy when you have too many options listed,
because it repeats all of them. For example, after invoking completion
with this input:

    $ partx --output END,SECTORS,SCHEME,START,

You got these completions:

    END,SECTORS,SCHEME,START,FLAGS,  END,SECTORS,SCHEME,START,NR,
    END,SECTORS,SCHEME,START,TYPE,
    END,SECTORS,SCHEME,START,NAME,   END,SECTORS,SCHEME,START,SIZE,
    END,SECTORS,SCHEME,START,UUID,

Nevertheless, it works even with numbers (listed options properly
excluded from completion). Try to invoke completion after
'chcpu --disable ' or 'lsblk --exclude ' to see it in action.

Few issues remained:

    * completion interrupts after encountering ':' in listed option,
    like in 'MAJ:MIN' in lsblk, losetup.
    * lscpu completion is broken: it inserts space after '--extended',
    but lscpu assumes there is no space after this option. It also
    doesn't complete '--parse' option.
    * some completion options are outdated (for example, lscpu MMHZ). We
    need to sync them with code. Fix for lscpu follows.

Signed-off-by: Boris Egorov <egorov@linux.com>
13 files changed:
bash-completion/chcpu
bash-completion/findmnt
bash-completion/losetup
bash-completion/lsblk
bash-completion/lscpu
bash-completion/lslocks
bash-completion/partx
bash-completion/prlimit
bash-completion/setpriv
bash-completion/swapon
bash-completion/taskset
bash-completion/wdctl
bash-completion/zramctl

index da9c6caf0aaf7a728d9f2e15aa82ea921a1b0358..33991f4a82b19699f877b0e98151acfccf288f69 100644 (file)
@@ -6,19 +6,31 @@ _chcpu_module()
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        case $prev in
                '-e'|'--enable')
-                       local CPULIST
-                       # FIXME: will propose only binding to a cpu.
-                       # Maybe this should add comma, and continue?
-                       CPULIST=$(sed 's/^/{/; s/-/../g; s/,/} {/g; s/$/}/' /sys/devices/system/cpu/offline)
-                       COMPREPLY=( $(compgen -W "$(eval echo $CPULIST)" -- $cur) )
+                       local prefix realcur CPULIST_ALL CPULIST
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       CPULIST_ALL=$(sed 's/^/{/; s/-/../g; s/,/} {/g; s/$/}/' /sys/devices/system/cpu/offline)
+                       for WORD in $(eval echo $CPULIST_ALL); do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       CPULIST="$WORD $CPULIST"
+                               fi
+                       done
+                       compopt -o nospace
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$CPULIST" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-d'|'--disable')
-                       local CPULIST
-                       # FIXME: will propose only binding to a cpu.
-                       # Maybe this should add comma, and continue?
-                       CPULIST=$(sed 's/^/{/; s/-/../g; s/,/} {/g; s/$/}/' /sys/devices/system/cpu/online)
-                       COMPREPLY=( $(compgen -W "$(eval echo $CPULIST)" -- $cur) )
+                       local prefix realcur CPULIST_ALL CPULIST
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       CPULIST_ALL=$(sed 's/^/{/; s/-/../g; s/,/} {/g; s/$/}/' /sys/devices/system/cpu/online)
+                       for WORD in $(eval echo $CPULIST_ALL); do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       CPULIST="$WORD $CPULIST"
+                               fi
+                       done
+                       compopt -o nospace
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$CPULIST" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-c'|'--configure'|'-g'|'--deconfigure')
index cf66565c137dce7506da88d4bb823b9f51fbe4cf..3ad914735fd3ef76e3071c8e0bb6757c30ec02c2 100644 (file)
@@ -43,15 +43,23 @@ _findmnt_module()
                        return 0
                        ;;
                '-o'|'--output')
-                       # FIXME: how to append to a string with compgen?
-                       local OUTPUT
-                       OUTPUT="SOURCE TARGET FSTYPE OPTIONS VFS-OPTIONS
+                       local prefix realcur OUTPUT_ALL OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+
+                       OUTPUT_ALL="SOURCE TARGET FSTYPE OPTIONS VFS-OPTIONS
                                FS-OPTIONS LABEL UUID PARTLABEL PARTUUID
                                MAJ\:MIN ACTION OLD-TARGET OLD-OPTIONS
                                SIZE AVAIL USED USE% FSROOT TID ID
                                OPT-FIELDS PROPAGATION FREQ PASSNO"
+
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-t'|'--types')
index d2b74184ffb3bb4f356454c29f018ce28dda4711..629d34b78d74bcc086f24d8e8fe0556e44f15066 100644 (file)
@@ -25,13 +25,19 @@ _losetup_module()
                        return 0
                        ;;
                '-O'|'--output')
-                       # FIXME: how to append to a string with compgen?
-                       local OUTPUT
-                       OUTPUT="NAME AUTOCLEAR BACK-FILE BACK-INO
+                       local prefix realcur OUTPUT_ALL OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       OUTPUT_ALL="NAME AUTOCLEAR BACK-FILE BACK-INO
                                BACK-MAJ:MIN MAJ:MIN OFFSET PARTSCAN RO
                                SIZELIMIT"
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-h'|'--help'|'-V'|'--version')
index af8b9ad65d24335cbad94ddfaa054193a65965e6..1692dade8b07ded6352538b40daf8276e3facffa 100644 (file)
@@ -5,7 +5,7 @@ _lsblk_module()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
 
-       LSBLK_COLS="NAME KNAME MAJ:MIN FSTYPE MOUNTPOINT
+       LSBLK_COLS_ALL="NAME KNAME MAJ:MIN FSTYPE MOUNTPOINT
                LABEL UUID PARTTYPE PARTLABEL PARTUUID PARTFLAGS
                RA RO RM
                MODEL SIZE STATE OWNER GROUP MODE
@@ -16,26 +16,38 @@ _lsblk_module()
 
        case $prev in
                '-e'|'--exclude'|'-I'|'--include')
-                       local MAJOR I J
-                       MAJOR=''
+                       local realcur prefix MAJOR_ALL MAJOR I J
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
                        for I in /sys/dev/block/*; do
                                J=${I##*/}
-                               MAJOR="$MAJOR ${J%%:*}"
+                               MAJOR_ALL="$MAJOR_ALL ${J%%:*}"
+                       done
+                       for WORD in $MAJOR_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       MAJOR="$WORD $MAJOR"
+                               fi
                        done
-                       # FIXME: how to append to a string with compgen?
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$MAJOR" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$MAJOR" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-o'|'--output')
-                       # FIXME: how to append to a string with compgen?
+                       local prefix realcur LSBLK_COLS
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       for WORD in $LSBLK_COLS_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       LSBLK_COLS="$WORD $LSBLK_COLS"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$LSBLK_COLS" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$LSBLK_COLS" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-x'|'--sort')
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$LSBLK_COLS"  -- $cur) )
+                       COMPREPLY=( $(compgen -W "$LSBLK_COLS_ALL"  -- $cur) )
                        return 0
                        ;;
                '-h'|'--help'|'-V'|'--version')
index 7e189eee6bae100ea9c0f7bb669633d4fbbe5a49..ecadd24f391e528b7d188a7fc50abb4151fba400 100644 (file)
@@ -1,26 +1,25 @@
 _lscpu_module()
 {
-       local cur OPTS
+       local cur OPTS_ALL
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        case $prev in
-               '--extended'|'=')
+               '--extended='|'=')
+                       local prefix realcur OPTS
                        cur=${cur#=}
-                       # FIXME: how to append to a string with compgen?
-                       OPTS="CPU,
-                               CORE,
-                               SOCKET,
-                               NODE,
-                               BOOK,
-                               CACHE,
-                               POLARIZATION,
-                               ADDRESS,
-                               CONFIGURED,
-                               ONLINE,
-                               MMHZ"
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       OPTS_ALL="CPU CORE SOCKET NODE
+                               BOOK CACHE POLARIZATION ADDRESS
+                               CONFIGURED ONLINE MMHZ"
+                       for WORD in $OPTS_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OPTS="$WORD $OPTS"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OPTS" -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OPTS" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-h'|'--help'|'-V'|'--version')
@@ -29,7 +28,7 @@ _lscpu_module()
        esac
        case $cur in
                -*)
-                       OPTS="--all
+                       OPTS_ALL="--all
                                --online
                                --offline
                                --extended=
@@ -38,7 +37,7 @@ _lscpu_module()
                                --hex
                                --help
                                --version"
-                       COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
+                       COMPREPLY=( $(compgen -W "${OPTS_ALL[*]}" -- $cur) )
                        return 0
                        ;;
        esac
index c9cff2c6b7a31192aa2d629f282912d7986824eb..6ad6c057a4c2587b43a2f6f48961110aa7c21366 100644 (file)
@@ -14,11 +14,17 @@ _lslocks_module()
                        return 0
                        ;;
                '-o'|'--output')
-                       # FIXME: how to append to a string with compgen?
-                       local OUTPUT
-                       OUTPUT="COMMAND PID TYPE SIZE MODE M START END PATH BLOCKER"
+                       local prefix realcur OUTPUT_ALL OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       OUTPUT_ALL="COMMAND PID TYPE SIZE MODE M START END PATH BLOCKER"
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-h'|'--help'|'-V'|'--version')
index 5d662fc9ce300aca2dff976ea75bd538d71f079a..804787f9d17a7d749a1c8a9b50e6bbe4f72b0e2a 100644 (file)
@@ -1,8 +1,8 @@
 _partx_module()
 {
-       local cur prev OPTS OUTPUT
+       local cur prev OPTS OUTPUT_ALL
        COMPREPLY=()
-       OUTPUT="NR START END SECTORS SIZE NAME UUID TYPE FLAGS SCHEME"
+       OUTPUT_ALL="NR START END SECTORS SIZE NAME UUID TYPE FLAGS SCHEME"
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        case $prev in
@@ -10,9 +10,16 @@ _partx_module()
                        return 0
                        ;;
                '-o'|'--output')
-                       # FIXME: how to append to a string with compgen?
+                       local realcur prefix OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-t'|'--type')
index c6802143d2615e5ba8761033bca61e2ad93b8e46..fff7a85c529118fcbc72a790d673d506d7c0089d 100644 (file)
@@ -11,11 +11,17 @@ _prlimit_module()
                        return 0
                        ;;
                '-o'|'--output')
-                       # FIXME: how to append to a string with compgen?
-                       local OUTPUT
-                       OUTPUT="DESCRIPTION RESOURCE SOFT HARD UNITS"
+                       local prefix realcur OUTPUT_ALL OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       OUTPUT_ALL="DESCRIPTION RESOURCE SOFT HARD UNITS"
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-h'|'--help'|'-V'|'--version')
index 7c21deefa315e8faa08dcb7de34861dd538635df..bdd3b7dabe2fab1ad09df67e66871d7e3c86e0e0 100644 (file)
@@ -6,11 +6,17 @@ _setpriv_module()
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        case $prev in
                '--inh-caps'|'--bounding-set')
-                       # FIXME: how to append to a string with compgen?
-                       local INHERIT
-                       INHERIT=$($1 --list-caps| awk '{print $1, "-" $1}')
+                       local prefix realcur INHERIT_ALL INHERIT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       INHERIT_ALL=$($1 --list-caps| awk '{print $1, "-" $1}')
+                       for WORD in $INHERIT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       INHERIT="$WORD $INHERIT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "all $INHERIT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$INHERIT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '--ruid'|'--euid'|'--reuid')
@@ -26,11 +32,17 @@ _setpriv_module()
                        return 0
                        ;;
                '--groups')
-                       # FIXME: how to append to a string with compgen?
-                       local GIDS
-                       GIDS=$(getent group | awk -F: '{print $3}')
+                       local prefix realcur GIDS_ALL GIDS
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       GIDS_ALL=$(getent group | awk -F: '{print $3}')
+                       for WORD in $GIDS_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       GIDS="$WORD $GIDS"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$GIDS" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$GIDS" -S ',' -- $realcur) )
                        return 0
                        ;;
                '--securebits')
index f471e079cc6781d304afd43923af40aa1e9a7e2b..fc80af5eb7aea37b9ebe3ec57dd28cd24c15328b 100644 (file)
@@ -12,11 +12,17 @@ _swapon_module()
                        return 0
                        ;;
                '--show')
-                       # FIXME: how to append to a string with compgen?
-                       local OUTPUT
-                       OUTPUT="NAME TYPE SIZE USED PRIO UUID LABEL"
+                       local prefix realcur OUTPUT_ALL OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       OUTPUT_ALL="NAME TYPE SIZE USED PRIO UUID LABEL"
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-U')
index dd1ef1f695fe4ad07393f9aa6b8720f669dba1ed..8e62a3b676705d9dfa9fc175beb8e3f77ef0f33f 100644 (file)
@@ -6,11 +6,17 @@ _taskset_module()
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        case $prev in
                '-c'|'--cpu-list')
-                       local CPULIST
-                       # FIXME: will propose only binding to a cpu.
-                       # Maybe this should add comma, and continue?
-                       CPULIST=$(sed 's/^/{/; s/-/../g; s/,/} {/g; s/$/}/' /sys/devices/system/cpu/online)
-                       COMPREPLY=( $(compgen -W "$(eval echo $CPULIST)" -- $cur) )
+                       local prefix realcur CPULIST_ALL CPULIST
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       CPULIST_ALL=$(sed 's/^/{/; s/-/../g; s/,/} {/g; s/$/}/' /sys/devices/system/cpu/online)
+                       for WORD in $(eval echo $CPULIST_ALL); do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       CPULIST="$WORD $CPULIST"
+                               fi
+                       done
+                       compopt -o nospace
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$CPULIST" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-p'|'--pid')
index 4f16e760721e8a394507058ee303c9bf560c40c8..811b5e3ccb2ccf2e7062459c9ff43bded68ee950 100644 (file)
@@ -23,11 +23,17 @@ _wdctl_module()
                        return 0
                        ;;
                '-o'|'--output')
-                       # FIXME: how to append to a string with compgen?
-                       local OUTPUT
-                       OUTPUT="FLAG DESCRIPTION STATUS BOOT-STATUS DEVICE"
+                       local prefix realcur OUTPUT_ALL OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       OUTPUT_ALL="FLAG DESCRIPTION STATUS BOOT-STATUS DEVICE"
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-s'|'--settimeout')
index 90ed6089b35f9f39370804556a0cf107cfc1aef6..a4ef536d87a4628488a92e10420f78dec89deb04 100644 (file)
@@ -10,11 +10,17 @@ _zramctl_module()
                        return 0
                        ;;
                '-o'|'--output')
-                       # FIXME: how to append to a string with compgen?
-                       local OUTPUT
-                       OUTPUT="NAME DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MOUNTPOINT"
+                       local prefix realcur OUTPUT_ALL OUTPUT
+                       realcur="${cur##*,}"
+                       prefix="${cur%$realcur}"
+                       OUTPUT_ALL="NAME DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MOUNTPOINT"
+                       for WORD in $OUTPUT_ALL; do
+                               if ! [[ $prefix == *"$WORD"* ]]; then
+                                       OUTPUT="$WORD $OUTPUT"
+                               fi
+                       done
                        compopt -o nospace
-                       COMPREPLY=( $(compgen -W "$OUTPUT" -S ',' -- $cur) )
+                       COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) )
                        return 0
                        ;;
                '-s'|'--size')