diff options
Diffstat (limited to 'cli/completion/nmcli')
| -rw-r--r-- | cli/completion/nmcli | 1236 |
1 files changed, 0 insertions, 1236 deletions
diff --git a/cli/completion/nmcli b/cli/completion/nmcli deleted file mode 100644 index 343c7322..00000000 --- a/cli/completion/nmcli +++ /dev/null @@ -1,1236 +0,0 @@ -# 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 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) - 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 |