| command -v cargo >/dev/null 2>&1 && |
| _cargo() |
| { |
| local cur prev words cword |
| _get_comp_words_by_ref cur prev words cword |
| |
| COMPREPLY=() |
| |
| # Skip past - and + options to find the command. |
| local nwords=${#words[@]} |
| local cmd_i cmd |
| for (( cmd_i=1; cmd_i<$nwords; cmd_i++ )); |
| do |
| if [[ ! "${words[$cmd_i]}" =~ ^[+-] ]]; then |
| cmd="${words[$cmd_i]}" |
| break |
| fi |
| done |
| |
| local vcs='git hg none' |
| local color='auto always never' |
| local msg_format='human json' |
| |
| local opt_help='-h --help' |
| local opt_verbose='-v --verbose' |
| local opt_quiet='-q --quiet' |
| local opt_color='--color' |
| local opt_common="$opt_help $opt_verbose $opt_quiet $opt_color" |
| local opt_pkg='-p --package' |
| local opt_feat='--features --all-features --no-default-features' |
| local opt_mani='--manifest-path' |
| local opt_jobs='-j --jobs' |
| local opt_force='-f --force' |
| local opt_test='--test --bench' |
| local opt_lock='--frozen --locked' |
| |
| local opt___nocmd="$opt_common -V --version --list" |
| local opt__bench="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --no-run" |
| local opt__build="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --release" |
| local opt__check="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --release" |
| local opt__clean="$opt_common $opt_pkg $opt_mani $opt_lock --target --release" |
| local opt__doc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs --message-format --bin --lib --target --open --no-deps --release" |
| local opt__fetch="$opt_common $opt_mani $opt_lock" |
| local opt__generate_lockfile="${opt__fetch}" |
| local opt__git_checkout="$opt_common $opt_lock --reference --url" |
| local opt__help="$opt_help" |
| local opt__init="$opt_common $opt_lock --bin --lib --name --vcs" |
| local opt__install="$opt_common $opt_feat $opt_jobs $opt_lock $opt_force --bin --branch --debug --example --git --list --path --rev --root --tag --vers" |
| local opt__locate_project="$opt_mani -h --help" |
| local opt__login="$opt_common $opt_lock --host" |
| local opt__metadata="$opt_common $opt_feat $opt_mani $opt_lock --format-version --no-deps" |
| local opt__new="$opt_common $opt_lock --vcs --bin --lib --name" |
| local opt__owner="$opt_common $opt_lock -a --add -r --remove -l --list --index --token" |
| local opt__package="$opt_common $opt_mani $opt_lock $opt_jobs --allow-dirty -l --list --no-verify --no-metadata" |
| local opt__pkgid="${opt__fetch} $opt_pkg" |
| local opt__publish="$opt_common $opt_mani $opt_lock $opt_jobs --allow-dirty --dry-run --host --token --no-verify" |
| local opt__read_manifest="$opt_help $opt_verbose $opt_mani $opt_color --no-deps" |
| local opt__run="$opt_common $opt_feat $opt_mani $opt_lock $opt_jobs --message-format --target --bin --example --release" |
| local opt__rustc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --profile --target --lib --bin --example --release" |
| local opt__rustdoc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --release --open" |
| local opt__search="$opt_common $opt_lock --host --limit" |
| local opt__test="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --all --doc --target --lib --bin --example --no-run --release --no-fail-fast" |
| local opt__uninstall="$opt_common $opt_lock --bin --root" |
| local opt__update="$opt_common $opt_pkg $opt_mani $opt_lock --aggressive --precise" |
| local opt__verify_project="${opt__fetch}" |
| local opt__version="$opt_help $opt_verbose $opt_color" |
| local opt__yank="$opt_common $opt_lock --vers --undo --index --token" |
| |
| if [[ $cmd_i -ge $nwords-1 ]]; then |
| # Completion before or at the command. |
| if [[ "$cur" == -* ]]; then |
| COMPREPLY=( $( compgen -W "${opt___nocmd}" -- "$cur" ) ) |
| elif [[ "$cur" == +* ]]; then |
| COMPREPLY=( $( compgen -W "$(_toolchains)" -- "$cur" ) ) |
| else |
| COMPREPLY=( $( compgen -W "$__cargo_commands" -- "$cur" ) ) |
| fi |
| else |
| case "${prev}" in |
| --vcs) |
| COMPREPLY=( $( compgen -W "$vcs" -- "$cur" ) ) |
| ;; |
| --color) |
| COMPREPLY=( $( compgen -W "$color" -- "$cur" ) ) |
| ;; |
| --message-format) |
| COMPREPLY=( $( compgen -W "$msg_format" -- "$cur" ) ) |
| ;; |
| --manifest-path) |
| _filedir toml |
| ;; |
| --bin) |
| COMPREPLY=( $( compgen -W "$(_bin_names)" -- "$cur" ) ) |
| ;; |
| --test) |
| COMPREPLY=( $( compgen -W "$(_test_names)" -- "$cur" ) ) |
| ;; |
| --bench) |
| COMPREPLY=( $( compgen -W "$(_benchmark_names)" -- "$cur" ) ) |
| ;; |
| --example) |
| COMPREPLY=( $( compgen -W "$(_get_examples)" -- "$cur" ) ) |
| ;; |
| --target) |
| COMPREPLY=( $( compgen -W "$(_get_targets)" -- "$cur" ) ) |
| ;; |
| help) |
| COMPREPLY=( $( compgen -W "$__cargo_commands" -- "$cur" ) ) |
| ;; |
| *) |
| local opt_var=opt__${cmd//-/_} |
| COMPREPLY=( $( compgen -W "${!opt_var}" -- "$cur" ) ) |
| ;; |
| esac |
| fi |
| |
| # compopt does not work in bash version 3 |
| |
| return 0 |
| } && |
| complete -F _cargo cargo |
| |
| __cargo_commands=$(cargo --list 2>/dev/null | tail -n +2) |
| |
| _locate_manifest(){ |
| local manifest=`cargo locate-project 2>/dev/null` |
| # regexp-replace manifest '\{"root":"|"\}' '' |
| echo ${manifest:9:${#manifest}-11} |
| } |
| |
| # Extracts the values of "name" from the array given in $1 and shows them as |
| # command line options for completion |
| _get_names_from_array() |
| { |
| local manifest=$(_locate_manifest) |
| if [[ -z $manifest ]]; then |
| return 0 |
| fi |
| |
| local last_line |
| local -a names |
| local in_block=false |
| local block_name=$1 |
| while read line |
| do |
| if [[ $last_line == "[[$block_name]]" ]]; then |
| in_block=true |
| else |
| if [[ $last_line =~ .*\[\[.* ]]; then |
| in_block=false |
| fi |
| fi |
| |
| if [[ $in_block == true ]]; then |
| if [[ $line =~ .*name.*\= ]]; then |
| line=${line##*=} |
| line=${line%%\"} |
| line=${line##*\"} |
| names+=($line) |
| fi |
| fi |
| |
| last_line=$line |
| done < $manifest |
| echo "${names[@]}" |
| } |
| |
| #Gets the bin names from the manifest file |
| _bin_names() |
| { |
| _get_names_from_array "bin" |
| } |
| |
| #Gets the test names from the manifest file |
| _test_names() |
| { |
| _get_names_from_array "test" |
| } |
| |
| #Gets the bench names from the manifest file |
| _benchmark_names() |
| { |
| _get_names_from_array "bench" |
| } |
| |
| _get_examples(){ |
| local files=($(dirname $(_locate_manifest))/examples/*.rs) |
| local names=("${files[@]##*/}") |
| local names=("${names[@]%.*}") |
| # "*" means no examples found |
| if [[ "${names[@]}" != "*" ]]; then |
| echo "${names[@]}" |
| fi |
| } |
| |
| _get_targets(){ |
| local CURRENT_PATH |
| if [ `uname -o` == "Cygwin" -a -f "$PWD"/Cargo.toml ]; then |
| CURRENT_PATH=$PWD |
| else |
| CURRENT_PATH=$(_locate_manifest) |
| fi |
| if [[ -z "$CURRENT_PATH" ]]; then |
| return 1 |
| fi |
| local TARGETS=() |
| local FIND_PATHS=( "/" ) |
| local FIND_PATH LINES LINE |
| while [[ "$CURRENT_PATH" != "/" ]]; do |
| FIND_PATHS+=( "$CURRENT_PATH" ) |
| CURRENT_PATH=$(dirname $CURRENT_PATH) |
| done |
| for FIND_PATH in ${FIND_PATHS[@]}; do |
| if [[ -f "$FIND_PATH"/.cargo/config ]]; then |
| LINES=( `grep "$FIND_PATH"/.cargo/config -e "^\[target\."` ) |
| for LINE in ${LINES[@]}; do |
| TARGETS+=(`sed 's/^\[target\.\(.*\)\]$/\1/' <<< $LINE`) |
| done |
| fi |
| done |
| echo "${TARGETS[@]}" |
| } |
| |
| _toolchains(){ |
| local result=() |
| local toolchains=$(rustup toolchain list) |
| local channels="nightly|beta|stable|[0-9]\.[0-9]{1,2}\.[0-9]" |
| local date="[0-9]{4}-[0-9]{2}-[0-9]{2}" |
| while read line |
| do |
| # Strip " (default)" |
| line=${line%% *} |
| if [[ "$line" =~ ^($channels)(-($date))?(-.*) ]]; then |
| if [[ -z ${BASH_REMATCH[3]} ]]; then |
| result+=("+${BASH_REMATCH[1]}") |
| else |
| # channel-date |
| result+=("+${BASH_REMATCH[1]}-${BASH_REMATCH[3]}") |
| fi |
| result+=("+$line") |
| else |
| result+=("+$line") |
| fi |
| done <<< "$toolchains" |
| echo "${result[@]}" |
| } |
| |
| # vim:ft=sh |