summaryrefslogtreecommitdiff
path: root/bash_completion
blob: 72839a8e927c0f0480847cf4c64b35967da72c2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# SPDX-License-Identifier: GPL-2.0

_para_complete()
{
	local prg=$1 # the program to execute, either para_client or para_audioc
	local cur OLD_IFS list opt
	local -i n old_extglob=1 ddpos=-1 # position of the double-dash arg
	# This awk script extracts short and long options from the help output.
	local script='{
		if ($1 ~ "^-[a-zA-Z]," && $2 ~ "^--[a-zA-Z]") {
			print substr($1, 0, 2);
			gsub("=.*", "", $2)
			print $2
		} else if ($1 ~ "^--[a-zA-Z]") {
			gsub("=.*", "", $1)
			print $1
		}
	}'

	# Ask readline to recreate COMP_WORDS using space as the only delimiter.
	if [[ "$COMP_WORDBREAKS" != ' ' ]]; then
		COMP_WORDBREAKS=' '
		return 124
	fi
	n=$COMP_POINT
	cur=
	while ((n > 0)); do
		let n--;
		[[ "${COMP_LINE:$n:1}" == ' ' ]] && break
		cur="${COMP_LINE:$n:1}$cur"
	done
	for ((n = 0; n < $COMP_CWORD; n++)); do
		[[ "${COMP_WORDS[$n]}" != '--' ]] && continue
		ddpos=$n
		break
	done
	# Figure out whether we need to complete according to options of the
	# given program or according to its subcommands. The 'para' shortcut
	# is expected to be aliased to 'para_client --' and we always complete
	# on subcommands in this case.
	if [[ "$cur" == -* ]] && [[ "${COMP_WORDS[0]}" != 'para' ]]; then
		# If '--' is none of the previous words, we complete on options
		# of the given program.
		if ((ddpos < 0 || COMP_CWORD < ddpos)); then
			list=$($prg --help | awk "$script")
			COMPREPLY=($(compgen -W "$list" -- "$cur"))
			return
		fi
	fi
	# Rebuild the command line with the first word and anything up to
	# "--" stripped off. Then call the given program with --complete on
	# the remainder. Treat the 'para' shortcut as if no double-dash had
	# been given. i.e. only strip off the first word.
	if [[ "${COMP_WORDS[0]}" == 'para' ]] || ((ddpos < 0)); then
		n=0
	else
		n=$ddpos
	fi
	shopt -pq extglob || old_extglob=0
	shopt -s extglob
	list=${COMP_LINE:0:$COMP_POINT}
	while ((n >= 0)); do
		list=${list##+([^ ])} # remove argument
		list=${list##*( )} # remove leading whitespace
		let n--
	done
	((!old_extglob)) && shopt -u extglob
	# prg relies on COMP_POINT and COMP_LINE, so adjust these
	export COMP_POINT=${#list}
	export COMP_LINE=$list
	COMPREPLY=($($prg --complete 2>/dev/null))
	((${#COMPREPLY[@]} == 0)) && return # oops, $prg did not write any output
	# The last line of the output contains the options for compopt, prefixed
	# with '-o='.
	n=$((${#COMPREPLY[@]} - 1))
	OLD_IFS=$IFS
	IFS=','
	for opt in ${COMPREPLY[$n]#-o=}; do
		case "$opt" in
		filenames) compopt -o default;;
		nospace) compopt -o nospace;;
		esac
	done
	IFS=$OLD_IFS
	unset COMPREPLY[$n]
	COMPREPLY=($(compgen -W "${COMPREPLY[*]}" -- "$cur"))
}

_para_audioc()
{
	_para_complete para_audioc
}

_para_client()
{
	_para_complete para_client
}
complete -F _para_audioc para_audioc
complete -F _para_client para_client para