1# Bash auto-completion for west subcommands and flags. To initialize, run 2# 3# source west-completion.bash 4# 5# To make it persistent, add it to e.g. your .bashrc. 6 7__west_previous_extglob_setting=$(shopt -p extglob) 8shopt -s extglob 9 10# The following function is based on code from: 11# 12# bash_completion - programmable completion functions for bash 3.2+ 13# 14# Copyright © 2006-2008, Ian Macdonald <ian@caliban.org> 15# © 2009-2010, Bash Completion Maintainers 16# <bash-completion-devel@lists.alioth.debian.org> 17# 18# This program is free software; you can redistribute it and/or modify 19# it under the terms of the GNU General Public License as published by 20# the Free Software Foundation; either version 2, or (at your option) 21# any later version. 22# 23# This program is distributed in the hope that it will be useful, 24# but WITHOUT ANY WARRANTY; without even the implied warranty of 25# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26# GNU General Public License for more details. 27# 28# You should have received a copy of the GNU General Public License 29# along with this program; if not, see <http://www.gnu.org/licenses/>. 30# 31# The latest version of this software can be obtained here: 32# 33# http://bash-completion.alioth.debian.org/ 34# 35# RELEASE: 2.x 36 37# This function can be used to access a tokenized list of words 38# on the command line: 39# 40# __git_reassemble_comp_words_by_ref '=:' 41# if test "${words_[cword_-1]}" = -w 42# then 43# ... 44# fi 45# 46# The argument should be a collection of characters from the list of 47# word completion separators (COMP_WORDBREAKS) to treat as ordinary 48# characters. 49# 50# This is roughly equivalent to going back in time and setting 51# COMP_WORDBREAKS to exclude those characters. The intent is to 52# make option types like --date=<type> and <rev>:<path> easy to 53# recognize by treating each shell word as a single token. 54# 55# It is best not to set COMP_WORDBREAKS directly because the value is 56# shared with other completion scripts. By the time the completion 57# function gets called, COMP_WORDS has already been populated so local 58# changes to COMP_WORDBREAKS have no effect. 59# 60# Output: words_, cword_, cur_. 61 62__west_reassemble_comp_words_by_ref() 63{ 64 local exclude i j first 65 # Which word separators to exclude? 66 exclude="${1//[^$COMP_WORDBREAKS]}" 67 cword_=$COMP_CWORD 68 if [ -z "$exclude" ]; then 69 words_=("${COMP_WORDS[@]}") 70 return 71 fi 72 # List of word completion separators has shrunk; 73 # re-assemble words to complete. 74 for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do 75 # Append each nonempty word consisting of just 76 # word separator characters to the current word. 77 first=t 78 while 79 [ $i -gt 0 ] && 80 [ -n "${COMP_WORDS[$i]}" ] && 81 # word consists of excluded word separators 82 [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] 83 do 84 # Attach to the previous token, 85 # unless the previous token is the command name. 86 if [ $j -ge 2 ] && [ -n "$first" ]; then 87 ((j--)) 88 fi 89 first= 90 words_[$j]=${words_[j]}${COMP_WORDS[i]} 91 if [ $i = $COMP_CWORD ]; then 92 cword_=$j 93 fi 94 if (($i < ${#COMP_WORDS[@]} - 1)); then 95 ((i++)) 96 else 97 # Done. 98 return 99 fi 100 done 101 words_[$j]=${words_[j]}${COMP_WORDS[i]} 102 if [ $i = $COMP_CWORD ]; then 103 cword_=$j 104 fi 105 done 106} 107 108if ! type _get_comp_words_by_ref >/dev/null 2>&1; then 109_get_comp_words_by_ref () 110{ 111 local exclude cur_ words_ cword_ 112 if [ "$1" = "-n" ]; then 113 exclude=$2 114 shift 2 115 fi 116 __west_reassemble_comp_words_by_ref "$exclude" 117 cur_=${words_[cword_]} 118 while [ $# -gt 0 ]; do 119 case "$1" in 120 cur) 121 cur=$cur_ 122 ;; 123 prev) 124 prev=${words_[$cword_-1]} 125 ;; 126 words) 127 words=("${words_[@]}") 128 ;; 129 cword) 130 cword=$cword_ 131 ;; 132 esac 133 shift 134 done 135} 136fi 137 138if ! type _tilde >/dev/null 2>&1; then 139# Perform tilde (~) completion 140# @return True (0) if completion needs further processing, 141# False (> 0) if tilde is followed by a valid username, completions 142# are put in COMPREPLY and no further processing is necessary. 143_tilde() 144{ 145 local result=0 146 if [[ $1 == \~* && $1 != */* ]]; then 147 # Try generate ~username completions 148 COMPREPLY=( $( compgen -P '~' -u -- "${1#\~}" ) ) 149 result=${#COMPREPLY[@]} 150 # 2>/dev/null for direct invocation, e.g. in the _tilde unit test 151 [[ $result -gt 0 ]] && compopt -o filenames 2>/dev/null 152 fi 153 return $result 154} 155fi 156 157if ! type _quote_readline_by_ref >/dev/null 2>&1; then 158# This function quotes the argument in a way so that readline dequoting 159# results in the original argument. This is necessary for at least 160# `compgen' which requires its arguments quoted/escaped: 161# 162# $ ls "a'b/" 163# c 164# $ compgen -f "a'b/" # Wrong, doesn't return output 165# $ compgen -f "a\'b/" # Good 166# a\'b/c 167# 168# See also: 169# - http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html 170# - http://www.mail-archive.com/bash-completion-devel@lists.alioth.\ 171# debian.org/msg01944.html 172# @param $1 Argument to quote 173# @param $2 Name of variable to return result to 174_quote_readline_by_ref() 175{ 176 if [ -z "$1" ]; then 177 # avoid quoting if empty 178 printf -v $2 %s "$1" 179 elif [[ $1 == \'* ]]; then 180 # Leave out first character 181 printf -v $2 %s "${1:1}" 182 elif [[ $1 == \~* ]]; then 183 # avoid escaping first ~ 184 printf -v $2 \~%q "${1:1}" 185 else 186 printf -v $2 %q "$1" 187 fi 188 189 # Replace double escaping ( \\ ) by single ( \ ) 190 # This happens always when argument is already escaped at cmdline, 191 # and passed to this function as e.g.: file\ with\ spaces 192 [[ ${!2} == *\\* ]] && printf -v $2 %s "${1//\\\\/\\}" 193 194 # If result becomes quoted like this: $'string', re-evaluate in order to 195 # drop the additional quoting. See also: http://www.mail-archive.com/ 196 # bash-completion-devel@lists.alioth.debian.org/msg01942.html 197 [[ ${!2} == \$* ]] && eval $2=${!2} 198} # _quote_readline_by_ref() 199fi 200 201# This function turns on "-o filenames" behavior dynamically. It is present 202# for bash < 4 reasons. See http://bugs.debian.org/272660#64 for info about 203# the bash < 4 compgen hack. 204_compopt_o_filenames() 205{ 206 # We test for compopt availability first because directly invoking it on 207 # bash < 4 at this point may cause terminal echo to be turned off for some 208 # reason, see https://bugzilla.redhat.com/653669 for more info. 209 type compopt &>/dev/null && compopt -o filenames 2>/dev/null || \ 210 compgen -f /non-existing-dir/ >/dev/null 211} 212 213if ! type _filedir >/dev/null 2>&1; then 214# This function performs file and directory completion. It's better than 215# simply using 'compgen -f', because it honours spaces in filenames. 216# @param $1 If `-d', complete only on directories. Otherwise filter/pick only 217# completions with `.$1' and the uppercase version of it as file 218# extension. 219# 220_filedir() 221{ 222 local IFS=$'\n' 223 224 _tilde "$cur" || return 225 226 local -a toks 227 local x tmp 228 229 x=$( compgen -d -- "$cur" ) && 230 while read -r tmp; do 231 toks+=( "$tmp" ) 232 done <<< "$x" 233 234 if [[ "$1" != -d ]]; then 235 local quoted 236 _quote_readline_by_ref "$cur" quoted 237 238 # Munge xspec to contain uppercase version too 239 # http://thread.gmane.org/gmane.comp.shells.bash.bugs/15294/focus=15306 240 local xspec=${1:+"!*.@($1|${1^^})"} 241 x=$( compgen -f -X "$xspec" -- $quoted ) && 242 while read -r tmp; do 243 toks+=( "$tmp" ) 244 done <<< "$x" 245 246 # Try without filter if it failed to produce anything and configured to 247 [[ -n ${COMP_FILEDIR_FALLBACK:-} && -n "$1" && ${#toks[@]} -lt 1 ]] && \ 248 x=$( compgen -f -- $quoted ) && 249 while read -r tmp; do 250 toks+=( "$tmp" ) 251 done <<< "$x" 252 fi 253 254 if [[ ${#toks[@]} -ne 0 ]]; then 255 # 2>/dev/null for direct invocation, e.g. in the _filedir unit test 256 _compopt_o_filenames 257 COMPREPLY+=( "${toks[@]}" ) 258 fi 259} # _filedir() 260fi 261 262# Misc helpers taken from Docker: 263# https://github.com/docker/docker-ce/blob/master/components/cli/contrib/completion/bash/docker 264 265# __west_pos_first_nonflag finds the position of the first word that is neither 266# option nor an option's argument. If there are options that require arguments, 267# you should pass a glob describing those options, e.g. "--option1|-o|--option2" 268# Use this function to restrict completions to exact positions after the argument list. 269__west_pos_first_nonflag() 270{ 271 local argument_flags=$1 272 273 local counter=$((${subcommand_pos:-${command_pos}} + 1)) 274 while [ "$counter" -le "$cword" ]; do 275 if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then 276 (( counter++ )) 277 # eat "=" in case of --option=arg syntax 278 [ "${words[$counter]}" = "=" ] && (( counter++ )) 279 else 280 case "${words[$counter]}" in 281 -*) 282 ;; 283 *) 284 break 285 ;; 286 esac 287 fi 288 289 # Bash splits words at "=", retaining "=" as a word, examples: 290 # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words 291 while [ "${words[$counter + 1]}" = "=" ] ; do 292 counter=$(( counter + 2)) 293 done 294 295 (( counter++ )) 296 done 297 298 echo $counter 299} 300 301# __west_map_key_of_current_option returns `key` if we are currently completing the 302# value of a map option (`key=value`) which matches the extglob given as an argument. 303# This function is needed for key-specific completions. 304__west_map_key_of_current_option() 305{ 306 local glob="$1" 307 308 local key glob_pos 309 if [ "$cur" = "=" ] ; then # key= case 310 key="$prev" 311 glob_pos=$((cword - 2)) 312 elif [[ $cur == *=* ]] ; then # key=value case (OSX) 313 key=${cur%=*} 314 glob_pos=$((cword - 1)) 315 elif [ "$prev" = "=" ] ; then 316 key=${words[$cword - 2]} # key=value case 317 glob_pos=$((cword - 3)) 318 else 319 return 320 fi 321 322 [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax 323 324 [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key" 325} 326 327# __west_value_of_option returns the value of the first option matching `option_glob`. 328# Valid values for `option_glob` are option names like `--log-level` and globs like 329# `--log-level|-l` 330# Only positions between the command and the current word are considered. 331__west_value_of_option() 332{ 333 local option_extglob=$(__west_to_extglob "$1") 334 335 local counter=$((command_pos + 1)) 336 while [ "$counter" -lt "$cword" ]; do 337 case ${words[$counter]} in 338 $option_extglob ) 339 echo "${words[$counter + 1]}" 340 break 341 ;; 342 esac 343 (( counter++ )) 344 done 345} 346 347# __west_to_alternatives transforms a multiline list of strings into a single line 348# string with the words separated by `|`. 349# This is used to prepare arguments to __west_pos_first_nonflag(). 350__west_to_alternatives() 351{ 352 local parts=( $1 ) 353 local IFS='|' 354 echo "${parts[*]}" 355} 356 357# __west_to_extglob transforms a multiline list of options into an extglob pattern 358# suitable for use in case statements. 359__west_to_extglob() 360{ 361 local extglob=$( __west_to_alternatives "$1" ) 362 echo "@($extglob)" 363} 364 365__set_comp_dirs() 366{ 367 _filedir -d 368} 369 370__set_comp_files() 371{ 372 _filedir 373} 374 375# Sets completions for $cur, from the possibilities in $1..n 376__set_comp() 377{ 378 # "${*:1}" gives a single argument with arguments $1..n 379 COMPREPLY=($(compgen -W "${*:1}" -- "$cur")) 380} 381 382 383__west_x() 384{ 385 west 2>/dev/null "$@" 386} 387 388__set_comp_west_projs() 389{ 390 __set_comp "$(__west_x list --format={name} "$@")" 391} 392 393__set_comp_west_boards() 394{ 395 boards=( $(__west_x boards --format='{name}|{qualifiers}' "$@") ) 396 for i in ${!boards[@]}; do 397 name="${boards[$i]%%|*}" 398 transformed_board="${boards[$i]//|//}" 399 boards[$i]="${transformed_board//,/\ ${name}\/}" 400 done 401 __set_comp ${boards[@]} 402} 403 404__set_comp_west_shields() 405{ 406 __set_comp "$(__west_x shields "$@")" 407} 408 409__comp_west_west() 410{ 411 case "$prev" in 412 --zephyr-base|-z) 413 __set_comp_dirs 414 return 415 ;; 416 # We don't know how to autocomplete any others 417 $(__west_to_extglob "$global_args_opts") ) 418 return 419 ;; 420 esac 421 422 case "$cur" in 423 -*) 424 __set_comp $global_bool_opts $global_args_opts 425 ;; 426 *) 427 local counter=$( __west_pos_first_nonflag "$(__west_to_extglob "$global_args_opts")" ) 428 if [ "$cword" -eq "$counter" ]; then 429 __set_comp ${cmds[*]} 430 fi 431 ;; 432 esac 433} 434 435__comp_west_init() 436{ 437 local dir_opts=" 438 --manifest -m 439 --local -l 440 " 441 442 local bool_opts=" 443 --manifest-rev --mr 444 --manifest-file --mf 445 " 446 447 all_opts="$dir_opts $bool_opts" 448 449 case "$prev" in 450 $(__west_to_extglob "$dir_opts") ) 451 __set_comp_dirs 452 return 453 ;; 454 esac 455 456 case "$cur" in 457 -*) 458 __set_comp $all_opts 459 ;; 460 esac 461} 462 463__comp_west_update() 464{ 465 local bool_opts=" 466 --stats 467 --narrow -n 468 --keep-descendants -k 469 --rebase -r 470 " 471 472 local dir_opts=" 473 --name-cache 474 --path-cache 475 " 476 477 local other_opts=" 478 --fetch -f 479 --fetch-opt -o 480 " 481 482 all_opts="$dir_opts $bool_opts $other_opts" 483 484 case "$prev" in 485 # We don't know how to autocomplete those 486 $(__west_to_extglob "$other_opts") ) 487 return 488 ;; 489 490 $(__west_to_extglob "$dir_opts") ) 491 __set_comp_dirs 492 return 493 ;; 494 esac 495 496 case "$cur" in 497 -*) 498 __set_comp $all_opts 499 ;; 500 *) 501 __set_comp_west_projs 502 ;; 503 esac 504} 505 506__comp_west_list() 507{ 508 local other_opts=" 509 --format -f 510 " 511 512 local bool_opts=" 513 --all -a 514 " 515 516 all_opts="$other_opts $bool_opts" 517 518 case "$prev" in 519 # We don't know how to autocomplete those 520 $(__west_to_extglob "$other_opts") ) 521 return 522 ;; 523 esac 524 525 case "$cur" in 526 -*) 527 __set_comp $all_opts 528 ;; 529 *) 530 __set_comp_west_projs 531 ;; 532 esac 533} 534 535__comp_west_manifest() 536{ 537 local bool_opts=" 538 --resolve 539 --freeze 540 --validate 541 --path 542 " 543 local file_opts=" 544 --out -o 545 " 546 547 all_opts="$bool_opts $file_opts" 548 549 case "$prev" in 550 $(__west_to_extglob "$file_opts") ) 551 __set_comp_files 552 return 553 ;; 554 esac 555 556 case "$cur" in 557 -*) 558 __set_comp $all_opts 559 ;; 560 esac 561} 562 563__comp_west_diff() 564{ 565 local bool_opts=" 566 --all -a 567 " 568 569 case "$cur" in 570 -*) 571 __set_comp $bool_opts 572 ;; 573 *) 574 __set_comp_west_projs 575 ;; 576 esac 577} 578 579__comp_west_status() 580{ 581 local bool_opts=" 582 --all -a 583 " 584 case "$cur" in 585 -*) 586 __set_comp $bool_opts 587 ;; 588 *) 589 __set_comp_west_projs 590 ;; 591 esac 592} 593 594__comp_west_forall() 595{ 596 local bool_opts=" 597 --all -a 598 " 599 local other_opts=" 600 -c 601 " 602 603 all_opts="$bool_opts $other_opts" 604 case "$prev" in 605 # We don't know how to autocomplete those 606 $(__west_to_extglob "$other_opts") ) 607 return 608 ;; 609 esac 610 611 case "$cur" in 612 -*) 613 __set_comp $all_opts 614 ;; 615 *) 616 __set_comp_west_projs 617 ;; 618 esac 619} 620 621__comp_west_config() 622{ 623 local bool_opts=" 624 --list -l 625 --delete -d 626 --delete-all -D 627 --global 628 --local 629 --system 630 " 631 632 case "$cur" in 633 -*) 634 __set_comp $bool_opts 635 ;; 636 esac 637} 638 639__comp_west_help() 640{ 641 case "$cur" in 642 *) 643 local counter=$( __west_pos_first_nonflag "$(__west_to_extglob "$global_args_opts")" ) 644 if [ "$cword" -eq "$counter" ]; then 645 __set_comp ${cmds[*]} 646 fi 647 ;; 648 esac 649} 650 651# Zephyr extension commands 652__comp_west_completion() 653{ 654 case "$cur" in 655 *) 656 local counter=$( __west_pos_first_nonflag "$(__west_to_extglob "$global_args_opts")" ) 657 if [ "$cword" -eq "$counter" ]; then 658 __set_comp "bash zsh fish" 659 fi 660 ;; 661 esac 662} 663 664__comp_west_boards() 665{ 666 local other_opts=" 667 --format -f 668 --name -n 669 " 670 671 local dir_opts=" 672 --arch-root 673 --board-root 674 --soc-root 675 " 676 677 all_opts="$dir_opts $other_opts" 678 679 case "$prev" in 680 $(__west_to_extglob "$other_opts") ) 681 # We don't know how to autocomplete these. 682 return 683 ;; 684 $(__west_to_extglob "$dir_opts") ) 685 __set_comp_dirs 686 return 687 ;; 688 esac 689 690 case "$cur" in 691 -*) 692 __set_comp $all_opts 693 ;; 694 esac 695} 696 697__comp_west_shields() 698{ 699 local other_opts=" 700 --format -f 701 --name -n 702 " 703 704 local dir_opts=" 705 --board-root 706 " 707 708 all_opts="$dir_opts $other_opts" 709 710 case "$prev" in 711 $(__west_to_extglob "$other_opts") ) 712 # We don't know how to autocomplete these. 713 return 714 ;; 715 $(__west_to_extglob "$dir_opts") ) 716 __set_comp_dirs 717 return 718 ;; 719 esac 720 721 case "$cur" in 722 -*) 723 __set_comp $all_opts 724 ;; 725 esac 726} 727 728__comp_west_build() 729{ 730 local bool_opts=" 731 --cmake -c 732 --cmake-only 733 -n --just-print --dry-run --recon 734 --force -f 735 --sysbuild 736 --no-sysbuild 737 " 738 739 local special_opts=" 740 --board -b 741 --snippet -S 742 --shield 743 --pristine -p 744 " 745 746 local dir_opts=" 747 --build-dir -d 748 " 749 750 local other_opts=" 751 --target -t 752 --test-item -T 753 --build-opt -o 754 --domain 755 " 756 757 all_opts="$bool_opts $special_opts $dir_opts $other_opts" 758 759 case "$prev" in 760 --board|-b) 761 __set_comp_west_boards 762 return 763 ;; 764 --shield) 765 __set_comp_west_shields 766 return 767 ;; 768 --pristine|-p) 769 __set_comp "auto always never" 770 return 771 ;; 772 $(__west_to_extglob "$dir_opts") ) 773 __set_comp_dirs 774 return 775 ;; 776 # We don't know how to autocomplete those 777 $(__west_to_extglob "$other_opts") ) 778 return 779 ;; 780 esac 781 782 case "$cur" in 783 -*) 784 __set_comp $all_opts 785 ;; 786 *) 787 __set_comp_dirs 788 ;; 789 esac 790} 791 792__comp_west_sign() 793{ 794 local bool_opts=" 795 --quiet -q 796 --force -f 797 --bin --no-bin 798 --hex --no-hex 799 " 800 801 local special_opts=" 802 --tool -t 803 " 804 805 local dir_opts=" 806 --build-dir -d 807 --tool-path -p 808 --tool-data -D 809 " 810 811 local file_opts=" 812 --sbin -B 813 --shex -H 814 " 815 816 all_opts="$bool_opts $special_opts $dir_opts $file_opts" 817 818 case "$prev" in 819 $(__west_to_extglob "$dir_opts") ) 820 __set_comp_dirs 821 return 822 ;; 823 --tool|-t) 824 __set_comp "imgtool rimage" 825 return 826 ;; 827 $(__west_to_extglob "$file_opts") ) 828 __set_comp_files 829 return 830 ;; 831 esac 832 833 case "$cur" in 834 -*) 835 __set_comp $all_opts 836 ;; 837 esac 838} 839 840__comp_west_runner_cmd() 841{ 842 # Common arguments for runners 843 local bool_opts=" 844 --context -H 845 --rebuild 846 --no-rebuild 847 " 848 849 local dir_opts=" 850 --board-dir 851 --openocd-search 852 --build-dir -d 853 " 854 855 local file_opts=" 856 --file -f 857 --file-type -t 858 --elf-file 859 --hex-file 860 --bin-file 861 --gdb 862 --openocd 863 " 864 865 local other_opts=" 866 --runner -r 867 --domain 868 --dev-id -i 869 " 870 871 all_opts="$bool_opts $other_opts $dir_opts $file_opts" 872 873 case "$prev" in 874 $(__west_to_extglob "$dir_opts") ) 875 __set_comp_dirs 876 return 877 ;; 878 $(__west_to_extglob "$file_opts") ) 879 __set_comp_files 880 return 881 ;; 882 esac 883 884 case "$cur" in 885 -*) 886 __set_comp $all_opts 887 ;; 888 esac 889} 890 891__comp_west_flash() 892{ 893 __comp_west_runner_cmd 894} 895 896__comp_west_debug() 897{ 898 __comp_west_runner_cmd 899} 900 901__comp_west_debugserver() 902{ 903 __comp_west_runner_cmd 904} 905 906__comp_west_attach() 907{ 908 __comp_west_runner_cmd 909} 910 911__comp_west_spdx() 912{ 913 local bool_opts=" 914 --init -i 915 --analyze-includes 916 --include-sdk 917 " 918 919 local dir_opts=" 920 --build-dir -d 921 --namespace-prefix -n 922 --spdx-dir -s 923 " 924 925 local other_opts=" 926 --namespace-prefix -n 927 " 928 929 all_opts="$bool_opts $other_opts $dir_opts" 930 931 case "$prev" in 932 $(__west_to_extglob "$dir_opts") ) 933 __set_comp_dirs 934 return 935 ;; 936 937 # We don't know how to autocomplete those 938 $(__west_to_extglob "$other_opts") ) 939 return 940 ;; 941 esac 942 943 case "$cur" in 944 -*) 945 __set_comp $all_opts 946 ;; 947 esac 948} 949 950__comp_west_blobs() 951{ 952 local other_opts=" 953 --format -f 954 " 955 956 case "$prev" in 957 # We don't know how to autocomplete those 958 $(__west_to_extglob "$other_opts") ) 959 return 960 ;; 961 blobs) 962 __set_comp "list fetch clean" 963 return 964 ;; 965 esac 966 967 case "$cur" in 968 -*) 969 __set_comp $other_opts 970 ;; 971 *) 972 __set_comp_west_projs 973 ;; 974 esac 975} 976 977__comp_west_twister() 978{ 979 local bool_opts=" 980 --aggressive-no-clean 981 --all -l 982 --all-deltas -D 983 --allow-installed-plugin 984 --build-only -b 985 --clobber-output -c 986 --cmake-only 987 --coverage -C 988 --create-rom-ram-report 989 --detailed-skipped-report 990 --detailed-test-id 991 --device-flash-with-test 992 --device-testing 993 --disable-suite-name-check 994 --disable-unrecognized-section-test 995 --disable-warnings-as-errors -W 996 --dry-run -y 997 --emulation-only 998 --enable-asan 999 --enable-coverage 1000 --enable-lsan 1001 --enable-size-report 1002 --enable-slow -S 1003 --enable-slow-only 1004 --enable-ubsan 1005 --enable-valgrind 1006 --flash-before 1007 --footprint-from-buildlog 1008 --force-color 1009 --force-platform -K 1010 --force-toolchain 1011 --ignore-platform-key 1012 --inline-logs -i 1013 --integration -G 1014 --last-metrics -m 1015 --list-tags 1016 --list-tests 1017 --make -k 1018 --ninja -N 1019 --no-clean -n 1020 --no-detailed-test-id 1021 --no-update -u 1022 --only-failed -f 1023 --overflow-as-errors 1024 --persistent-hardware-map 1025 --platform-reports 1026 --prep-artifacts-for-testing 1027 --quarantine-verify 1028 --retry-build-errors 1029 --short-build-path 1030 --show-footprint 1031 --shuffle-tests 1032 --test-only 1033 --test-tree 1034 --timestamps 1035 --verbose -v 1036 " 1037 1038 local dir_opts=" 1039 --alt-config-root 1040 --board-root -A 1041 --coverage-basedir 1042 --outdir -O 1043 --report-dir -o 1044 --testsuite-root -T 1045 " 1046 1047 local file_opts=" 1048 --compare-report 1049 --device-serial 1050 --device-serial-pty 1051 --gcov-tool 1052 --generate-hardware-map 1053 --hardware-map 1054 --load-tests -F 1055 --log-file 1056 --package-artifacts 1057 --pre-script 1058 --quarantine-list 1059 --save-tests -E 1060 --size -z 1061 --test-config 1062 " 1063 1064 local special_opts=" 1065 --coverage-platform 1066 --coverage-tool 1067 --exclude-platform -P 1068 --filter 1069 --log-level 1070 --platform -p 1071 --runtime-artifact-cleanup -M 1072 " 1073 1074 local other_opts=" 1075 --arch -a 1076 --coverage-formats 1077 --device-flash-timeout 1078 --device-serial-baud 1079 --exclude-tag -e 1080 --extra-args -x 1081 --fixture -X 1082 --footprint-threshold -H 1083 --jobs -j 1084 --level 1085 --pytest-args 1086 --report-name 1087 --report-suffix 1088 --retry-failed 1089 --retry-interval 1090 --scenario --test -s 1091 --seed 1092 --shuffle-tests-seed 1093 --sub-test 1094 --subset -B 1095 --tag -t 1096 --timeout-multiplier 1097 --vendor 1098 --west-flash 1099 --west-runner 1100 " 1101 1102 all_opts="$bool_opts $dir_opts $file_opts $special_opts $other_opts" 1103 1104 case "$prev" in 1105 --platform|-p|--exclude-platform|-P|--coverage-platform) 1106 __set_comp_west_boards 1107 return 1108 ;; 1109 1110 --coverage-tool) 1111 __set_comp "gcovr lcov" 1112 return 1113 ;; 1114 1115 --filter) 1116 __set_comp "buildable runnable" 1117 return 1118 ;; 1119 1120 --log-level) 1121 __set_comp "CRITICAL DEBUG ERROR INFO NOTSET WARNING" 1122 return 1123 ;; 1124 1125 --runtime-artifact-cleanup|-M) 1126 __set_comp "all pass" 1127 return 1128 ;; 1129 1130 $(__west_to_extglob "$dir_opts") ) 1131 __set_comp_dirs 1132 return 1133 ;; 1134 1135 $(__west_to_extglob "$file_opts") ) 1136 __set_comp_files 1137 return 1138 ;; 1139 1140 # We don't know how to autocomplete those 1141 $(__west_to_extglob "$other_opts") ) 1142 return 1143 ;; 1144 esac 1145 1146 case "$cur" in 1147 -*) 1148 __set_comp $all_opts 1149 ;; 1150 esac 1151} 1152 1153__comp_west_sdk() 1154{ 1155 local bool_opts=" 1156 --interactive -i 1157 --no-toolchains -T 1158 --no-hosttools -H 1159 " 1160 1161 local dir_opts=" 1162 --install-dir -d 1163 --install-base -b 1164 " 1165 1166 local other_opts=" 1167 --version 1168 --toolchains -t 1169 --personal-access-token 1170 --api-url 1171 " 1172 1173 all_opts="$bool_opts $dir_opts $other_opts" 1174 1175 case "$prev" in 1176 sdk) 1177 __set_comp "list install" 1178 return 1179 ;; 1180 list) 1181 return 1182 ;; 1183 $(__west_to_extglob "$dir_opts") ) 1184 __set_comp_dirs 1185 return 1186 ;; 1187 # We don't know how to autocomplete those 1188 $(__west_to_extglob "$other_opts") ) 1189 return 1190 ;; 1191 esac 1192 1193 case "$cur" in 1194 -*) 1195 __set_comp $all_opts 1196 ;; 1197 esac 1198} 1199 1200__comp_west() 1201{ 1202 local previous_extglob_setting=$(shopt -p extglob) 1203 shopt -s extglob 1204 # Reset to default, to make sure compgen works properly 1205 local IFS=$' \t\n' 1206 1207 local builtin_cmds=( 1208 init 1209 update 1210 list 1211 manifest 1212 compare 1213 diff 1214 status 1215 forall 1216 grep 1217 help 1218 config 1219 topdir 1220 ) 1221 1222 local zephyr_ext_cmds=( 1223 completion 1224 boards 1225 shields 1226 build 1227 twister 1228 sign 1229 flash 1230 debug 1231 debugserver 1232 attach 1233 rtt 1234 zephyr-export 1235 spdx 1236 blobs 1237 bindesc 1238 robot 1239 simulate 1240 sdk 1241 packages 1242 patch 1243 gtags 1244 ) 1245 1246 local cmds=(${builtin_cmds[*]} ${zephyr_ext_cmds[*]}) 1247 1248 # Global options for all commands 1249 local global_bool_opts=" 1250 --help -h 1251 --verbose -v 1252 --version -V 1253 " 1254 local global_args_opts=" 1255 --zephyr-base -z 1256 " 1257 1258 COMPREPLY=() 1259 local cur words cword prev 1260 _get_comp_words_by_ref -n : cur words cword prev 1261 1262 local command='west' command_pos=0 1263 local counter=1 1264 while [ "$counter" -lt "$cword" ]; do 1265 case "${words[$counter]}" in 1266 west) 1267 return 0 1268 ;; 1269 $(__west_to_extglob "$global_args_opts") ) 1270 (( counter++ )) 1271 ;; 1272 -*) 1273 ;; 1274 =) 1275 (( counter++ )) 1276 ;; 1277 *) 1278 command="${words[$counter]}" 1279 command_pos=$counter 1280 break 1281 ;; 1282 esac 1283 (( counter++ )) 1284 done 1285 1286 1287 # Construct the function name to be called 1288 local completions_func=__comp_west_${command//-/_} 1289 #echo "comp_func: ${completions_func}" 1290 declare -F $completions_func >/dev/null && $completions_func 1291 1292 # Restore the user's extglob setting 1293 eval "$previous_extglob_setting" 1294 return 0 1295} 1296 1297eval "$__west_previous_extglob_setting" 1298unset __west_previous_extglob_setting 1299 1300complete -F __comp_west west 1301