mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-04 21:10:32 +01:00
To support optimal completion, more context must be considered. Especially the OPTIONS, which must appear before the OBJECT. Modify bash completion to try parsing first the options. Before, whenever you had options, completion did not work anymore (because the object was expected as first argument). Moreover, options were also suggested after specifying the object. This is now mitigated by parsing the command line in two steps. Signed-off-by: Thomas Haller <thaller@redhat.com>
425 lines
13 KiB
Bash
425 lines
13 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_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_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)"
|
|
}
|
|
|
|
# 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 )
|
|
|
|
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
|
|
}
|
|
|
|
_nmcli()
|
|
{
|
|
local cur prev words cword
|
|
_init_completion || return
|
|
|
|
# we don't care about any arguments after the current curser position
|
|
# because we only parse from left to right. So, if there are some arguments
|
|
# right of the curser, just ignore them. Also don't care about ${words[0]}.
|
|
words=("${words[@]:1:$cword}")
|
|
|
|
_nmcli_complete_OPTIONS && return 0
|
|
|
|
# FIXME: the following block completes certain parameters without
|
|
# considering enough context, while they only make sense depending on
|
|
# the OBJECT and COMMAND.
|
|
case $prev in
|
|
id)
|
|
_nmcli_list_nl "$(_nmcli_con_id)"
|
|
return 0
|
|
;;
|
|
uuid)
|
|
_nmcli_list_nl "$(_nmcli_con_uuid)"
|
|
return 0
|
|
;;
|
|
path)
|
|
_nmcli_list_nl "$(_nmcli_con_path)"
|
|
return 0
|
|
;;
|
|
apath)
|
|
_nmcli_list_nl "$(_nmcli_con_apath)"
|
|
return 0
|
|
;;
|
|
iface | ifname)
|
|
#_available_interfaces
|
|
_nmcli_list_nl "$(_nmcli_NM_devices)"
|
|
return 0
|
|
;;
|
|
bssid)
|
|
_nmcli_list_nl "$(_nmcli_ap_bssid)"
|
|
return 0
|
|
;;
|
|
wep-key-type)
|
|
_nmcli_list "key phrase"
|
|
return 0
|
|
;;
|
|
autoconnect | stp | hairpin | private)
|
|
_nmcli_list "yes no"
|
|
return 0
|
|
;;
|
|
# connection types
|
|
type)
|
|
_nmcli_list "ethernet wifi wimax gsm cdma infiniband adsl bluetooth vpn \
|
|
olpc-mesh vlan bond bridge bond-slave bridge-slave"
|
|
return 0
|
|
;;
|
|
# VPN types
|
|
vpn-type)
|
|
_nmcli_list "vpn-type vpnc openvpn pptp openconnect openswan"
|
|
return 0
|
|
;;
|
|
# Bluetooth modes
|
|
bt-type)
|
|
_nmcli_list "panu dun-gsm dun-cdma"
|
|
return 0
|
|
;;
|
|
# InfiniBand transport modes
|
|
transport-mode)
|
|
_nmcli_list "datagram connected"
|
|
return 0
|
|
;;
|
|
# bonding modes
|
|
mode)
|
|
_nmcli_list "balance-rr active-backup balance-xor broadcast \
|
|
802.3ad balance-tlb balance-alb"
|
|
return 0
|
|
;;
|
|
# MAC addresses
|
|
mac)
|
|
_mac_addresses
|
|
return 0
|
|
;;
|
|
# master interface
|
|
master)
|
|
UUIDS=$(_nmcli_con_uuid)
|
|
DEVICES=$(_nmcli_NM_devices)
|
|
_nmcli_list "$DEVICES $UUIDS"
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
local object=${words[0]}
|
|
local command=${words[1]}
|
|
|
|
case $object in
|
|
h|he|hel|help)
|
|
return 0
|
|
;;
|
|
g|ge|gen|gene|gener|genera|general)
|
|
if [[ ${#words[@]} -gt 2 ]]; then
|
|
case $command in
|
|
s|st|sta|stat|statu|status | p|pe|per|perm|permi|permis|permiss|permissi|permissio|permission|permissions)
|
|
return 0
|
|
;;
|
|
l|lo|log|logg|loggi|loggin|logging)
|
|
_nmcli_list "level domains"
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
_nmcli_list "status permissions logging help"
|
|
;;
|
|
|
|
n|ne|net|netw|netwo|networ|network|networki|networkin|networking)
|
|
if [[ ${#words[@]} -gt 2 ]]; then
|
|
case $command in
|
|
on | off)
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
_nmcli_list "on off help"
|
|
;;
|
|
|
|
r|ra|rad|radi|radio)
|
|
if [[ ${#words[@]} -gt 2 ]]; then
|
|
case $command in
|
|
a|al|all | w|wi|wif|wifi | ww|wwa|wwan | wim|wima|wimax)
|
|
_nmcli_list "on off"
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
_nmcli_list "all wifi wwan wimax help"
|
|
;;
|
|
|
|
c|co|con|conn|conne|connec|connect|connecti|connectio|connection)
|
|
if [[ ${#words[@]} -gt 2 ]]; then
|
|
case $command in
|
|
s|sh|sho|show)
|
|
local subcommand=${words[2]}
|
|
|
|
if [[ ${#words[@]} -gt 3 ]]; then
|
|
case $subcommand in
|
|
c|co|con|conf|confi|config|configu|configur|configure|configured)
|
|
_nmcli_list "id uuid path"
|
|
return 0
|
|
;;
|
|
a|ac|act|acti|activ|active)
|
|
_nmcli_list "id uuid path apath"
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
_nmcli_list "configured active"
|
|
return 0
|
|
;;
|
|
u|up)
|
|
if [[ "$cur" == -* ]]; then
|
|
_nmcli_list "--nowait --timeout"
|
|
else
|
|
_nmcli_list "id uuid path iface ap nsp"
|
|
fi
|
|
return 0
|
|
;;
|
|
d|do|dow|down)
|
|
_nmcli_list "id uuid path apath"
|
|
return 0
|
|
;;
|
|
a|ad|add)
|
|
_nmcli_list "type con-name autoconnect ifname help"
|
|
return 0
|
|
;;
|
|
e|ed|edi|edit)
|
|
_nmcli_list "id uuid path type con-name"
|
|
return 0
|
|
;;
|
|
m|mo|mod|modi|modif|modify)
|
|
_nmcli_list_nl "$(_nmcli_con_id)"
|
|
return 0
|
|
;;
|
|
de|del|dele|delet|delete)
|
|
_nmcli_list "id uuid path"
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
_nmcli_list "show up down add modify edit delete reload help"
|
|
;;
|
|
|
|
d|de|dev|devi|devic|device)
|
|
if [[ ${#words[@]} -gt 2 ]]; then
|
|
case $command in
|
|
sh|sho|show)
|
|
_nmcli_list_nl "$(_nmcli_NM_devices)"
|
|
return 0
|
|
;;
|
|
d|di|dis|disc|disco|discon|disconn|disconne|disconnec|disconnect)
|
|
if [[ "$cur" == -* ]]; then
|
|
_nmcli_list "--nowait --timeout"
|
|
else
|
|
_nmcli_list_nl "$(_nmcli_NM_devices)"
|
|
fi
|
|
return 0
|
|
;;
|
|
w|wi|wif|wifi)
|
|
local subcommand=${words[2]}
|
|
|
|
case $subcommand in
|
|
l|li|lis|list)
|
|
_nmcli_list "iface bssid"
|
|
return 0
|
|
;;
|
|
c|co|con|conn|conne|connec|connect)
|
|
if [[ "$cur" == -* ]]; then
|
|
_nmcli_list "--private --nowait --timeout"
|
|
else
|
|
if [[ "$prev" == "connect" ]]; then
|
|
_nmcli_list_nl "$(_nmcli_ap_ssid)"
|
|
else
|
|
_nmcli_list "password wep-key-type iface bssid name"
|
|
fi
|
|
fi
|
|
return 0
|
|
;;
|
|
r|re|res|resc|resca|rescan)
|
|
if [[ "$cur" == i* ]]; then
|
|
_nmcli_list "iface"
|
|
else
|
|
_nmcli_list_nl "$(_nmcli_NM_devices)"
|
|
fi
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
_nmcli_list "list connect scan"
|
|
return 0
|
|
;;
|
|
wim|wima|wimax)
|
|
local subcommand=${words[2]}
|
|
|
|
if [[ ${#words[@]} -gt 3 ]]; then
|
|
case $subcommand in
|
|
l|li|lis|list)
|
|
_nmcli_list "iface nsp"
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
_nmcli_list "list"
|
|
return 0
|
|
;;
|
|
|
|
esac
|
|
fi
|
|
|
|
_nmcli_list "status show disconnect wifi wimax help"
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
} &&
|
|
complete -F _nmcli nmcli
|
|
|
|
# ex: ts=4 sw=4 et filetype=sh
|