summaryrefslogtreecommitdiff
path: root/clients/cli/nmcli-completion
diff options
context:
space:
mode:
Diffstat (limited to 'clients/cli/nmcli-completion')
-rw-r--r--clients/cli/nmcli-completion1237
1 files changed, 1237 insertions, 0 deletions
diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion
new file mode 100644
index 0000000000..e6dc5b5d2d
--- /dev/null
+++ b/clients/cli/nmcli-completion
@@ -0,0 +1,1237 @@
+# nmcli(1) completion -*- shell-script -*-
+# Originally based on
+# https://github.com/GArik/bash-completion/blob/master/completions/nmcli
+
+_nmcli_list()
+{
+ COMPREPLY=( $( compgen -W '$1' -- $cur ) )
+}
+
+_nmcli_list_nl()
+{
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -W '$1' -- $cur ) )
+
+ # Now escape special characters (spaces, single and double quotes),
+ # so that the argument is really regarded a single argument by bash.
+ # See http://stackoverflow.com/questions/1146098/properly-handling-spaces-and-quotes-in-bash-completion
+ local escaped_single_quote="'\''"
+ local i=0
+ local entry
+ for entry in ${COMPREPLY[*]}
+ do
+ if [[ "${cur:0:1}" == "'" ]]; then
+ # started with single quote, escaping only other single quotes
+ # [']bla'bla"bla\bla bla --> [']bla'\''bla"bla\bla bla
+ COMPREPLY[$i]="${entry//\'/${escaped_single_quote}}"
+ elif [[ "${cur:0:1}" == '"' ]]; then
+ # started with double quote, escaping all double quotes and all backslashes
+ # ["]bla'bla"bla\bla bla --> ["]bla'bla\"bla\\bla bla
+ entry="${entry//\\/\\\\}"
+ entry="${entry//\"/\\\"}"
+ COMPREPLY[$i]="$entry"
+ else
+ # no quotes in front, escaping _everything_
+ # [ ]bla'bla"bla\bla bla --> [ ]bla\'bla\"bla\\bla\ bla
+ entry="${entry//\\/\\\\}"
+ entry="${entry//\'/\'}"
+ entry="${entry//\"/\\\"}"
+ entry="${entry// /\\ }"
+ COMPREPLY[$i]="$entry"
+ fi
+ (( i++ ))
+ done
+}
+
+_nmcli_con_show()
+{
+ nmcli -t -f "$1" connection show $2 2> /dev/null
+}
+
+_nmcli_wifi_list()
+{
+ nmcli -t -f "$1" device wifi list 2>/dev/null
+}
+
+_nmcli_dev_status()
+{
+ nmcli -t -f "$1" device status 2>/dev/null
+}
+
+_nmcli_array_has_value() {
+ # expects the name of an array as first parameter and
+ # returns true if if one of the remaining arguments is
+ # contained in the array ${$1[@]}
+ eval "local ARRAY=(\"\${$1[@]}\")"
+ local arg a
+ shift
+ for arg; do
+ for a in "${ARRAY[@]}"; do
+ if [[ "$a" = "$arg" ]]; then
+ return 0
+ fi
+ done
+ done
+ return 1
+}
+
+_nmcli_array_delete_at()
+{
+ eval "local ARRAY=(\"\${$1[@]}\")"
+ local i
+ local tmp=()
+ local lower=$2
+ local upper=${3:-$lower}
+
+ # for some reason the following fails. So this clumsy workaround...
+ # A=(a "")
+ # echo " >> ${#A[@]}"
+ # >> 2
+ # A=("${A[@]:1}")
+ # echo " >> ${#A[@]}"
+ # >> 0
+ # ... seriously???
+
+ for i in "${!ARRAY[@]}"; do
+ if [[ "$i" -lt "$2" || "$i" -gt "${3-$2}" ]]; then
+ tmp=("${tmp[@]}" "${ARRAY[$i]}")
+ fi
+ done
+ eval "$1=(\"\${tmp[@]}\")"
+}
+
+_nmcli_compl_match_option()
+{
+ local S="$1"
+ local V
+ shift
+ if [[ "${S:0:2}" == "--" ]]; then
+ S="${S:2}"
+ elif [[ "${S:0:1}" == "-" ]]; then
+ S="${S:1}"
+ fi
+ for V; do
+ case "$V" in
+ "$S"*)
+ printf "%s" "$V"
+ return 0
+ ;;
+ esac
+ done
+ return 1
+}
+
+# OPTIONS appear first at the command line (before the OBJECT).
+# This iterates over the argument list and tries to complete
+# the options. If there are options that are to be completed,
+# zero is returned and completion will be performed.
+# Otherwise it will remove all the option parameters from the ${words[@]}
+# array and return with zero (so that completion of OBJECT can continue).
+_nmcli_compl_OPTIONS()
+{
+ local i W
+
+ for (( ; ; )); do
+ if [[ "${#words[@]}" -le 1 ]]; then
+ return 1
+ fi
+ W="$(_nmcli_compl_match_option "${words[0]}" "${LONG_OPTIONS[@]}")"
+ if [[ $? != 0 ]]; then
+ return 2
+ fi
+
+ # remove the options already seen.
+ for i in ${!LONG_OPTIONS[@]}; do
+ if [[ "${LONG_OPTIONS[$i]}" == "$W" ]]; then
+ _nmcli_array_delete_at LONG_OPTIONS $i
+ break
+ fi
+ done
+
+ if [[ "$HELP_ONLY_AS_FIRST" == '1' ]]; then
+ for i in ${!LONG_OPTIONS[@]}; do
+ if [[ "${LONG_OPTIONS[$i]}" == "help" ]]; then
+ _nmcli_array_delete_at LONG_OPTIONS $i
+ break
+ fi
+ done
+ fi
+
+ case "$W" in
+ terse)
+ _nmcli_array_delete_at words 0
+ ;;
+ pretty)
+ _nmcli_array_delete_at words 0
+ ;;
+ nocheck)
+ _nmcli_array_delete_at words 0
+ ;;
+ ask)
+ _nmcli_array_delete_at words 0
+ ;;
+ active)
+ _nmcli_array_delete_at words 0
+ ;;
+ version)
+ _nmcli_array_delete_at words 0
+ ;;
+ help)
+ _nmcli_array_delete_at words 0
+ if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then
+ HELP_ONLY_AS_FIRST=0
+ return 0
+ fi
+ HELP_ONLY_AS_FIRST=0
+ ;;
+ temporary)
+ _nmcli_array_delete_at words 0
+ ;;
+ mode)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "tabular multiline"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ fields)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "all common
+ NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH
+ connection 802-3-ethernet 802-1x 802-11-wireless 802-11-wireless-security ipv4 ipv6 serial ppp pppoe gsm cdma bluetooth 802-11-olpc-mesh vpn wimax infiniband bond vlan adsl bridge bridge-port team team-port dcb
+ GENERAL IP4 DHCP4 IP6 DHCP6 VPN
+ profile active"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ escape)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "no yes"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ wait)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list ""
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ *)
+ # something unexpected. We are finished with parsing the OPTIONS.
+ return 2
+ ;;
+ esac
+ done
+}
+
+# after the OPTIONS, the OBJECT, the COMMAND and possible the COMMAND_CONNECTION, the syntax for nmcli
+# expects several options with parameters. This function can parse them and remove them from the words array.
+_nmcli_compl_ARGS()
+{
+ local OPTIONS_ALL N_REMOVE_WORDS REMOVE_OPTIONS OPTIONS_HAS_MANDATORY i
+ OPTIONS_ALL=("${OPTIONS[@]}")
+ OPTIONS_UNKNOWN_OPTION=
+
+ OPTIONS_HAS_MANDATORY=0
+ if [[ "${#OPTIONS_MANDATORY[@]}" -ge 1 ]]; then
+ OPTIONS_HAS_MANDATORY=1
+ fi
+
+ for (( ; ; )); do
+ if [[ "${#words[@]}" -le 1 ]]; then
+ # we have no more words left...
+ if [[ ${#OPTIONS[@]} -eq 0 ]]; then
+ return 1;
+ fi
+ if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then
+ _nmcli_list "$(echo "${OPTIONS[@]}")"
+ return 0
+ fi
+ COMMAND_ARGS_WAIT_OPTIONS=0
+ return 1
+ fi
+ if ! _nmcli_array_has_value OPTIONS_ALL "${words[0]}"; then
+ # This is an entirely unknown option.
+ OPTIONS_UNKNOWN_OPTION="?${words[0]}"
+ return 1
+ fi
+ if [[ "$OPTIONS_HAS_MANDATORY" -eq 1 && "${#OPTIONS_MANDATORY[@]}" -eq 0 ]]; then
+ # we had some mandatory options, but they are all satisfied... stop here...
+ # This means, that we can continue with more additional options from the NEXT_GROUP.
+ return 1
+ fi
+
+ N_REMOVE_WORDS=2
+ REMOVE_OPTIONS=("${words[0]}")
+ case "${words[0]}" in
+ level)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "ERR WARN INFO DEBUG"
+ return 0
+ fi
+ ;;
+ domains)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ local OPTIONS_DOM=(ALL DEFAULT PLATFORM RFKILL ETHER WIFI BT MB DHCP4 DHCP6 PPP WIFI_SCAN IP4 IP6 AUTOIP4 DNS VPN SHARING SUPPLICANT AGENTS SETTINGS SUSPEND CORE DEVICE OLPC WIMAX INFINIBAND FIREWALL ADSL BOND VLAN BRIDGE DBUS_PROPS TEAM CONCHECK DCB DISPATCH)
+ if [[ "${words[1]}" != "" ]]; then
+
+ # split the comma separaeted domain string into its parts LOGD
+ local oIFS="$IFS"
+ IFS=","
+ local LOGD=($(printf '%s' "${words[1]}" | sed 's/\(^\|,\)/,#/g'))
+ IFS="$oIFS"
+ unset oIFS
+
+ local LOGDLAST LOGDLAST_IS_OPTION LOGDI i
+ # first we iterate over all present domains and remove them from OPTIONS_DOM
+ for LOGDI in ${LOGD[@]}; do
+ LOGDI="${LOGDI:1}"
+ LOGDLAST="$LOGDI"
+ LOGDLAST_IS_OPTION=0
+ for i in ${!OPTIONS_DOM[*]}; do
+ if [[ "${OPTIONS_DOM[$i]}" = "$LOGDI" ]]; then
+ LOGDLAST_IS_OPTION=1
+ unset OPTIONS_DOM[$i]
+ fi
+ done
+ done
+
+ local OPTIONS_DOM2=()
+ if [[ "$LOGDLAST" = "" ]]; then
+ # we have a word that ends with ','. Just append all remaining options.
+ for i in ${!OPTIONS_DOM[*]}; do
+ OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]}${OPTIONS_DOM[$i]}"
+ done
+ else
+ # if the last option is not "" we keep only those option with the same prefix
+ # as the last domain (LOGDLAST)
+ for i in ${!OPTIONS_DOM[*]}; do
+ if [[ "${OPTIONS_DOM[$i]:0:${#LOGDLAST}}" == "$LOGDLAST" ]]; then
+ # modify the option with the present prefix
+ OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]}${OPTIONS_DOM[$i]:${#LOGDLAST}}"
+ fi
+ done
+
+ if [[ $LOGDLAST_IS_OPTION -eq 1 ]]; then
+ # if the last logd itself was a valid iption, ${words[1]} is itself a valid match
+ OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]}"
+
+ # also, add all remaining options by comma separated to the word.
+ for i in ${!OPTIONS_DOM[*]}; do
+ OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]},${OPTIONS_DOM[$i]}"
+ done
+ fi
+ if [[ ${#OPTIONS_DOM2[@]} -eq 1 ]]; then
+ for i in ${!OPTIONS_DOM[*]}; do
+ if [[ "$LOGDLAST" != "${OPTIONS_DOM[$i]:0:${#LOGDLAST}}" ]]; then
+ OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${OPTIONS_DOM2[0]},${OPTIONS_DOM[$i]}"
+ fi
+ done
+ fi
+
+ fi
+ OPTIONS_DOM=(${OPTIONS_DOM2[@]})
+ fi
+
+ _nmcli_list "$(echo "${OPTIONS_DOM[@]}")"
+ return 0
+ fi
+ ;;
+ type)
+ if [[ "$OPTIONS_TYPE" != "" ]]; then
+ return 1
+ fi
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ if [[ "${words[1]:0:1}" = "8" ]]; then
+ # usually we don't want to show the 802-x types (because the shorter aliases are more
+ # user friendly. Only complete them, if the current word already starts with an "8".
+ _nmcli_list "802-3-ethernet 802-11-wireless 802-11-olpc-mesh"
+ else
+ _nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bond-slave bridge bridge-slave team team-slave pppoe"
+ fi
+ return 0
+ fi
+ OPTIONS_TYPE="${words[1]}"
+
+ if [[ "x$OPTIONS_MANDATORY_IFNAME" != x ]]; then
+ # the ifname is not a mandatory option for a few connection types...
+ # Check, if we have such a 'type' and remove the 'ifname' from the list
+ # of mandatory options.
+ case "$OPTIONS_TYPE" in
+ vl|vla|vlan| \
+ bond| \
+ team| \
+ bridge)
+ for i in ${!OPTIONS_MANDATORY[*]}; do
+ if [[ "${OPTIONS_MANDATORY[$i]}" = "ifname" ]]; then
+ unset OPTIONS_MANDATORY[$i]
+ fi
+ done
+ ;;
+ *)
+ ;;
+
+ esac
+ OPTIONS_MANDATORY_IFNAME=
+ fi
+ ;;
+ master)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ if [[ "${words[1]}" = "" ]]; then
+ _nmcli_list_nl "$(_nmcli_dev_status DEVICE)"
+ else
+ _nmcli_list_nl "$(printf "%s\n%s\n%s" "$(_nmcli_dev_status DEVICE)" "$(_nmcli_con_show UUID)")"
+ fi
+ return 0
+ fi
+ ;;
+ dev)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ if [[ "${words[1]}" = "" ]]; then
+ _nmcli_list_nl "$(_nmcli_dev_status DEVICE)"
+ else
+ _nmcli_list_nl "$(printf "%s\n%s\n%s" "$(_nmcli_dev_status DEVICE)" "$(_nmcli_wifi_list BSSID)" "$(_nmcli_con_show UUID)")"
+ fi
+ return 0
+ fi
+ ;;
+ primary| \
+ ifname)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_dev_status DEVICE)"
+ return 0
+ fi
+ ;;
+ mode)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb"
+ return 0
+ fi
+ ;;
+ transport-mode)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "datagram connected"
+ return 0
+ fi
+ ;;
+ vpn-type)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "vpnc openvpn pptp openconnect openswan libreswan ssh l2tp iodine"
+ return 0
+ fi
+ ;;
+ bt-type)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "panu dun-gsm dun-cdma"
+ return 0
+ fi
+ ;;
+ wep-key-type)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "key phrase"
+ return 0
+ fi
+ ;;
+ autoconnect| \
+ stp| \
+ hairpin| \
+ save| \
+ private)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list "yes no"
+ return 0
+ fi
+ ;;
+ config)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ compopt -o default
+ COMPREPLY=()
+ return 0
+ fi
+ ;;
+ ip4| \
+ ip6| \
+ gw4| \
+ gw6| \
+ priority| \
+ forward-delay| \
+ hello-time| \
+ max-age| \
+ ageing-time| \
+ nsp| \
+ path-cost| \
+ name| \
+ mtu| \
+ cloned-mac| \
+ addr| \
+ parent| \
+ miimon| \
+ arp-interval| \
+ arp-ip-target| \
+ downdelay| \
+ updelay| \
+ p-key| \
+ mac| \
+ id| \
+ flags| \
+ ingress| \
+ dhcp-anycast| \
+ channel| \
+ egress| \
+ apn| \
+ con-name| \
+ user| \
+ username| \
+ service| \
+ password)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ return 0
+ fi
+ ;;
+ ssid)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_wifi_list SSID)"
+ return 0
+ fi
+ ;;
+ ap| \
+ bssid)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_wifi_list BSSID)"
+ return 0
+ fi
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+
+
+ if [[ "${#OPTIONS_NEXT_GROUP[@]}" -gt 0 ]]; then
+ if _nmcli_array_has_value OPTIONS_NEXT_GROUP "${words[0]}"; then
+ # the current value is from the next group...
+ # We back off, because the current group is complete.
+ return 1
+ fi
+ fi
+
+ _nmcli_array_delete_at words 0 $((N_REMOVE_WORDS-1))
+ # remove the options already seen.
+ for i in ${!OPTIONS[*]}; do
+ if [[ "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then
+ unset OPTIONS[$i]
+ fi
+ done
+ for i in ${!OPTIONS_MANDATORY[*]}; do
+ if [[ "${OPTIONS_MANDATORY[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS_MANDATORY[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then
+ unset OPTIONS_MANDATORY[$i]
+ fi
+ done
+ done
+}
+
+# some commands expect a connection as parameter. This connection can either be given
+# as id|uuid|path|apath. Parse that connection parameter.
+_nmcli_compl_ARGS_CONNECTION()
+{
+ if ! _nmcli_array_has_value OPTIONS "${words[0]}"; then
+ COMMAND_CONNECTION_TYPE=
+ COMMAND_CONNECTION_ID="${words[0]}"
+ _nmcli_array_delete_at words 0
+ return 1
+ fi
+ COMMAND_CONNECTION_TYPE="${words[0]}"
+ COMMAND_CONNECTION_ID="${words[1]}"
+ local CON_TYPE=
+ if [[ "x$COMMAND_CONNECTION_ACTIVE" != x ]]; then
+ CON_TYPE=--active
+ fi
+ case "${words[0]}" in
+ id)
+ if [[ ${#words[@]} -le 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_con_show NAME $CON_TYPE)"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ uuid)
+ if [[ ${#words[@]} -le 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_con_show UUID $CON_TYPE)"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ path)
+ if [[ ${#words[@]} -le 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_con_show DBUS-PATH $CON_TYPE)"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ apath)
+ if [[ ${#words[@]} -le 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_con_show ACTIVE-PATH --active)"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ ifname)
+ if [[ ${#words[@]} -le 2 ]]; then
+ _nmcli_list_nl "$(_nmcli_dev_status DEVICE)"
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ ;;
+ *)
+ COMMAND_CONNECTION_TYPE=
+ COMMAND_CONNECTION_ID="${words[0]}"
+ _nmcli_array_delete_at words 0
+ ;;
+ esac
+ return 1
+}
+
+_nmcli_compl_COMMAND() {
+ local command="$1"
+ shift
+ local V=("$@")
+ local H=
+ if [[ "${command[0]:0:1}" != '-' ]]; then
+ H=help
+ elif [[ "${command[0]:1:1}" == '-' || "${command[0]}" == "-" ]]; then
+ H=--help
+ else
+ H=-help
+ fi
+ if [[ "x$COMPL_COMMAND_NO_HELP" == x ]]; then
+ V=("${V[@]}" "$H")
+ fi
+ _nmcli_list "${V[*]}"
+}
+
+_nmcli_compl_COMMAND_nl() {
+ local command="$1"
+ local a="$2"
+ shift
+ shift
+ local V=("$@")
+ local H=
+ if [[ "${command[0]:0:1}" != '-' ]]; then
+ V=("${V[@]/#/--}")
+ H=help
+ elif [[ "${command[0]:1:1}" == '-' || "${command[0]}" == "-" ]]; then
+ V=("${V[@]/#/--}")
+ H=--help
+ else
+ V=("${V[@]/#/-}")
+ H=-help
+ fi
+ if [[ "x$COMPL_COMMAND_NO_HELP" == x ]]; then
+ V=("${V[@]}" "$H")
+ fi
+ local IFS=$'\n'
+ V="${V[*]}"
+ _nmcli_list_nl "$(printf "%s%s\n%s" "" "$V" "$a")"
+}
+
+_nmcli()
+{
+ local cur prev words cword i
+ _init_completion || return
+
+ # we don't care about any arguments after the current cursor position
+ # because we only parse from left to right. So, if there are some arguments
+ # right of the cursor, just ignore them. Also don't care about ${words[0]}.
+ _nmcli_array_delete_at words $((cword+1)) ${#words[@]}
+ _nmcli_array_delete_at words 0
+
+ # _init_completion returns the words with all the quotes and escaping
+ # characters. We don't care about them, drop them at first.
+ for i in ${!words[@]}; do
+ words[i]="$(printf '%s' "${words[i]}" | xargs printf '%s\n' 2>/dev/null || true)"
+ done
+
+ # In case the cursor is not at the end of the line,
+ # $cur consists of spaces that we want do remove.
+ # For example: `nmcli connection modify id <TAB> lo`
+ if [[ "$cur" =~ ^[[:space:]]+ ]]; then
+ cur=''
+ fi
+
+ local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP
+ local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID OPTIONS_MANDATORY_IFNAME HELP_ONLY_AS_FIRST
+ local COMMAND_CONNECTION_ACTIVE=""
+
+ HELP_ONLY_AS_FIRST=
+ local LONG_OPTIONS=(terse pretty mode fields escape nocheck ask wait version help)
+ _nmcli_compl_OPTIONS
+ i=$?
+
+ if [[ "$HELP_ONLY_AS_FIRST" == '0' ]]; then
+ # got a --help. No more completion.
+ return 0
+ fi
+
+ case $i in
+ 0)
+ return 0
+ ;;
+ 1)
+ # we show for completion either the (remaining) OPTIONS
+ # (if the current word starts with a dash) or the OBJECT list
+ # otherwise.
+ if [[ "${words[0]:0:1}" != '-' ]]; then
+ OPTIONS=(help general networking radio connection device)
+ elif [[ "${words[0]:1:1}" == '-' || "${words[0]}" == "-" ]]; then
+ OPTIONS=("${LONG_OPTIONS[@]/#/--}")
+ else
+ OPTIONS=("${LONG_OPTIONS[@]/#/-}")
+ fi
+ _nmcli_list "${OPTIONS[*]}"
+ return 0
+ ;;
+ esac
+
+ local command="${words[1]}"
+ case "${words[0]}" in
+ h|he|hel|help)
+ ;;
+ g|ge|gen|gene|gener|genera|general)
+ if [[ ${#words[@]} -eq 2 ]]; then
+ _nmcli_compl_COMMAND "$command" status permissions logging hostname
+ elif [[ ${#words[@]} -gt 2 ]]; then
+ case "$command" in
+ ho|hos|host|hostn|hostna|hostnam|hostname)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" \
+ "$(printf '%s\n%s\n%s\n' \
+ "$(nmcli general hostname 2>/dev/null)" \
+ "$(cat /etc/hostname 2>/dev/null)" \
+ "$(hostnamectl status 2>/dev/null | sed -n '1s/^.\+hostname: \(.\+\)$/\1/p')" \
+ "$HOSTNAME")"
+ fi
+ ;;
+ l|lo|log|logg|loggi|loggin|logging)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND "${words[2]}" level domains
+ else
+ _nmcli_array_delete_at words 0 1
+ OPTIONS=(level domains)
+ _nmcli_compl_ARGS
+ fi
+ ;;
+ esac
+ fi
+ ;;
+ n|ne|net|netw|netwo|networ|network|networki|networkin|networking)
+ if [[ ${#words[@]} -eq 2 ]]; then
+ _nmcli_compl_COMMAND "$command" on off connectivity
+ elif [[ ${#words[@]} -eq 3 ]]; then
+ case "$command" in
+ c|co|con|conn|conne|connec|connect|connecti|connectiv|connectivi|connectivit|connectivity)
+ _nmcli_compl_COMMAND "${words[2]}" "check"
+ ;;
+ esac
+ fi
+ ;;
+ r|ra|rad|radi|radio)
+ if [[ ${#words[@]} -eq 2 ]]; then
+ _nmcli_compl_COMMAND "$command" all wifi wwan wimax
+ elif [[ ${#words[@]} -eq 3 ]]; then
+ case "$command" in
+ a|al|all | w|wi|wif|wifi | ww|wwa|wwan | wim|wima|wimax)
+ _nmcli_compl_COMMAND "${words[2]}" "on off"
+ ;;
+ esac
+ fi
+ ;;
+ c|co|con|conn|conne|connec|connect|connecti|connectio|connection)
+ if [[ ${#words[@]} -eq 2 ]]; then
+ _nmcli_compl_COMMAND "$command" show up down add modify edit delete reload load
+ elif [[ ${#words[@]} -gt 2 ]]; then
+ case "$command" in
+ s|sh|sho|show)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")" active
+ elif [[ ${#words[@]} -gt 3 ]]; then
+ _nmcli_array_delete_at words 0 1
+
+ LONG_OPTIONS=(help active)
+ HELP_ONLY_AS_FIRST=1
+ _nmcli_compl_OPTIONS
+ i=$?
+
+ if ! _nmcli_array_has_value LONG_OPTIONS active; then
+ COMMAND_CONNECTION_ACTIVE=1
+ fi
+
+ case $i in
+ 0)
+ return 0
+ ;;
+ 1)
+ if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then
+ if [[ "x$COMMAND_CONNECTION_ACTIVE" = x ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}"
+
+ else
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")" "${LONG_OPTIONS[@]}"
+ fi
+ fi
+ return 0
+ ;;
+ esac
+
+ OPTIONS=(id uuid path apath)
+ while [[ ${#words[@]} -gt 0 ]]; do
+ _nmcli_compl_ARGS_CONNECTION && return 0
+ done
+ if [[ "x$COMMAND_CONNECTION_ACTIVE" = x ]]; then
+ _nmcli_list_nl "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")"
+ else
+ _nmcli_list_nl "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")"
+ fi
+ fi
+ ;;
+ u|up)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "ifname\nid\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")"
+ elif [[ ${#words[@]} -gt 3 ]]; then
+ _nmcli_array_delete_at words 0 1
+
+ LONG_OPTIONS=(help)
+ HELP_ONLY_AS_FIRST=1
+ _nmcli_compl_OPTIONS
+
+ case $? in
+ 0)
+ return 0
+ ;;
+ 1)
+ if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "ifname\nid\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}"
+ fi
+ return 0
+ ;;
+ esac
+
+ local COMMAND_CONNECTION_TYPE=''
+ OPTIONS=(ifname id uuid path)
+ _nmcli_compl_ARGS_CONNECTION && return 0
+
+ if [[ "$COMMAND_CONNECTION_TYPE" = "ifname" ]]; then
+ OPTIONS=(ap nsp)
+ else
+ OPTIONS=(ifname ap nsp)
+ fi
+ _nmcli_compl_ARGS
+ fi
+ ;;
+ d|do|dow|down)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")"
+ elif [[ ${#words[@]} -gt 3 ]]; then
+ _nmcli_array_delete_at words 0 1
+
+ LONG_OPTIONS=(help)
+ HELP_ONLY_AS_FIRST=1
+ _nmcli_compl_OPTIONS
+ case $? in
+ 0)
+ return 0
+ ;;
+ 1)
+ if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")" "${LONG_OPTIONS[@]}"
+ fi
+ return 0
+ ;;
+ esac
+
+ OPTIONS=(id uuid path apath)
+ COMMAND_CONNECTION_ACTIVE=1
+ _nmcli_compl_ARGS_CONNECTION && return 0
+ fi
+ ;;
+ a|ad|add)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND "${words[2]}" type ifname con-name autoconnect
+ elif [[ ${#words[@]} -gt 3 ]]; then
+ _nmcli_array_delete_at words 0 1
+
+ LONG_OPTIONS=(help)
+ HELP_ONLY_AS_FIRST=1
+ _nmcli_compl_OPTIONS
+ case $? in
+ 0)
+ return 0
+ ;;
+ 1)
+ if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then
+ _nmcli_compl_COMMAND "${words[2]}" type ifname con-name autoconnect
+ fi
+ return 0
+ ;;
+ esac
+
+ OPTIONS_TYPE=
+ OPTIONS=(type ifname con-name autoconnect save)
+ OPTIONS_MANDATORY=(type ifname)
+ COMMAND_ARGS_WAIT_OPTIONS=1
+ OPTIONS_MANDATORY_IFNAME=1
+ _nmcli_compl_ARGS && return 0
+
+ OPTIONS_MANDATORY_IFNAME=
+ if _nmcli_array_has_value OPTIONS "${OPTIONS_MANDATORY[@]}"; then
+ # we still have some missing mandatory options...
+ if [[ "$OPTIONS_UNKNOWN_OPTION" != '' ]]; then
+ if ! _nmcli_array_has_value OPTIONS "${OPTIONS_UNKNOWN_OPTION:1}"; then
+ # if we encountered an unknown option while having mandatory
+ # options, just return.
+ return 0
+ fi
+ fi
+ _nmcli_list "$(echo "${OPTIONS[@]}")"
+ return 0
+ fi
+
+ OPTIONS_IP=(ip4 ip6 gw4 gw6)
+ OPTIONS_MANDATORY=()
+ case "$OPTIONS_TYPE" in
+ 802-3|802-3-|802-3-e|802-3-et|802-3-eth|802-3-ethe|802-3-ether|802-3-ethern|802-3-etherne|802-3-ethernet| \
+ e|et|eth|ethe|ether|ethern|etherne|ethernet)
+ OPTIONS_TYPED=(mac cloned-mac mtu)
+ ;;
+ 802-11-w|802-11-wi|802-11-wir|802-11-wire|802-11-wirel|802-11-wirele|802-11-wireles|802-11-wireless| \
+ wif|wifi)
+ OPTIONS_TYPED=(ssid mac cloned-mac mtu)
+ OPTIONS_MANDATORY=(ssid)
+ ;;
+ wim|wima|wimax)
+ OPTIONS_TYPED=(mac nsp)
+ ;;
+ g|gs|gsm)
+ OPTIONS_TYPED=(apn user password)
+ OPTIONS_MANDATORY=(apn)
+ ;;
+ c|cd|cdm|cdma)
+ OPTIONS_TYPED=(user password)
+ ;;
+ i|in|inf|infi|infin|infini|infinib|infiniba|infiniban|infiniband)
+ OPTIONS_TYPED=(mac mtu transport-mode parent p-key)
+ ;;
+ bl|blu|blue|bluet|blueto|bluetoo|bluetoot|bluetooth)
+ OPTIONS_TYPED=(addr bt-type)
+ ;;
+ vl|vla|vlan)
+ OPTIONS_TYPED=(dev id flags ingress egress mtu)
+ OPTIONS_MANDATORY=(dev)
+ ;;
+ bond)
+ OPTIONS_TYPED=(mode miimon downdelay updelay arp-interval arp-ip-target primary)
+ ;;
+ bond-|bond-s|bond-sl|bond-sla|bond-slav|bond-slave)
+ OPTIONS_TYPED=(master)
+ OPTIONS_MANDATORY=(master)
+ OPTIONS_IP=()
+ ;;
+ team)
+ OPTIONS_TYPED=(config)
+ ;;
+ team-|team-s|team-sl|team-sla|team-slav|team-slave)
+ OPTIONS_TYPED=(master config)
+ OPTIONS_MANDATORY=(master)
+ OPTIONS_IP=()
+ ;;
+ bridge)
+ OPTIONS_TYPED=(stp priority forward-delay hello-time max-age ageing-time mac)
+ ;;
+ bridge-|bridge-s|bridge-sl|bridge-sla|bridge-slav|bridge-slave)
+ OPTIONS_TYPED=(master priority path-cost hairpin)
+ OPTIONS_MANDATORY=(master)
+ OPTIONS_IP=()
+ ;;
+ vp|vpn)
+ OPTIONS_TYPED=(vpn-type user)
+ OPTIONS_MANDATORY=(vpn-type)
+ ;;
+ 802-11-o|802-11-ol|802-11-olp|802-11-olpc|802-11-olpc-|802-11-olpc-m|802-11-olpc-me|802-11-olpc-mes|802-11-olpc-mesh| \
+ o|ol|olp|olpc|olpc-|olpc-m|olpc-me|olpc-mes|olpc-mesh)
+ OPTIONS_TYPED=(ssid channel dhcp-anycast)
+ OPTIONS_MANDATORY=(ssid)
+ ;;
+ p|pp|ppp|pppo|pppoe)
+ OPTIONS_TYPED=(username password service mtu mac)
+ OPTIONS_MANDATORY=(username)
+ ;;
+ *)
+ # for an unknown connection type, we stop completion here
+ return 0
+ ;;
+ esac
+ if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then
+ # means, we are at the end of options. Nothing more to parse, just show
+ # what are the options now.
+ if [[ "${#OPTIONS_MANDATORY[@]}" -gt 0 ]]; then
+ _nmcli_list "$(echo "${OPTIONS[@]}") $(echo "${OPTIONS_TYPED[@]}")"
+ else
+ _nmcli_list "$(echo "${OPTIONS[@]}") $(echo "${OPTIONS_TYPED[@]}") $(echo "${OPTIONS_IP[@]}")"
+ fi
+ return 0
+ fi
+ if [[ "${#OPTIONS[@]}" -gt 0 ]]; then
+ # we still have some options from before, but no mandatory ones. Mix them with OPTIONS_TYPED
+ # and continue parsing the options...
+ OPTIONS=("${OPTIONS[@]}" "${OPTIONS_TYPED[@]}")
+ OPTIONS_NEXT_GROUP=("${OPTIONS_TYPED[@]}")
+ _nmcli_compl_ARGS && return 0
+
+ if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then
+ # means, we are at the end of options. Nothing more to parse, just show
+ # what are the options now.
+ if [[ "${#OPTIONS_MANDATORY[@]}" -gt 0 ]]; then
+ _nmcli_list "$(echo "${OPTIONS[@]}")"
+ else
+ _nmcli_list "$(echo "${OPTIONS[@]}") $(echo "${OPTIONS_IP[@]}")"
+ fi
+ return 0
+ fi
+
+ if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then
+ # there was an unknown option specified. Maybe we have to stop with the completion.
+ if [[ "${#OPTIONS_MANDATORY[@]}" -gt 0 ]]; then
+ # we have an unknown option, but still mandatory ones that must be fullfiled first.
+ return 0
+ fi
+ if ! _nmcli_array_has_value OPTIONS_IP "${OPTIONS_UNKNOWN_OPTION:1}"; then
+ # the unknown option is NOT an IP option.
+ return 0
+ fi
+ # The unknown option is an IP option, which is fine... continue...
+ fi
+
+ fi
+ OPTIONS=("${OPTIONS_TYPED[@]}")
+ OPTIONS_NEXT_GROUP=()
+
+ if [[ "${#OPTIONS_MANDATORY[@]}" -ge 1 ]]; then
+ # we have some mandatory options... don't check for IP options yet...
+ _nmcli_compl_ARGS && return 0
+
+ if _nmcli_array_has_value OPTIONS "${OPTIONS_MANDATORY[@]}"; then
+ _nmcli_list "$(echo "${OPTIONS[@]}")"
+ return 0
+ fi
+
+ if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then
+ if ! _nmcli_array_has_value OPTIONS_IP "${OPTIONS_UNKNOWN_OPTION:1}"; then
+ # the unknown option is NOT an IP option.
+ return 0
+ fi
+ fi
+ fi
+
+
+ # no mandatory options... do final completion including IP options
+ OPTIONS=("${OPTIONS[@]}" "${OPTIONS_IP[@]}")
+ OPTIONS_NEXT_GROUP=("${OPTIONS_IP[@]}")
+ _nmcli_compl_ARGS && return 0
+
+ if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then
+ return 0
+ fi
+
+ if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then
+ # means, we are at the end of options. Nothing more to parse, just show
+ # what are the options now.
+ _nmcli_list "$(echo "${OPTIONS[@]}")"
+ return 0
+ fi
+
+ # process the last group of options, as the OPTIONS_TYPED are already handled...
+ OPTIONS=("${OPTIONS_IP[@]}")
+ OPTIONS_NEXT_GROUP=()
+ COMMAND_ARGS_WAIT_OPTIONS=0
+ _nmcli_compl_ARGS && return 0
+ fi
+ ;;
+ e|ed|edi|edit)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\ntype\ncon-name\n%s" "$(_nmcli_con_show NAME)")"
+ elif [[ ${#words[@]} -gt 3 ]]; then
+ _nmcli_array_delete_at words 0 1
+
+ LONG_OPTIONS=(help)
+ HELP_ONLY_AS_FIRST=1
+ _nmcli_compl_OPTIONS
+
+ case $? in
+ 0)
+ return 0
+ ;;
+ 1)
+ if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\ntype\ncon-name\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}"
+ fi
+ return 0
+ ;;
+ esac
+
+ if [[ "${words[0]}" = 'type' || "${words[0]}" = 'con-name' ]]; then
+ OPTIONS=(type con-name)
+ _nmcli_compl_ARGS
+ else
+ OPTIONS=(id uuid path apath)
+ _nmcli_compl_ARGS_CONNECTION
+ fi
+ fi
+ ;;
+ m|mo|mod|modi|modif|modify)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" temporary
+ elif [[ ${#words[@]} -gt 3 ]]; then
+ _nmcli_array_delete_at words 0 1
+
+ LONG_OPTIONS=(help temporary)
+ HELP_ONLY_AS_FIRST=1
+ _nmcli_compl_OPTIONS
+ case $? in
+ 0)
+ return 0
+ ;;
+ 1)
+ if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}"
+ fi
+ return 0
+ ;;
+ esac
+
+ OPTIONS=(id uuid path apath)
+ _nmcli_compl_ARGS_CONNECTION && return 0
+ while [[ "${#words[@]}" -gt 0 ]]; do
+ if [[ ${#words[@]} -le 1 ]]; then
+ _nmcli_list_nl "$(nmcli --fields profile connection show "${COMMAND_CONNECTION_TYPE:-id}" "$COMMAND_CONNECTION_ID" 2>/dev/null | sed -n 's/^\([^:]\+\):.*/\1/p')"
+ return 0
+ elif [[ ${#words[@]} -le 2 ]]; then
+ return 0
+ fi
+ _nmcli_array_delete_at words 0 1
+ done
+ _nmcli_list_nl "$(nmcli --fields profile connection show "${COMMAND_CONNECTION_TYPE:-id}" "$COMMAND_CONNECTION_ID" 2>/dev/null | sed -n 's/^\([^:]\+\):.*/\1/p')"
+ return 0
+ fi
+ ;;
+ de|del|dele|delet|delete)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")"
+ elif [[ ${#words[@]} -gt 3 ]]; then
+ _nmcli_array_delete_at words 0 1
+
+ LONG_OPTIONS=(help)
+ _nmcli_compl_OPTIONS
+ case $? in
+ 0)
+ return 0
+ ;;
+ 1)
+ if ! _nmcli_array_has_value LONG_OPTIONS "help"; then
+ return 0
+ fi
+ ;;
+ esac
+
+ OPTIONS=(id uuid path apath)
+ while [[ ${#words[@]} -gt 0 ]]; do
+ _nmcli_compl_ARGS_CONNECTION && return 0
+ done
+ _nmcli_list_nl "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")"
+ fi
+ ;;
+ l|lo|loa|load)
+ if [[ ${#words[@]} -gt 2 ]]; then
+ # we should also complete for help/--help, but who to mix that
+ # with file name completion?
+ compopt -o default
+ COMPREPLY=()
+ fi
+ ;;
+ esac
+ fi
+ ;;
+ d|de|dev|devi|devic|device)
+ if [[ ${#words[@]} -eq 2 ]]; then
+ _nmcli_compl_COMMAND "$command" status show connect disconnect delete wifi wimax
+ elif [[ ${#words[@]} -gt 2 ]]; then
+ case "$command" in
+ s|st|sta|stat|statu|status)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND "${words[2]}"
+ fi
+ ;;
+ sh|sho|show| \
+ c|co|con|conn|conne|connec|connect| \
+ d|di|dis|disc|disco|discon|disconn|disconne|disconnec|disconnect| \
+ de|del|dele|delet|delete)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND_nl "${words[2]}" "$(_nmcli_dev_status DEVICE)"
+ fi
+ ;;
+ w|wi|wif|wifi)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND "${words[2]}" list connect rescan
+ else
+ case "${words[2]}" in
+ l|li|lis|list)
+ _nmcli_array_delete_at words 0 2
+ OPTIONS=(ifname bssid)
+ _nmcli_compl_ARGS
+ ;;
+ c|co|con|conn|conne|connec|connect)
+ if [[ ${#words[@]} -eq 4 ]]; then
+ if [[ "${words[3]}" = "" ]]; then
+ _nmcli_list_nl "$(_nmcli_wifi_list SSID)"
+ else
+ _nmcli_list_nl "$(printf "%s\n%s" "$(_nmcli_wifi_list SSID)" "$(_nmcli_wifi_list BSSID)")"
+ fi
+ else
+ _nmcli_array_delete_at words 0 3
+ local OPTIONS=(password wep-key-type ifname bssid name private)
+ _nmcli_compl_ARGS
+ fi
+ ;;
+ r|re|res|resc|resca|rescan)
+ _nmcli_array_delete_at words 0 2
+ OPTIONS=(ifname)
+ _nmcli_compl_ARGS
+ ;;
+ esac
+ fi
+ ;;
+ wim|wima|wimax)
+ if [[ ${#words[@]} -eq 3 ]]; then
+ _nmcli_compl_COMMAND "${words[2]}" list
+ else
+ case "${words[2]}" in
+ l|li|lis|list)
+ _nmcli_array_delete_at words 0 2
+ OPTIONS=(ifname nsp)
+ _nmcli_compl_ARGS
+ ;;
+ esac
+ fi
+ ;;
+
+ esac
+ fi
+ ;;
+ esac
+
+ return 0
+} &&
+complete -F _nmcli nmcli
+
+# ex: ts=4 sw=4 et filetype=sh