NetworkManager/cli/completion/nmcli
Thomas Haller 623f8a2be1 cli: fix bash completion for nmcli connection modify
Only complete the setting name if it is at the very first
position after the connection.

e.g. complete the settings name in the case
  $ nmcli connection modify em1 connec<TAB>
but not at
  $ nmcli connection modify em1 connection.autoconnect <TAB>

Signed-off-by: Thomas Haller <thaller@redhat.com>
2013-10-30 13:33:47 +01:00

927 lines
39 KiB
Bash

# 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 ) )
}
_nmcli_con_id()
{
echo "$(nmcli -t -f NAME con show c 2>/dev/null)"
}
_nmcli_con_id_active()
{
echo "$(nmcli -t -f NAME con show a 2>/dev/null)"
}
_nmcli_con_uuid()
{
echo "$(nmcli -t -f UUID con show c 2>/dev/null)"
}
_nmcli_con_path()
{
echo "$(nmcli -t -f DBUS-PATH con show c 2>/dev/null)"
}
_nmcli_con_apath()
{
echo "$(nmcli -t -f DBUS-PATH con show a 2>/dev/null)"
}
_nmcli_ap_ssid()
{
echo "$(nmcli -t -f SSID dev wifi list 2>/dev/null)"
# without quotes
#ssids="$(nmcli -t -f SSID dev wifi list 2>/dev/null)"
#local IFS=$'\n'
#for ssid in $ssids; do
# temp="${ssid%\'}"
# temp="${temp#\'}"
# echo "$temp"
#done
}
_nmcli_device_wifi_list_SSID()
{
echo "$(nmcli -t -f SSID device wifi list 2>/dev/null | sort | uniq)"
}
_nmcli_ap_bssid()
{
echo "$(nmcli -e no -t -f BSSID dev wifi list 2>/dev/null)"
}
_nmcli_NM_devices()
{
echo "$(nmcli -t -f DEVICE dev status 2>/dev/null)"
}
_nmcli_NM_dev_MAC()
{
echo "$(nmcli -t dev show | grep HWADDR | cut -d':' -f2- | sort | uniq)"
}
_nmcli_array_has_value() {
# expects an array variable ARRAY defined and returns true
# if one of the arguments $@ is contained in ${ARRAY[@]}
local arg a
for arg; do
for a in "${ARRAY[@]}"; do
if [[ "$a" = "$arg" ]]; then
return 0
fi
done
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_complete_OPTIONS()
{
local OPTIONS=( -t --terse -p --pretty -m --mode -f --fields -e --escape -n --nocheck -a --ask -w --wait -v --version -h --help )
local i REMOVE_OPTIONS
for (( ; ; )); do
if [[ "${#words[@]}" -le 1 ]]; then
# 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)
fi
_nmcli_list "$(echo "${OPTIONS[@]}")"
return 0
fi
case "${words[0]}" in
-t|--terse)
REMOVE_OPTIONS=(-t --terse)
words=("${words[@]:1}")
;;
-p|--pretty)
REMOVE_OPTIONS=(-p --pretty)
words=("${words[@]:1}")
;;
-n|--nocheck)
REMOVE_OPTIONS=(-n --nocheck)
words=("${words[@]:1}")
;;
-a|--ask)
REMOVE_OPTIONS=(-a --ask)
words=("${words[@]:1}")
;;
-v|--version)
REMOVE_OPTIONS=(-v --version)
words=("${words[@]:1}")
;;
-h|--help)
REMOVE_OPTIONS=(-h --help)
words=("${words[@]:1}")
;;
-m|--mode)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "tabular multiline"
return 0
fi
REMOVE_OPTIONS=(-m --mode)
words=("${words[@]:2}")
;;
-f|--fields)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "all common"
return 0
fi
REMOVE_OPTIONS=(-f --fields)
words=("${words[@]:2}")
;;
-e|--escape)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "no yes"
return 0
fi
REMOVE_OPTIONS=(-e --escape)
words=("${words[@]:2}")
;;
-w|--wait)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list ""
return 0
fi
REMOVE_OPTIONS=(-w --wait)
words=("${words[@]:2}")
;;
*)
# something unexpected. We are finished with parsing the OPTIONS.
return 1
;;
esac
# 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
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_complete_COMMAND_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
ARRAY=("${OPTIONS_ALL[@]}")
if ! _nmcli_array_has_value "${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 "ERROR 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_MESH WIMAX INFINIBAND FIREWALL ADSL BOND VLAN BRIDGE DBUS_PROPS TEAM CONCHECK)
if [[ "${words[1]}" != "" ]]; then
# split the comma separaeted domain string into its parts LOGD
local oIFS="$IFS"
IFS=","
local LOGD=($(echo "${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 adsl bluetooth vpn olpc-mesh vlan bond bond-slave bridge bridge-slave team team-slave"
fi
return 0
fi
OPTIONS_TYPE="${words[1]}"
;;
master)
if [[ "${#words[@]}" -eq 2 ]]; then
if [[ "${words[1]}" = "" ]]; then
_nmcli_list_nl "$(_nmcli_NM_devices)"
else
_nmcli_list_nl "$(printf "%s\n%s\n%s" "$(_nmcli_NM_devices)" "$(_nmcli_con_uuid)")"
fi
return 0
fi
;;
dev)
if [[ "${#words[@]}" -eq 2 ]]; then
if [[ "${words[1]}" = "" ]]; then
_nmcli_list_nl "$(_nmcli_NM_devices)"
else
_nmcli_list_nl "$(printf "%s\n%s\n%s" "$(_nmcli_NM_devices)" "$(_nmcli_ap_bssid)" "$(_nmcli_con_uuid)")"
fi
return 0
fi
;;
primary| \
ifname)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list_nl "$(_nmcli_NM_devices)"
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"
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| \
private)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "yes no"
return 0
fi
;;
ip4| \
ip6| \
gw4| \
gw6| \
priority| \
forward-delay| \
hello-time| \
max-age| \
ageing-time| \
nsp| \
path-cost| \
name| \
mtu| \
cloned-mac| \
addr| \
config| \
parent| \
miimon| \
arp-interval| \
arp-ip-target| \
downdelay| \
updelay| \
p-key| \
mac| \
id| \
flags| \
ingress| \
dhcp-anycast| \
channel| \
egress| \
apn| \
con-name| \
user| \
password)
if [[ "${#words[@]}" -eq 2 ]]; then
return 0
fi
;;
ssid)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list_nl "$(_nmcli_device_wifi_list_SSID)"
return 0
fi
;;
ap| \
bssid)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list_nl "$(_nmcli_ap_bssid)"
return 0
fi
;;
*)
echo
echo "unexpected option. This is a bug in the completion. Check for \"${words[0]}\""
echo
return 1
;;
esac
if [[ "${#OPTIONS_NEXT_GROUP[@]}" -gt 0 ]]; then
ARRAY=("${OPTIONS_NEXT_GROUP[@]}")
if _nmcli_array_has_value "${words[0]}"; then
# the current value is from the next group...
# We back off, because the current group is complete.
return 1
fi
fi
words=("${words[@]:$N_REMOVE_WORDS}")
# 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_complete_COMMAND_CONNECTION()
{
ARRAY=("${OPTIONS[@]}")
if ! _nmcli_array_has_value "${words[0]}"; then
COMMAND_CONNECTION_TYPE=
COMMAND_CONNECTION_ID="${words[0]}"
words=("${words[@]:1}")
return 1
fi
COMMAND_CONNECTION_TYPE="${words[0]}"
COMMAND_CONNECTION_ID="${words[1]}"
case "${words[0]}" in
id)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list_nl "$(_nmcli_con_id)"
return 0
fi
words=("${words[@]:2}")
;;
uuid)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list_nl "$(_nmcli_con_uuid)"
return 0
fi
words=("${words[@]:2}")
;;
path)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list_nl "$(_nmcli_con_path)"
return 0
fi
words=("${words[@]:2}")
;;
apath)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list_nl "$(_nmcli_con_apath)"
return 0
fi
words=("${words[@]:2}")
;;
*)
COMMAND_CONNECTION_TYPE=
COMMAND_CONNECTION_ID="${words[0]}"
words=("${words[@]:1}")
;;
esac
return 1
}
_nmcli()
{
local cur prev words cword
_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]}.
words=("${words[@]:1:$cword}")
_nmcli_complete_OPTIONS && return 0
local command="${words[1]}"
local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS ARRAY OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP
local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID
case "${words[0]}" in
h|he|hel|help)
;;
g|ge|gen|gene|gener|genera|general)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list "status permissions logging help"
elif [[ ${#words[@]} -gt 2 ]]; then
case "$command" in
s|st|sta|stat|statu|status | p|pe|per|perm|permi|permis|permiss|permissi|permissio|permission|permissions)
;;
l|lo|log|logg|loggi|loggin|logging)
words=("${words[@]:2}")
OPTIONS=(level domains)
_nmcli_complete_COMMAND_ARGS
;;
esac
fi
;;
n|ne|net|netw|netwo|networ|network|networki|networkin|networking)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list "on off connectivity help"
elif [[ ${#words[@]} -eq 3 ]]; then
case "$command" in
c|co|con|conn|conne|connec|connect|connecti|connectiv|connectivi|connectivit|connectivity)
_nmcli_list "check"
;;
esac
fi
;;
r|ra|rad|radi|radio)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list "all wifi wwan wimax help"
elif [[ ${#words[@]} -eq 3 ]]; then
case "$command" in
a|al|all | w|wi|wif|wifi | ww|wwa|wwan | wim|wima|wimax)
_nmcli_list "on off"
;;
esac
fi
;;
c|co|con|conn|conne|connec|connect|connecti|connectio|connection)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list "show up down add modify edit delete reload help"
elif [[ ${#words[@]} -gt 2 ]]; then
case "$command" in
s|sh|sho|show)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list "configured active"
elif [[ ${#words[@]} -gt 3 ]]; then
case "${words[2]}" in
c|co|con|conf|confi|config|configu|configur|configure|configured)
if [[ ${#words[@]} -eq 4 ]]; then
_nmcli_list_nl "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_id)")"
else
words=("${words[@]:3}")
OPTIONS=(id uuid path)
_nmcli_complete_COMMAND_CONNECTION
fi
;;
a|ac|act|acti|activ|active)
if [[ ${#words[@]} -eq 4 ]]; then
_nmcli_list_nl "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_id_active)")"
else
words=("${words[@]:3}")
OPTIONS=(id uuid path apath)
_nmcli_complete_COMMAND_CONNECTION
fi
;;
esac
fi
;;
u|up)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list_nl "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_id)")"
elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}")
OPTIONS=(id uuid path)
_nmcli_complete_COMMAND_CONNECTION && return 0
OPTIONS=(ifname ap nsp)
_nmcli_complete_COMMAND_ARGS
fi
;;
d|do|dow|down)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list_nl "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_id_active)")"
elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}")
OPTIONS=(id uuid path apath)
_nmcli_complete_COMMAND_CONNECTION
fi
;;
a|ad|add)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list "type ifname con-name autoconnect help"
elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}")
OPTIONS_TYPE=
OPTIONS=(type ifname con-name autoconnect)
OPTIONS_MANDATORY=(type)
COMMAND_ARGS_WAIT_OPTIONS=1
_nmcli_complete_COMMAND_ARGS && return 0
ARRAY=("${OPTIONS[@]}")
if _nmcli_array_has_value "${OPTIONS_MANDATORY[@]}"; then
# we still have some missing mandatory options...
if [[ "$OPTIONS_UNKNOWN_OPTION" != '' ]]; then
ARRAY="${OPTIONS[@]}"
if ! _nmcli_array_has_value "${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)
;;
team)
OPTIONS_TYPED=(config)
;;
team-|team-s|team-sl|team-sla|team-slav|team-slave)
OPTIONS_TYPED=(master)
OPTIONS_MANDATORY=(master)
;;
bridge)
OPTIONS_TYPED=(stp priority forward-delay hello-time max-age ageing-time)
;;
bridge-|bridge-s|bridge-sl|bridge-sla|bridge-slav|bridge-slave)
OPTIONS_TYPED=(master priority path-cost hairpin)
OPTIONS_MANDATORY=(master)
;;
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)
;;
*)
# 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_complete_COMMAND_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
ARRAY=("${OPTIONS_IP[@]}")
if ! _nmcli_array_has_value "${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_complete_COMMAND_ARGS && return 0
ARRAY=("${OPTIONS[@]}")
if _nmcli_array_has_value "${OPTIONS_MANDATORY[@]}"; then
_nmcli_list "$(echo "${OPTIONS[@]}")"
return 0
fi
if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then
ARRAY=("${OPTIONS_IP[@]}")
if ! _nmcli_array_has_value "${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_complete_COMMAND_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_complete_COMMAND_ARGS && return 0
fi
;;
e|ed|edi|edit)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list_nl "$(printf "id\nuuid\npath\ntype\ncon-name\n%s" "$(_nmcli_con_id)")"
elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}")
if [[ "${words[0]}" = 'type' || "${words[0]}" = 'con-name' ]]; then
OPTIONS=(type con-name)
_nmcli_complete_COMMAND_ARGS
else
OPTIONS=(id uuid path apath)
_nmcli_complete_COMMAND_CONNECTION
fi
fi
;;
m|mo|mod|modi|modif|modify)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list_nl "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_id)")"
elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}")
OPTIONS=(id uuid path apath)
_nmcli_complete_COMMAND_CONNECTION && return 0
if [[ ${#words[@]} -le 1 ]]; then
_nmcli_list_nl "$(nmcli connection show configured "${COMMAND_CONNECTION_TYPE:-id}" "$COMMAND_CONNECTION_ID" 2>/dev/null | sed -n 's/^\([^:]\+\):.*/\1/p')"
fi
fi
;;
de|del|dele|delet|delete)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list_nl "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_id)")"
elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}")
OPTIONS=(id uuid path apath)
_nmcli_complete_COMMAND_CONNECTION
fi
;;
esac
fi
;;
d|de|dev|devi|devic|device)
if [[ ${#words[@]} -eq 2 ]]; then
_nmcli_list "status show disconnect wifi wimax help"
elif [[ ${#words[@]} -gt 2 ]]; then
case "$command" in
s|st|sta|stat|statu|status)
;;
sh|sho|show| \
d|di|dis|disc|disco|discon|disconn|disconne|disconnec|disconnect)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list_nl "$(_nmcli_NM_devices)"
fi
;;
w|wi|wif|wifi)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list "list connect rescan"
else
case "${words[2]}" in
l|li|lis|list)
words=("${words[@]:3}")
OPTIONS=(ifname bssid)
_nmcli_complete_COMMAND_ARGS
;;
c|co|con|conn|conne|connec|connect)
if [[ ${#words[@]} -eq 4 ]]; then
if [[ "${words[3]}" = "" ]]; then
_nmcli_list_nl "$(_nmcli_ap_ssid)"
else
_nmcli_list_nl "$(printf "%s\n%s" "$(_nmcli_ap_ssid)" "$(_nmcli_ap_bssid)")"
fi
else
words=("${words[@]:4}")
local OPTIONS=(password wep-key-type ifname bssid name private)
_nmcli_complete_COMMAND_ARGS
fi
;;
r|re|res|resc|resca|rescan)
words=("${words[@]:3}")
OPTIONS=(ifname)
_nmcli_complete_COMMAND_ARGS
;;
esac
fi
;;
wim|wima|wimax)
if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_list "list"
else
case "${words[2]}" in
l|li|lis|list)
words=("${words[@]:3}")
OPTIONS=(ifname nsp)
_nmcli_complete_COMMAND_ARGS
;;
c|co|con|conn|conne|connec|connect)
if [[ ${#words[@]} -eq 4 ]]; then
if [[ "${words[3]}" = "" ]]; then
_nmcli_list_nl "$(_nmcli_ap_ssid)"
else
_nmcli_list_nl "$(_nmcli_ap_ssid) $(_nmcli_ap_bssid)"
fi
else
words=("${words[@]:4}")
OPTIONS=(password wep-key-type ifname bssid name private)
_nmcli_complete_COMMAND_ARGS
fi
;;
r|re|res|resc|resca|rescan)
words=("${words[@]:3}")
OPTIONS=(ifname)
_nmcli_complete_COMMAND_ARGS
;;
esac
fi
;;
esac
fi
;;
esac
return 0
} &&
complete -F _nmcli nmcli
# ex: ts=4 sw=4 et filetype=sh