replicant-vendor_replicant/bash_completion/repo.bash

656 lines
11 KiB
Bash

# -*- mode: sh; -*-
declare -A CMD_HANDLERS
CMD_HANDLERS=(
["init"]=_repo_init
["help"]=_repo_help
["abandon"]=_repo_abandon
["branch"]=_repo_branch
["branches"]=_repo_branches
["checkout"]=_repo_checkout
["cherry-pick"]=_repo_cherry_pick
["diff"]=_repo_diff
["download"]=_repo_download
["forall"]=_repo_forall
["grep"]=_repo_grep
["list"]=_repo_list
["prune"]=_repo_prune
["rebase"]=_repo_rebase
["selfupdate"]=_repo_selfupdate
["smartsync"]=_repo_smartsync
["stage"]=_repo_stage
["start"]=_repo_start
["status"]=_repo_status
["sync"]=_repo_sync
["upload"]=_repo_upload
["version"]=_repo_version
)
# To be populated by command handlers.
declare -a OPTIONS
declare -A ARG_OPTIONS
declare cur
declare prev
_init_cur_prev() {
cur=$(_get_cword "=")
prev=$(_get_cword "=" 1)
_split_longopt
}
_find_repo() {
local dir=$(pwd)
local found=1
while [ "${dir}" != / ]
do
if [ -e "${dir}/.repo/repo/main.py" ]
then
found=0
break
fi
dir=$(cd "${dir}/.." && pwd)
done
if [ ${found} -eq 0 ]
then
echo "${dir}"
fi
}
_is_repo_dir() {
local repo_root=$(_find_repo)
[ -n "${repo_root}" ]
}
_gen_comps() {
local completions="$1"
local suffix="${2:- }"
local -i i
local -a tmp=( $(compgen -W "${completions}" -- ${cur}) )
for (( i=0; i < ${#tmp[*]}; i++ ))
do
tmp[$i]="${tmp[$i]}${suffix}"
done
COMPREPLY=(
"${COMPREPLY[@]}"
"${tmp[@]}"
)
}
_strip_colors () {
# taken from http://goo.gl/7KlLZ
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
}
_no_completion() {
true
}
_command_completion() {
local cmds
if _is_repo_dir
then
cmds=("abandon" "branch" "branches" "checkout" "cherry-pick" "diff"
"download" "forall" "grep" "help" "init" "list" "prune" "rebase"
"selfupdate" "smartsync" "stage" "start" "status" "sync"
"upload" "version")
else
cmds=("help" "init")
fi
_gen_comps "${cmds[*]}"
}
_branch_completion() {
local raw_branches
# separate statement required to be able to access exit code
raw_branches=$(repo branches 2>/dev/null)
if [ $? -eq 0 ]
then
local branches=$(
echo "${raw_branches}" |
_strip_colors | awk 'BEGIN { FS="|" } { print $1 }' | cut -c 3-
)
_gen_comps "${branches}"
fi
}
_dir_completion() {
_filedir -d
}
_project_completion() {
local repo_root=$(_find_repo)
if [ -n "${repo_root}" -a -f "${repo_root}/.repo/project.list" ]
then
local projects=$(cat "${repo_root}/.repo/project.list")
_gen_comps "${projects}"
fi
}
_manifest_completion() {
local repo_root=$(_find_repo)
if [ -n "${repo_root}" ]
then
local manifests_dir="${repo_root}/.repo/manifests"
local git_dir="${manifests_dir}/.git"
local candidates
manifests=$(
git --git-dir "${git_dir}" ls-files "*.xml" 2>/dev/null)
if [ $? -eq 0 ]
then
_gen_comps "${manifests}"
fi
fi
}
_path_cmd_completion() {
_gen_comps "$(compgen -c ${cur})"
}
_is_option() {
local opt="$1"
[[ "${opt}" == -* ]]
}
_is_long_option() {
local opt="$1"
[[ "${opt}" == --* ]]
}
_expects_arg() {
local opt="$1"
if [[ ${ARG_OPTIONS[$opt]} ]]
then
return 0
else
return 1
fi
}
_handle_options() {
if _expects_arg "${prev}"
then
local handler=${ARG_OPTIONS[$prev]}
eval ${handler} "${cur}"
elif _is_option "${cur}"
then
_gen_comps "${OPTIONS[*]}"
local arg_short
local arg_long
for opt in "${!ARG_OPTIONS[@]}"
do
if _is_long_option "${opt}"
then
arg_long="${arg_long} ${opt}"
else
arg_short="${arg_short} ${opt}"
fi
done
_gen_comps "${arg_short}"
_gen_comps "${arg_long}" "="
else
return 1
fi
return 0
}
_is_known_shortopt() {
local needle="$1"
for opt in ${OPTIONS[@]}
do
if [ "${opt}" = "${needle}" ]
then
return 0
fi
done
return 1
}
_is_known_longopt() {
local needle="$1"
[[ ${ARG_OPTIONS[$1]} ]]
}
_arg_index() {
local -i i=2 # skip repo and command
local -i ix=0
while [ ${i} -lt ${COMP_CWORD} ]
do
if _is_known_shortopt "${COMP_WORDS[i]}"
then
i+=1
elif _is_known_longopt "${COMP_WORDS[i]}"
then
i+=2
elif _is_option "${COMP_WORDS[i]}"
then
i+=1
else
i+=1
ix+=1
fi
done
eval $1="${ix}"
}
_when_ix() {
local ix="$1"
local completion="$2"
_arg_index arg_ix
if [ ${arg_ix} -eq ${ix} ]
then
${completion}
return 0
else
return 1
fi
}
_when_first() {
_when_ix 0 "$1"
}
_when_even() {
local completion="$1"
_arg_index arg_ix
if [ $(( ${arg_ix} % 2 )) -eq 0 ]
then
${completion}
return 0
else
return 1
fi
}
_cmp_opts() {
local opt="$1"
local word="$2"
if _is_option "${opt}" && ! _is_long_option "${opt}"
then
[ "${word}" == "${opt}" ]
else
[[ "${word}" == "${opt}"=* || "${word}" == "${opt}" ]]
fi
}
_before() {
local completion="$1"
local words
shift
_get_comp_words_by_ref -n = words
for word in "${words[@]}"
do
for needle in "$@"
do
if _cmp_opts "${needle}" "${word}"
then
return 1
fi
done
done
${completion}
return 0
}
_repo_init() {
OPTIONS=(
"-h" "--help"
"-q" "--quite"
"--mirror"
"--no-repo-verify"
)
ARG_OPTIONS=(
["-u"]=_no_completion
["--manifest-url"]=_no_completion
["-b"]=_no_completion
["--manifest-branch"]=_no_completion
["-m"]=_manifest_completion
["--manifest-name"]=_manifest_completion
["--reference"]=_dir_completion
["--repo-url"]=_no_completion
["--repo-branch"]=_no_completion
)
_handle_options
}
_repo_help() {
OPTIONS=(
"-a" "--all"
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options || _when_first _command_completion
}
_repo_abandon() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options || _when_first _branch_completion || _project_completion
}
_repo_branch() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options
}
_repo_branches() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options
}
_repo_checkout() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options || _when_first _branch_completion || _project_completion
}
_repo_cherry_pick() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options
}
_repo_diff() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options || _project_completion
}
_repo_download() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options || _when_even _project_completion
}
_repo_forall() {
OPTIONS=(
"-h" "--help"
"-p"
"-v" "--verbose"
)
ARG_OPTIONS=(
["-c"]=_path_cmd_completion
["--command"]=_path_cmd_completion
)
_handle_options || _before _project_completion -c --command || _filedir
}
_repo_grep() {
OPTIONS=(
"-h" "--help"
"--cached"
"-r" "--revision"
"-i" "--ignore-case"
"-a" "--text"
"-I"
"-w" "--word-regexp"
"-v" "--invert-match"
"-G" "--basic-regexp"
"-E" "--extended-regexp"
"-F" "--fixed-strings"
"--all-match"
"--and" "--or" "--not"
"-(" "-)"
"-n"
"-l" "--name-only" "--files-with-matches"
"-L" "--files-without-match"
)
ARG_OPTIONS=(
["-e"]=_no_completion
["-C"]=_no_completion
["-B"]=_no_completion
["-A"]=_no_completion
)
_handle_options || _project_completion
}
_repo_list() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options || _project_completion
}
_repo_prune() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options || _project_completion
}
_repo_rebase() {
OPTIONS=(
"-h" "--help"
"-i" "--interactive"
"-f" "--force-rebase"
"--no-ff"
"-q" "--quiet"
"--autosquash"
)
ARG_OPTIONS=(
["--whitespace"]=_no_completion
)
_handle_options || _project_completion
}
_repo_selfupdate() {
OPTIONS=(
"-h" "--help"
"--no-repo-verify"
)
ARG_OPTIONS=()
_handle_options
}
_repo_smartsync() {
OPTIONS=(
"-h" "--help"
"-f" "--force-broken"
"-l" "--local-only"
"-n" "--network-only"
"-d" "--detach"
"-q" "--quiet"
"--no-repo-verify"
)
ARG_OPTIONS=(
["-j"]=_no_completion
["--jobs"]=_no_completion
)
_handle_options || _project_completion
}
_repo_stage() {
OPTIONS=(
"-h" "--help"
"-i" "--interactive"
)
ARG_OPTIONS=()
_handle_options || _project_completion
}
_repo_start() {
OPTIONS=(
"-h" "--help"
"--all"
)
ARG_OPTIONS=()
_handle_options || _when_first _branch_completion || _project_completion
}
_repo_status() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=(
["-j"]=_no_completion
["--jobs"]=_no_completion
)
_handle_options || _project_completion
}
_repo_sync() {
OPTIONS=(
"-h" "--help"
"-f" "--force-broken"
"--force-sync"
"-l" "--local-only"
"-n" "--network-only"
"-d" "--detach"
"-q" "--quiet"
"-s" "--smart-sync"
"--no-repo-verify"
)
ARG_OPTIONS=(
["-j"]=_no_completion
["--jobs"]=_no_completion
)
_handle_options || _project_completion
}
_repo_upload() {
OPTIONS=(
"-h" "--help"
"-t"
"--no-verify"
"--verify"
)
ARG_OPTIONS=(
["--re"]=_no_completion
["--reviewers"]=_no_completion
["--cc"]=_no_completion
["--br"]=_branch_completion
)
_handle_options || _project_completion
}
_repo_version() {
OPTIONS=(
"-h" "--help"
)
ARG_OPTIONS=()
_handle_options
}
_repo() {
COMPREPLY=()
_init_cur_prev
if [ ${COMP_CWORD} -eq 1 ]
then
_command_completion
else
local cmd=${COMP_WORDS[1]}
local handler=${CMD_HANDLERS["${cmd}"]}
if [ -n ${handler} ]
then
eval ${handler}
fi
fi
return 0
}
complete -o nospace -F _repo repo