bash-it/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bash

287 lines
7.6 KiB
Bash

# shellcheck shell=bash
# shellcheck disable=SC2207
#
# Bash command line completion for defaults
#
# Version 1.0 created by Jonathon Mah on 2006-11-08.
# Version 2.0 written by John Pell on 2021-09-11.
#
function matchpattern()
{
local PATTERN=${2:?$FUNCNAME: a pattern is required}
local SEP=${3:-|}
[[ -z "${PATTERN##*${SEP}${1}${SEP}*}" ]]
}
function _defaults_verbs()
{
local IFS=$'\n' # Treat only newlines as delimiters in string operations.
local LC_CTYPE='C' # Do not consider character set in string operations.
local LC_COLLATE='C' # Do not consider character set in pattern matching.
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD - 1]}"
COMPREPLY=()
case $COMP_CWORD in
1)
candidates=("${cmds// /$IFS}" "${host_opts[@]}")
;;
2 | 3)
candidates=("${cmds// /$IFS}")
;;
*)
return 1
;;
esac
COMPREPLY=($(compgen -W "${candidates[*]}" | grep -i "^${cur}"))
return 0
}
function _defaults_domains()
{
local IFS=$'\n' # Treat only newlines as delimiters in string operations.
local LC_CTYPE='C' # Do not consider character set in string operations.
local LC_COLLATE='C' # Do not consider character set in pattern matching.
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD - 1]}"
COMPREPLY=()
if [[ "$BASH_VERSINFO" -ge 4 ]]
then # Exponential performance issue on strings greater than about 10k.
local domains="$(defaults domains)"
local candidates=($(compgen -W "${domains//, /$IFS}" | grep -i "^${cur}"))
else
local domains="$(defaults domains | sed -e 's/, /^/g' | tr '^' '\n')"
local candidates=($(compgen -W "${domains}" | grep -i "^${cur}"))
fi
COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
if grep -q "^$cur" <<< '-app'
then
COMPREPLY[${#COMPREPLY[@]}]="-app"
elif grep -q "^$cur" <<< '-g'
then
COMPREPLY[${#COMPREPLY[@]}]="-g"
fi
return 0
}
function _defaults()
{
local IFS=$'\n' # Treat only newlines as delimiters in string operations.
local LC_CTYPE='C' # Do not consider character set in string operations.
local LC_COLLATE='C' # Do not consider character set in pattern matching.
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD - 1]}"
COMPREPLY=()
local host_opts cmds cmd domain keys key_index candidates verbs value_types
host_opts=('-currentHost' '-host')
cmds=' delete domains export find help import read read-type rename write '
value_types=('-string' '-data' '-integer' '-float' '-boolean' '-date' '-array' '-array-add' '-dict' '-dict-add')
case $COMP_CWORD in
1)
_defaults_verbs
return "$?"
;;
2)
case $prev in
"-currentHost")
_defaults_verbs
;;
"-host")
_known_hosts -a
;;
*)
if matchpattern "$prev" "${cmds// /|}"
then
# TODO: not correct for verbs: domains, find, help
_defaults_domains
else
return 1 # verb is not recognized
fi
;;
esac
return "$?"
;;
3)
case ${COMP_WORDS[1]} in
"-currentHost")
_defaults_domains
return "$?"
;;
"-host")
_defaults_verbs
return "$?"
;;
esac
;;
4)
case ${COMP_WORDS[1]} in
"-host")
if matchpattern "$prev" "${cmds// /|}"
then
# TODO: not correct for verbs: domains, find, help
_defaults_domains
else
return 1 # verb is not recognized
fi
;;
esac
;;
esac
# Both a domain and command have been specified
case ${COMP_WORDS[1]} in
"-currentHost")
if matchpattern "${COMP_WORDS[2]}" "${cmds// /|}"
then
cmd="${COMP_WORDS[2]}"
domain="${COMP_WORDS[3]}"
key_index=4
if [[ "$domain" == "-app" ]]
then
if [[ $COMP_CWORD -eq 4 ]]
then
# Completing application name. Can't help here, sorry
return 0
fi
domain="-app ${COMP_WORDS[4]}"
key_index=5
fi
fi
;;
"-host")
if matchpattern "${COMP_WORDS[3]}" "${cmds// /|}"
then
cmd="${COMP_WORDS[3]}"
domain="${COMP_WORDS[4]}"
key_index=5
if [[ "$domain" == "-app" ]]
then
if [[ $COMP_CWORD -eq 5 ]]
then
# Completing application name. Can't help here, sorry
return 0
fi
domain="-app ${COMP_WORDS[5]}"
key_index=6
fi
fi
;;
*)
if matchpattern "${COMP_WORDS[1]}" "${cmds// /|}"
then
cmd="${COMP_WORDS[1]}"
domain="${COMP_WORDS[2]}"
key_index=3
if [[ "$domain" == "-app" ]]
then
if [[ $COMP_CWORD -eq 3 ]]
then
# Completing application name. Can't help here, sorry
return 0
fi
domain="-app ${COMP_WORDS[3]}"
key_index=4
fi
fi
;;
esac
keys=($(defaults read "$domain" 2> /dev/null | sed -n -e '/^ [^}) ]/p' | sed -e 's/^ \([^" ]\{1,\}\) = .*$/\1/g' -e 's/^ "\([^"]\{1,\}\)" = .*$/\1/g'))
case $cmd in
read | read-type)
# Complete key
if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
then
COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
fi
;;
write)
if [[ $key_index -eq $COMP_CWORD ]]
then
# Complete key
if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
then
COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
fi
elif [[ $((key_index + 1)) -eq $COMP_CWORD ]]
then
# Complete value type
local cur_type="$(defaults read-type "$domain" "${COMP_WORDS[key_index]}" 2> /dev/null | sed -e 's/^Type is \(.*\)/-\1/' -e's/dictionary/dict/' | grep "^$cur")"
if [[ $cur_type ]]
then
COMPREPLY=("$cur_type")
else
COMPREPLY=($(compgen -W "${value_types[*]}" -- "$cur"))
fi
elif [[ $((key_index + 2)) -eq $COMP_CWORD ]]
then
# Complete value
COMPREPLY=($(defaults read "$domain" "${COMP_WORDS[key_index]}" 2> /dev/null | grep -i "^${cur//\\/\\\\}"))
fi
;;
rename)
if [[ $key_index -eq $COMP_CWORD || $((key_index + 1)) -eq $COMP_CWORD ]]
then
# Complete source and destination keys
if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
then
COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
fi
fi
;;
delete)
if [[ $key_index -eq $COMP_CWORD ]]
then
# Complete key
if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
then
COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
fi
fi
;;
esac
return 0
}
complete -F _defaults -o default defaults
# This file is licensed under the BSD license, as follows:
#
# Copyright (c) 2006, Playhaus
# Copyright (c) 2021, gaelicWizard.LLC
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the names of the authors nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# This software is provided by the copyright holders and contributors "as is"
# and any express or implied warranties, including, but not limited to, the
# implied warranties of merchantability and fitness for a particular purpose are
# disclaimed. In no event shall the copyright owner or contributors be liable
# for any direct, indirect, incidental, special, exemplary, or consequential
# damages (including, but not limited to, procurement of substitute goods or
# services; loss of use, data, or profits; or business interruption) however
# caused and on any theory of liability, whether in contract, strict liability,
# or tort (including negligence or otherwise) arising in any way out of the use
# of this software, even if advised of the possibility of such damage.