[PATCH 1/3] bash-completion: handle comma-separated options

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 bash-completion/chcpu   | 32 ++++++++++++++++++++++----------
 bash-completion/findmnt | 16 ++++++++++++----
 bash-completion/losetup | 14 ++++++++++----
 bash-completion/lsblk   | 30 +++++++++++++++++++++---------
 bash-completion/lscpu   | 33 ++++++++++++++++-----------------
 bash-completion/lslocks | 14 ++++++++++----
 bash-completion/partx   | 15 +++++++++++----
 bash-completion/prlimit | 14 ++++++++++----
 bash-completion/setpriv | 28 ++++++++++++++++++++--------
 bash-completion/swapon  | 14 ++++++++++----
 bash-completion/taskset | 16 +++++++++++-----
 bash-completion/wdctl   | 14 ++++++++++----
 bash-completion/zramctl | 14 ++++++++++----
 13 files changed, 173 insertions(+), 81 deletions(-)

diff --git a/bash-completion/chcpu b/bash-completion/chcpu
index da9c6ca..33991f4 100644
--- a/bash-completion/chcpu
+++ b/bash-completion/chcpu
@@ -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')
diff --git a/bash-completion/findmnt b/bash-completion/findmnt
index cf66565..3ad9147 100644
--- a/bash-completion/findmnt
+++ b/bash-completion/findmnt
@@ -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')
diff --git a/bash-completion/losetup b/bash-completion/losetup
index d2b7418..629d34b 100644
--- a/bash-completion/losetup
+++ b/bash-completion/losetup
@@ -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')
diff --git a/bash-completion/lsblk b/bash-completion/lsblk
index af8b9ad..1692dad 100644
--- a/bash-completion/lsblk
+++ b/bash-completion/lsblk
@@ -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')
diff --git a/bash-completion/lscpu b/bash-completion/lscpu
index 7e189ee..ecadd24 100644
--- a/bash-completion/lscpu
+++ b/bash-completion/lscpu
@@ -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
diff --git a/bash-completion/lslocks b/bash-completion/lslocks
index c9cff2c..6ad6c05 100644
--- a/bash-completion/lslocks
+++ b/bash-completion/lslocks
@@ -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')
diff --git a/bash-completion/partx b/bash-completion/partx
index 5d662fc..804787f 100644
--- a/bash-completion/partx
+++ b/bash-completion/partx
@@ -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')
diff --git a/bash-completion/prlimit b/bash-completion/prlimit
index c680214..fff7a85 100644
--- a/bash-completion/prlimit
+++ b/bash-completion/prlimit
@@ -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')
diff --git a/bash-completion/setpriv b/bash-completion/setpriv
index 7c21dee..bdd3b7d 100644
--- a/bash-completion/setpriv
+++ b/bash-completion/setpriv
@@ -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')
diff --git a/bash-completion/swapon b/bash-completion/swapon
index f471e07..fc80af5 100644
--- a/bash-completion/swapon
+++ b/bash-completion/swapon
@@ -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')
diff --git a/bash-completion/taskset b/bash-completion/taskset
index dd1ef1f..8e62a3b 100644
--- a/bash-completion/taskset
+++ b/bash-completion/taskset
@@ -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')
diff --git a/bash-completion/wdctl b/bash-completion/wdctl
index 4f16e76..811b5e3 100644
--- a/bash-completion/wdctl
+++ b/bash-completion/wdctl
@@ -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')
diff --git a/bash-completion/zramctl b/bash-completion/zramctl
index 90ed608..a4ef536 100644
--- a/bash-completion/zramctl
+++ b/bash-completion/zramctl
@@ -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')
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe util-linux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux