1# Required for bash versions < 4.1 2# Default bash version is 3.2 on latest macOS. See #6874 3shopt -s extglob 4 5command -v cargo >/dev/null 2>&1 && 6_cargo() 7{ 8 local cur prev words cword 9 _get_comp_words_by_ref cur prev words cword 10 11 COMPREPLY=() 12 13 # Skip past - and + options to find the command. 14 local nwords=${#words[@]} 15 local cmd_i cmd dd_i 16 for (( cmd_i=1; cmd_i<$nwords; cmd_i++ )); 17 do 18 if [[ ! "${words[$cmd_i]}" =~ ^[+-] ]]; then 19 cmd="${words[$cmd_i]}" 20 break 21 fi 22 done 23 # Find the location of the -- separator. 24 for (( dd_i=1; dd_i<$nwords-1; dd_i++ )); 25 do 26 if [[ "${words[$dd_i]}" = "--" ]]; then 27 break 28 fi 29 done 30 31 local vcs='git hg none pijul fossil' 32 local color='auto always never' 33 local msg_format='human json short' 34 35 local opt_help='-h --help' 36 local opt_verbose='-v --verbose' 37 local opt_quiet='-q --quiet' 38 local opt_color='--color' 39 local opt_common="$opt_help $opt_verbose $opt_quiet $opt_color" 40 local opt_pkg_spec='-p --package --all --exclude --workspace' 41 local opt_pkg='-p --package' 42 local opt_feat='-F --features --all-features --no-default-features' 43 local opt_mani='--manifest-path' 44 local opt_jobs='-j --jobs' 45 local opt_parallel="$opt_jobs --keep-going" 46 local opt_force='-f --force' 47 local opt_sync='-s --sync' 48 local opt_lock='--frozen --locked --offline' 49 local opt_targets="--lib --bin --bins --example --examples --test --tests --bench --benches --all-targets" 50 51 local opt___nocmd="$opt_common -V --version --list --explain" 52 local opt__add="$opt_common -p --package --features --default-features --no-default-features $opt_mani --optional --no-optional --rename --dry-run --path --git --branch --tag --rev --registry --dev --build --target --ignore-rust-version" 53 local opt__bench="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_jobs $opt_targets --message-format --target --no-run --no-fail-fast --target-dir --ignore-rust-version" 54 local opt__build="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_parallel $opt_targets --message-format --target --release --profile --target-dir --ignore-rust-version" 55 local opt__b="$opt__build" 56 local opt__check="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_parallel $opt_targets --message-format --target --release --profile --target-dir --ignore-rust-version" 57 local opt__c="$opt__check" 58 local opt__clean="$opt_common $opt_pkg $opt_mani $opt_lock --target --release --doc --target-dir --profile" 59 local opt__clippy="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_parallel $opt_targets --message-format --target --release --profile --target-dir --no-deps --fix" 60 local opt__doc="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_parallel --message-format --bin --bins --lib --target --open --no-deps --release --document-private-items --target-dir --profile --ignore-rust-version" 61 local opt__d="$opt__doc" 62 local opt__fetch="$opt_common $opt_mani $opt_lock --target" 63 local opt__fix="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_parallel $opt_targets $opt_lock --release --target --message-format --broken-code --edition --edition-idioms --allow-no-vcs --allow-dirty --allow-staged --profile --target-dir --ignore-rust-version" 64 local opt__generate_lockfile="$opt_common $opt_mani $opt_lock" 65 local opt__help="$opt_help" 66 local opt__info="$opt_common $opt_lock --registry --index" 67 local opt__init="$opt_common $opt_lock --bin --lib --name --vcs --edition --registry" 68 local opt__install="$opt_common $opt_feat $opt_parallel $opt_lock $opt_force --bin --bins --branch --debug --example --examples --git --list --path --rev --root --tag --version --registry --target --profile --no-track --ignore-rust-version" 69 local opt__locate_project="$opt_common $opt_mani $opt_lock --message-format --workspace" 70 local opt__login="$opt_common $opt_lock --registry" 71 local opt__metadata="$opt_common $opt_feat $opt_mani $opt_lock --format-version=1 --no-deps --filter-platform" 72 local opt__new="$opt_common $opt_lock --vcs --bin --lib --name --edition --registry" 73 local opt__owner="$opt_common $opt_lock -a --add -r --remove -l --list --index --token --registry" 74 local opt__package="$opt_common $opt_mani $opt_feat $opt_lock $opt_parallel --allow-dirty -l --list --no-verify --no-metadata --index --registry --target --target-dir" 75 local opt__pkgid="$opt_common $opt_mani $opt_lock $opt_pkg" 76 local opt__publish="$opt_common $opt_mani $opt_feat $opt_lock $opt_parallel --allow-dirty --dry-run --token --no-verify --index --registry --target --target-dir" 77 local opt__read_manifest="$opt_help $opt_quiet $opt_verbose $opt_mani $opt_color $opt_lock --no-deps" 78 local opt__remove="$opt_common $opt_pkg $opt_lock $opt_mani --dry-run --dev --build --target" 79 local opt__rm="$opt__remove" 80 local opt__report="$opt_help $opt_verbose $opt_color future-incompat future-incompatibilities" 81 local opt__report__future_incompat="$opt_help $opt_verbose $opt_color $opt_pkg --id" 82 local opt__run="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_parallel --message-format --target --bin --example --release --target-dir --profile --ignore-rust-version" 83 local opt__r="$opt__run" 84 local opt__rustc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_parallel $opt_targets -L --crate-type --extern --message-format --profile --target --release --target-dir --ignore-rust-version" 85 local opt__rustdoc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_parallel $opt_targets --message-format --target --release --open --target-dir --profile --ignore-rust-version" 86 local opt__search="$opt_common $opt_lock --limit --index --registry" 87 local opt__test="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_jobs $opt_targets --message-format --doc --target --no-run --release --no-fail-fast --target-dir --profile --ignore-rust-version" 88 local opt__t="$opt__test" 89 local opt__tree="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock --target -i --invert --prefix --no-dedupe --duplicates -d --charset -f --format -e --edges" 90 local opt__uninstall="$opt_common $opt_lock $opt_pkg --bin --root" 91 local opt__update="$opt_common $opt_mani $opt_lock $opt_pkg --aggressive --recursive --precise --dry-run" 92 local opt__vendor="$opt_common $opt_mani $opt_lock $opt_sync --no-delete --respect-source-config --versioned-dirs" 93 local opt__verify_project="$opt_common $opt_mani $opt_lock" 94 local opt__version="$opt_common $opt_lock" 95 local opt__yank="$opt_common $opt_lock --version --undo --index --token --registry" 96 local opt__libtest="--help --include-ignored --ignored --test --bench --list --logfile --nocapture --test-threads --skip -q --quiet --exact --color --format" 97 98 if [[ $cword -gt $dd_i ]]; then 99 # Completion after -- separator. 100 if [[ "${cmd}" = @(test|bench) ]]; then 101 COMPREPLY=( $( compgen -W "${opt__libtest}" -- "$cur" ) ) 102 else 103 # Fallback to filename completion, useful with `cargo run`. 104 _filedir 105 fi 106 elif [[ $cword -le $cmd_i ]]; then 107 # Completion before or at the command. 108 if [[ "$cur" == -* ]]; then 109 COMPREPLY=( $( compgen -W "${opt___nocmd}" -- "$cur" ) ) 110 elif [[ "$cur" == +* ]]; then 111 COMPREPLY=( $( compgen -W "$(_toolchains)" -- "$cur" ) ) 112 else 113 _ensure_cargo_commands_cache_filled 114 COMPREPLY=( $( compgen -W "$__cargo_commands_cache" -- "$cur" ) ) 115 fi 116 else 117 case "${prev}" in 118 --vcs) 119 COMPREPLY=( $( compgen -W "$vcs" -- "$cur" ) ) 120 ;; 121 --color) 122 COMPREPLY=( $( compgen -W "$color" -- "$cur" ) ) 123 ;; 124 --message-format) 125 COMPREPLY=( $( compgen -W "$msg_format" -- "$cur" ) ) 126 ;; 127 --manifest-path) 128 _filedir toml 129 ;; 130 --bin) 131 COMPREPLY=( $( compgen -W "$(_bin_names)" -- "$cur" ) ) 132 ;; 133 --test) 134 COMPREPLY=( $( compgen -W "$(_test_names)" -- "$cur" ) ) 135 ;; 136 --bench) 137 COMPREPLY=( $( compgen -W "$(_benchmark_names)" -- "$cur" ) ) 138 ;; 139 --example) 140 COMPREPLY=( $( compgen -W "$(_get_examples)" -- "$cur" ) ) 141 ;; 142 --target) 143 COMPREPLY=( $( compgen -W "$(_get_targets)" -- "$cur" ) ) 144 ;; 145 --target-dir|--path) 146 _filedir -d 147 ;; 148 help) 149 _ensure_cargo_commands_cache_filled 150 COMPREPLY=( $( compgen -W "$__cargo_commands_cache" -- "$cur" ) ) 151 ;; 152 *) 153 if [[ "$cmd" == "report" && "$prev" == future-incompat* ]]; then 154 local opt_var=opt__${cmd//-/_}__${prev//-/_} 155 else 156 local opt_var=opt__${cmd//-/_} 157 fi 158 if [[ -z "${!opt_var-}" ]]; then 159 # Fallback to filename completion. 160 _filedir 161 else 162 COMPREPLY=( $( compgen -W "${!opt_var}" -- "$cur" ) ) 163 fi 164 ;; 165 esac 166 fi 167 168 # compopt does not work in bash version 3 169 170 return 0 171} && 172complete -F _cargo cargo 173 174__cargo_commands_cache= 175_ensure_cargo_commands_cache_filled(){ 176 if [[ -z $__cargo_commands_cache ]]; then 177 __cargo_commands_cache="$(cargo --list 2>/dev/null | awk 'NR>1 {print $1}')" 178 fi 179} 180 181_locate_manifest(){ 182 cargo locate-project --message-format plain 2>/dev/null 183} 184 185# Extracts the values of "name" from the array given in $1 and shows them as 186# command line options for completion 187_get_names_from_array() 188{ 189 local manifest=$(_locate_manifest) 190 if [[ -z $manifest ]]; then 191 return 0 192 fi 193 194 local last_line 195 local -a names 196 local in_block=false 197 local block_name=$1 198 while read line 199 do 200 if [[ $last_line == "[[$block_name]]" ]]; then 201 in_block=true 202 else 203 if [[ $last_line =~ .*\[\[.* ]]; then 204 in_block=false 205 fi 206 fi 207 208 if [[ $in_block == true ]]; then 209 if [[ $line =~ .*name.*\= ]]; then 210 line=${line##*=} 211 line=${line%%\"} 212 line=${line##*\"} 213 names+=("$line") 214 fi 215 fi 216 217 last_line=$line 218 done < "$manifest" 219 echo "${names[@]}" 220} 221 222#Gets the bin names from the manifest file 223_bin_names() 224{ 225 _get_names_from_array "bin" 226} 227 228#Gets the test names from the manifest file 229_test_names() 230{ 231 _get_names_from_array "test" 232} 233 234#Gets the bench names from the manifest file 235_benchmark_names() 236{ 237 _get_names_from_array "bench" 238} 239 240_get_examples(){ 241 local manifest=$(_locate_manifest) 242 [ -z "$manifest" ] && return 0 243 244 local files=("${manifest%/*}"/examples/*.rs) 245 local names=("${files[@]##*/}") 246 local names=("${names[@]%.*}") 247 # "*" means no examples found 248 if [[ "${names[@]}" != "*" ]]; then 249 echo "${names[@]}" 250 fi 251} 252 253_get_targets(){ 254 if command -v rustup >/dev/null 2>/dev/null; then 255 rustup target list --installed 256 else 257 rustc --print target-list 258 fi 259} 260 261_toolchains(){ 262 local result=() 263 local toolchains=$(rustup toolchain list) 264 local channels="nightly|beta|stable|[0-9]\.[0-9]{1,2}\.[0-9]" 265 local date="[0-9]{4}-[0-9]{2}-[0-9]{2}" 266 while read line 267 do 268 # Strip " (default)" 269 line=${line%% *} 270 if [[ "$line" =~ ^($channels)(-($date))?(-.*) ]]; then 271 if [[ -z ${BASH_REMATCH[3]} ]]; then 272 result+=("+${BASH_REMATCH[1]}") 273 else 274 # channel-date 275 result+=("+${BASH_REMATCH[1]}-${BASH_REMATCH[3]}") 276 fi 277 result+=("+$line") 278 else 279 result+=("+$line") 280 fi 281 done <<< "$toolchains" 282 echo "${result[@]}" 283} 284 285# vim:ft=sh 286