summaryrefslogtreecommitdiffstats
path: root/bash_completion/repo.bash
diff options
context:
space:
mode:
authorChirayu Desai <cdesai@cyanogenmod.org>2013-04-10 21:11:02 +0530
committerChirayu Desai <cdesai@cyanogenmod.org>2013-04-10 21:13:40 +0530
commitd308210b0fe51f1bfa5a4753ab9cf461777cac47 (patch)
tree1aed9e35fc44c6e03cf2241b2abad25de6818b75 /bash_completion/repo.bash
parent7a7185b04454f6517dc6ac7c90332ffee328ec38 (diff)
downloadvendor_replicant-d308210b0fe51f1bfa5a4753ab9cf461777cac47.zip
vendor_replicant-d308210b0fe51f1bfa5a4753ab9cf461777cac47.tar.gz
vendor_replicant-d308210b0fe51f1bfa5a4753ab9cf461777cac47.tar.bz2
repo.bash: replace with better version
From https://raw.github.com/aartamonau/repo.bash_completion/master/repo.bash_completion Change-Id: I7ca5d7eba70244d875c48ce76c999c8a10b88934
Diffstat (limited to 'bash_completion/repo.bash')
-rw-r--r--bash_completion/repo.bash723
1 files changed, 639 insertions, 84 deletions
diff --git a/bash_completion/repo.bash b/bash_completion/repo.bash
index e556d33..3b1d510 100644
--- a/bash_completion/repo.bash
+++ b/bash_completion/repo.bash
@@ -1,99 +1,654 @@
-# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the repo-LICENSE file.
+# -*- mode: sh; -*-
-# Programmable completion for some Chromium OS build scripts.
+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
+)
-_list_repo_commands() {
- local repo=${COMP_WORDS[0]}
- "${repo}" help --all | grep -E '^ ' | sed 's/ \([^ ]\+\) .\+/\1/'
+# 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 [ -f "${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
}
-_list_repo_branches() {
- local repo=${COMP_WORDS[0]}
- "${repo}" branches 2>&1 | grep \| | sed 's/[ *][Pp ] *\([^ ]\+\) .*/\1/'
+_path_cmd_completion() {
+ _gen_comps "$(compgen -c ${cur})"
}
-_list_repo_projects() {
- local repo=${COMP_WORDS[0]}
- local manifest=$(mktemp)
- "${repo}" manifest -o "${manifest}" >& /dev/null
- grep 'project name=' "${manifest}" | sed 's/.\+name="\([^"]\+\)".\+/\1/'
- rm -f "${manifest}" >& /dev/null
+_is_option() {
+ local opt="$1"
+
+ [[ "${opt}" == -* ]]
}
-# Complete the repo <command> argument.
-_complete_repo_command() {
- [ ${COMP_CWORD} -eq 1 ] || return 1
- local command=${COMP_WORDS[1]}
- COMPREPLY=($(compgen -W "$(_list_repo_commands)" -- "${command}"))
- return 0
+_is_long_option() {
+ local opt="$1"
+
+ [[ "${opt}" == --* ]]
}
-_complete_repo_arg() {
- [ ${COMP_CWORD} -gt 1 ] || return 1
- local command=${COMP_WORDS[1]}
- local current=${COMP_WORDS[COMP_CWORD]}
- if [[ ${command} == "abandon" ]]; then
- if [[ ${COMP_CWORD} -eq 2 ]]; then
- COMPREPLY=($(compgen -W "$(_list_repo_branches)" -- "${current}"))
+_expects_arg() {
+ local opt="$1"
+
+ if [[ ${ARG_OPTIONS[$opt]} ]]
+ then
+ return 0
else
- COMPREPLY=($(compgen -W "$(_list_repo_projects)" -- "${current}"))
+ 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
- fi
- if [[ ${command} == "help" ]]; then
- [ ${COMP_CWORD} -eq 2 ] && \
- COMPREPLY=($(compgen -W "$(_list_repo_commands)" -- "${current}"))
+}
+
+_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
- fi
- if [[ ${command} == "start" ]]; then
- [ ${COMP_CWORD} -gt 2 ] && \
- COMPREPLY=($(compgen -W "$(_list_repo_projects)" -- "${current}"))
+}
+
+_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"
+ "-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
- fi
- return 1
-}
-
-# Complete the repo arguments.
-_complete_repo() {
- COMPREPLY=()
- _complete_repo_command && return 0
- _complete_repo_arg && return 0
- return 0
-}
-
-complete -F _complete_repo repo
-
-# Add a way to get the "m" branch from repo easily; used by __git_branch_ps1()
-#
-# Repo seems to maintain a phony 'm/' remote and it always seems to be the name
-# of the manifest branch. This will retrieve it.
-__git_m_branch() {
- local git_dir=$(git rev-parse --git-dir 2> /dev/null)
- if [ -n "${git_dir}" ]; then
- echo $(cd ${git_dir}/refs/remotes/m 2> /dev/null && ls)
- fi
-}
-
-# A "subclass" of __git_ps1 that adds the manifest branch name into the prompt.
-# ...if you're on manifest branch "0.11.257.B" and local branch "lo" and
-# pass " (%s)", we'll output " (0.11.257.B/lo)". Note that we'll never show
-# the manifest branch 'master', since it's so common.
-__git_branch_ps1() {
- local format_str="${1:- (%s)}"
- local m_branch=$(__git_m_branch)
- if [ "${m_branch}" != "master" -a -n "${m_branch}" ]; then
- format_str=$(printf "${format_str}" "${m_branch}/%s")
- fi
- # for subshells, prefix the prompt with the shell nesting level
- local lshlvl=""
- [ ! -z "${SHLVL##*[!0-9]*}" ] && [ ${SHLVL} -gt 1 ] && lshlvl="${SHLVL} "
- __git_ps1 "${lshlvl}${format_str}"
-}
-
-# Prompt functions should not error when in subshells
-export -f __gitdir
-export -f __git_ps1
-export -f __git_m_branch
-export -f __git_branch_ps1
+}
+
+complete -o nospace -F _repo repo