mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 00:15:32 +00:00
129 lines
No EOL
4.4 KiB
Bash
Executable file
129 lines
No EOL
4.4 KiB
Bash
Executable file
# As this script must be sourced by shells to be useful, no practical #shebang is possible.
|
|
|
|
# Note: must 'source' this file again in the terminal after any edits!
|
|
_comp_builder() {
|
|
# Does the file actually exist? If not, abort.
|
|
local CMD_PATH=`readlink -f "$1"`
|
|
if [ -z "${CMD_PATH}" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Detect - is this a keyman repo? If not, exit early; we don't expect repo-external compatibility.
|
|
local CMD_DIR="$(dirname "${CMD_PATH}")"
|
|
cd "${CMD_DIR}"
|
|
# Works correctly even if the directory has no backing repository.
|
|
git remote get-url origin | grep -q 'github.com/keymanapp' || exit 0
|
|
|
|
# Some of the configuration differs when ZSH is the OS's primary terminal; this flag
|
|
# may be used to tailor this function accordingly.
|
|
local IS_ZSH=false
|
|
if [ "${SHELL##*/}" = "zsh" ]; then
|
|
IS_ZSH=true
|
|
fi
|
|
|
|
# Warning - zsh uses -A, not -a, for array-read operations!
|
|
# This is 'sourced' by the shell profile script, so macOS zsh terminal
|
|
# usage must be aware of this and adapt.
|
|
local READ_ARRAY="-a"
|
|
if [ $IS_ZSH = true ]; then
|
|
READ_ARRAY="-A"
|
|
fi
|
|
|
|
# Is it actually a builder-script? If not, abort. If so, it defines
|
|
# a special option used to provide us with completion-target data.
|
|
local builder_params=`${CMD_PATH} --builder-completion-describe` || exit 0
|
|
|
|
local BASE_NAME=$(basename "$CMD_PATH")
|
|
local BUILDER_ARG_STR="${COMP_LINE##*${BASE_NAME} }"
|
|
|
|
local builder_args
|
|
# Does not actually preserve an empty token at the end.
|
|
read -r $READ_ARRAY builder_args <<< "${BUILDER_ARG_STR}"
|
|
|
|
# Determine the current token (given the caret position) and
|
|
# all existing, already-completed actions, targets, and options
|
|
# for the script before the current token.
|
|
local current_token=
|
|
# If the caret is adjacent to non-whitespace - thus is editing
|
|
# a builder argument...
|
|
if [ ! -z "${COMP_WORDS[COMP_CWORD]}" ]; then
|
|
# Then note the last token as the token being edited...
|
|
current_token="${builder_args[-1]}"
|
|
# ... and thus not pre-completed.
|
|
unset builder_args[-1]
|
|
fi
|
|
|
|
# Parse the builder-description for completion target data.
|
|
local action_str target_str option_str
|
|
IFS=";" read -r action_str target_str option_str <<< "$builder_params"
|
|
local actions targets options
|
|
IFS=" " read -r $READ_ARRAY actions <<< "$action_str"
|
|
IFS=" " read -r $READ_ARRAY targets <<< "$target_str"
|
|
IFS=" " read -r $READ_ARRAY options <<< "$option_str"
|
|
|
|
local action target
|
|
if [[ $current_token =~ : ]]; then
|
|
IFS=: read -r action target <<< "$current_token"
|
|
target=:$target
|
|
else
|
|
action="$current_token"
|
|
target=
|
|
fi
|
|
|
|
local all=()
|
|
# If there is no $action component, it's a standalone target.
|
|
|
|
if [[ -z "$action" ]] && [[ -z "$target" ]]; then
|
|
all+="${actions[@]}"
|
|
all+=" ${targets[@]}"
|
|
all+=" ${options[@]}"
|
|
|
|
COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )
|
|
elif [[ -z "$action" ]]; then
|
|
# It's an unpaired target.
|
|
all="${targets[@]}"
|
|
COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )
|
|
|
|
if [ $IS_ZSH == false ]; then
|
|
# bash doesn't handle completion with colons well; we should remove the
|
|
# colon prefix from each entry. ZSH actually doesn't have this issue.
|
|
local i
|
|
for (( i=0; i<${#COMPREPLY[@]}; i++ )); do
|
|
COMPREPLY[$i]="${COMPREPLY[$i]##*:}"
|
|
done
|
|
fi
|
|
elif [[ -z "$target" ]]; then
|
|
# It's an untargeted action or an option.
|
|
all+="${actions[@]}"
|
|
all+=" ${options[@]}"
|
|
|
|
COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )
|
|
else
|
|
# Ah, an action-target pair. We have an existing action, so we only need to
|
|
# complete the target part.
|
|
|
|
# First, build up the list of legal paired tokens.
|
|
local actiontargets=()
|
|
for e in "${targets[@]}"; do
|
|
actiontargets+=("${action}${e}")
|
|
done
|
|
|
|
# Now, complete from that.
|
|
all+="${actiontargets[@]}"
|
|
COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )
|
|
|
|
if [ $IS_ZSH == false ]; then
|
|
# bash doesn't handle completion with colons well; we should remove the
|
|
# colon prefix from each entry. ZSH actually doesn't have this issue.
|
|
local i
|
|
for (( i=0; i<${#COMPREPLY[@]}; i++ )); do
|
|
COMPREPLY[$i]="${COMPREPLY[$i]##*:}"
|
|
done
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# When this script is sourced by .bashrc or similar, this provides autocompletion for
|
|
# builder scripts named build.sh and test.sh.
|
|
complete -o bashdefault -F _comp_builder build.sh
|
|
complete -o bashdefault -F _comp_builder test.sh |