Skip to content

Commit

Permalink
Merge pull request #3156 from canonical/filter-duplicate-bash-args
Browse files Browse the repository at this point in the history
3156: [bash] remove duplicates from completions r=ricab a=sharder996

Bash completions will currently suggest repeated flags endlessly. This PR filters out previously seen options/flags with the assumption that no multipass currently accepts this pattern.

Co-authored-by: sharder996 <[email protected]>
  • Loading branch information
ricab and sharder996 authored Oct 16, 2023
2 parents e04b12e + d49b6c6 commit 24ca05e
Showing 1 changed file with 40 additions and 69 deletions.
109 changes: 40 additions & 69 deletions completions/bash/multipass
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,11 @@ _multipass_complete()
local state=$1

local cmd="multipass list --format=csv --no-ipv4"
[ -n "$state" ] && cmd="$cmd | \awk -F',' '\$2 == \"$state\"'"
[ -n "$state" ] && cmd="$cmd | \tail -n +2 | \awk -F',' '\$2 == \"$state\"'"

local instances=$( \eval $cmd | \tail -n +2 | \cut -d',' -f 1 )
local instances=$( \eval $cmd | \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

0 comments on commit 24ca05e

Please sign in to comment.