Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bash] remove duplicates from completions #3156

Merged
merged 9 commits into from
Oct 16, 2023
107 changes: 39 additions & 68 deletions completions/bash/multipass
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,9 @@ _multipass_complete()
local cmd="multipass list --format=csv --no-ipv4"
[ -n "$state" ] && cmd="$cmd | \awk -F',' '\$2 == \"$state\"'"

local instances=$( \eval $cmd | \tail -n +2 | \cut -d',' -f 1 )
local instances=$( \eval $cmd | \tail -n +2 | \cut -d',' -f 1 | \tr '\r\n' ' ')

local found

_get_comp_words_by_ref -n := -w WORDS -i CWORD cur prev
for instance in $instances; do
found=0
for ((i=2; i<CWORD; i++)); do
if [[ "${WORDS[i]}" == ${instance} ]]; then
found=1
break
fi
done
if [ ${found} == 0 ]; then
opts="${opts} ${instance}"
fi
done
_add_nonrepeating_args "$instances"
}

# Set $opts to the list of available networks.
Expand Down Expand Up @@ -70,22 +56,14 @@ _multipass_complete()
{
opts=""

local no_map_found=0
local help_found=0
_add_nonrepeating_args "--no-map-working-directory --help --verbose"

local definition_found=0
local verbose_found=0

for ((i=2; i<COMP_CWORD; ++i)); do
if [[ "${COMP_WORDS[$i]}" == '--no-map-working-directory' ]]; then no_map_found=1; fi
if [[ "${COMP_WORDS[$i]}" == '--help' ]]; then help_found=1; fi
if [[ "${COMP_WORDS[$i]}" == '--verbose' ]]; then verbose_found=1; fi
if [[ "${COMP_WORDS[$i]}" =~ ':' ]]; then definition_found=1; fi
done

if [[ ${no_map_found} == 0 ]]; then opts="${opts} --no-map-working-directory"; fi
if [[ ${help_found} == 0 ]]; then opts="${opts} --help"; fi
if [[ ${verbose_found} == 0 ]]; then opts="${opts} --verbose"; fi

if [[ ${definition_found} == 0 ]] && [[ "${cur}" != ':' ]]; then
_multipass_instances_with_colon
fi
Expand All @@ -99,30 +77,6 @@ _multipass_complete()
multipass_aliases=$( \eval $cmd | \tail -n +2 | \cut -d',' -f 1 )
}

# Set $unused_aliases to the list of aliases from which were not yet specified in the command-line.
_unused_aliases()
{
_multipass_aliases

local alias_found=0

unused_aliases=""

for j in $multipass_aliases; do
alias_found=0

for ((i=2; i<COMP_CWORD; ++i)); do
if [[ "${COMP_WORDS[$i]}" == "$j" ]]; then
alias_found=1
fi
done

if [[ ${alias_found} == 0 ]]; then
unused_aliases="${unused_aliases} $j"
fi
done
}

# Removes the comma or equals sign at the end of $cur.
_remove_trailing_char()
{
Expand Down Expand Up @@ -192,6 +146,26 @@ _multipass_complete()
if [[ ${mode_found} == 0 ]]; then opts="${opts} mode="; fi
}

# Adds the passed list to the opts array while filtering out duplicates
_add_nonrepeating_args()
{
local array=$1
local found

for item in $array; do
found=0
for ((i=2; i<CWORD; i++)); do
if [[ "${WORDS[i]}" == ${item} ]]; then
found=1
break
fi
done
if [ ${found} == 0 ]; then
opts="${opts} ${item}"
fi
done
}

# Add comma and equals sign to the list of word separators if they are not already there, useful to separate
# options of the form "opt1=val1,opt2=val2".
if [[ ! "${COMP_WORDBREAKS}" =~ "," ]]; then
Expand All @@ -202,6 +176,7 @@ _multipass_complete()
fi

local cur cmd opts prev prev2 prev_opts multipass_aliases unused_aliases
_get_comp_words_by_ref -n := -w WORDS -i CWORD cur prev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
Expand All @@ -216,49 +191,45 @@ _multipass_complete()

if [[ "${multipass_cmds}" =~ " ${cmd} " || "${multipass_cmds}" =~ ^${cmd} || "${multipass_cmds}" =~ \ ${cmd}$ ]];
then
opts="--help --verbose"
_add_nonrepeating_args "--help"
opts="${opts} --verbose"
fi

case "${cmd}" in
"exec")
opts="${opts} --working-directory --no-map-working-directory"
;;
"info")
opts="${opts} --all --format"
_add_nonrepeating_args "--all --format"
;;
"list"|"ls")
opts="${opts} --format"
;;
"networks")
opts="${opts} --format"
"list"|"ls"|"networks"|"aliases")
_add_nonrepeating_args "--format"
;;
"delete")
opts="${opts} --all --purge"
_add_nonrepeating_args "--all --purge"
;;
"launch")
opts="${opts} --cpus --disk --memory --name --cloud-init --network --bridged --mount"
_add_nonrepeating_args "--cpus --disk --memory --name --cloud-init --bridged --mount"
opts="${opts} --network --mount"
;;
"mount")
opts="${opts} --gid-map --uid-map"
;;
"recover"|"start"|"suspend"|"restart")
opts="${opts} --all"
_add_nonrepeating_args "--all"
;;
"stop")
opts="${opts} --all --cancel --time"
_add_nonrepeating_args "--all --cancel --time"
;;
"find")
opts="${opts} --show-unsupported --force-update --format"
;;
"aliases")
opts="${opts} --format"
_add_nonrepeating_args "--show-unsupported --force-update --format"
;;
"unalias")
_unused_aliases
opts="${opts} ${unused_aliases}"
_multipass_aliases
_add_nonrepeating_args $multipass_aliases
;;
"transfer"|"copy-files")
opts="${opts} --parents --recursive"
_add_nonrepeating_args "--parents --recursive"
;;
esac

Expand Down