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 --skip-rebuild 846 " 847 848 local dir_opts=" 849 --board-dir 850 --openocd-search 851 --build-dir -d 852 " 853 854 local file_opts=" 855 --file -f 856 --file-type -t 857 --elf-file 858 --hex-file 859 --bin-file 860 --gdb 861 --openocd 862 " 863 864 local other_opts=" 865 --runner -r 866 --domain 867 --dev-id -i 868 " 869 870 all_opts="$bool_opts $other_opts $dir_opts $file_opts" 871 872 case "$prev" in 873 $(__west_to_extglob "$dir_opts") ) 874 __set_comp_dirs 875 return 876 ;; 877 $(__west_to_extglob "$file_opts") ) 878 __set_comp_files 879 return 880 ;; 881 esac 882 883 case "$cur" in 884 -*) 885 __set_comp $all_opts 886 ;; 887 esac 888} 889 890__comp_west_flash() 891{ 892 __comp_west_runner_cmd 893} 894 895__comp_west_debug() 896{ 897 __comp_west_runner_cmd 898} 899 900__comp_west_debugserver() 901{ 902 __comp_west_runner_cmd 903} 904 905__comp_west_attach() 906{ 907 __comp_west_runner_cmd 908} 909 910__comp_west_spdx() 911{ 912 local bool_opts=" 913 --init -i 914 --analyze-includes 915 --include-sdk 916 " 917 918 local dir_opts=" 919 --build-dir -d 920 --namespace-prefix -n 921 --spdx-dir -s 922 " 923 924 local other_opts=" 925 --namespace-prefix -n 926 " 927 928 all_opts="$bool_opts $other_opts $dir_opts" 929 930 case "$prev" in 931 $(__west_to_extglob "$dir_opts") ) 932 __set_comp_dirs 933 return 934 ;; 935 936 # We don't know how to autocomplete those 937 $(__west_to_extglob "$other_opts") ) 938 return 939 ;; 940 esac 941 942 case "$cur" in 943 -*) 944 __set_comp $all_opts 945 ;; 946 esac 947} 948 949__comp_west_blobs() 950{ 951 local other_opts=" 952 --format -f 953 " 954 955 case "$prev" in 956 # We don't know how to autocomplete those 957 $(__west_to_extglob "$other_opts") ) 958 return 959 ;; 960 blobs) 961 __set_comp "list fetch clean" 962 return 963 ;; 964 esac 965 966 case "$cur" in 967 -*) 968 __set_comp $other_opts 969 ;; 970 *) 971 __set_comp_west_projs 972 ;; 973 esac 974} 975 976__comp_west_twister() 977{ 978 local bool_opts=" 979 --aggressive-no-clean 980 --all -l 981 --all-deltas -D 982 --allow-installed-plugin 983 --build-only -b 984 --clobber-output -c 985 --cmake-only 986 --coverage -C 987 --create-rom-ram-report 988 --detailed-skipped-report 989 --detailed-test-id 990 --device-flash-with-test 991 --device-testing 992 --disable-suite-name-check 993 --disable-unrecognized-section-test 994 --disable-warnings-as-errors -W 995 --dry-run -y 996 --emulation-only 997 --enable-asan 998 --enable-coverage 999 --enable-lsan 1000 --enable-size-report 1001 --enable-slow -S 1002 --enable-slow-only 1003 --enable-ubsan 1004 --enable-valgrind 1005 --flash-before 1006 --footprint-from-buildlog 1007 --force-color 1008 --force-platform -K 1009 --force-toolchain 1010 --ignore-platform-key 1011 --inline-logs -i 1012 --integration -G 1013 --last-metrics -m 1014 --list-tags 1015 --list-tests 1016 --make -k 1017 --ninja -N 1018 --no-clean -n 1019 --no-detailed-test-id 1020 --no-update -u 1021 --only-failed -f 1022 --overflow-as-errors 1023 --persistent-hardware-map 1024 --platform-reports 1025 --prep-artifacts-for-testing 1026 --quarantine-verify 1027 --retry-build-errors 1028 --short-build-path 1029 --show-footprint 1030 --shuffle-tests 1031 --test-only 1032 --test-tree 1033 --timestamps 1034 --verbose -v 1035 " 1036 1037 local dir_opts=" 1038 --alt-config-root 1039 --board-root -A 1040 --coverage-basedir 1041 --outdir -O 1042 --report-dir -o 1043 --testsuite-root -T 1044 " 1045 1046 local file_opts=" 1047 --compare-report 1048 --device-serial 1049 --device-serial-pty 1050 --gcov-tool 1051 --generate-hardware-map 1052 --hardware-map 1053 --load-tests -F 1054 --log-file 1055 --package-artifacts 1056 --pre-script 1057 --quarantine-list 1058 --save-tests -E 1059 --size -z 1060 --test-config 1061 " 1062 1063 local special_opts=" 1064 --coverage-platform 1065 --coverage-tool 1066 --exclude-platform -P 1067 --filter 1068 --log-level 1069 --platform -p 1070 --runtime-artifact-cleanup -M 1071 " 1072 1073 local other_opts=" 1074 --arch -a 1075 --coverage-formats 1076 --device-flash-timeout 1077 --device-serial-baud 1078 --exclude-tag -e 1079 --extra-args -x 1080 --fixture -X 1081 --footprint-threshold -H 1082 --jobs -j 1083 --level 1084 --pytest-args 1085 --report-name 1086 --report-suffix 1087 --retry-failed 1088 --retry-interval 1089 --scenario --test -s 1090 --seed 1091 --shuffle-tests-seed 1092 --sub-test 1093 --subset -B 1094 --tag -t 1095 --timeout-multiplier 1096 --vendor 1097 --west-flash 1098 --west-runner 1099 " 1100 1101 all_opts="$bool_opts $dir_opts $file_opts $special_opts $other_opts" 1102 1103 case "$prev" in 1104 --platform|-p|--exclude-platform|-P|--coverage-platform) 1105 __set_comp_west_boards 1106 return 1107 ;; 1108 1109 --coverage-tool) 1110 __set_comp "gcovr lcov" 1111 return 1112 ;; 1113 1114 --filter) 1115 __set_comp "buildable runnable" 1116 return 1117 ;; 1118 1119 --log-level) 1120 __set_comp "CRITICAL DEBUG ERROR INFO NOTSET WARNING" 1121 return 1122 ;; 1123 1124 --runtime-artifact-cleanup|-M) 1125 __set_comp "all pass" 1126 return 1127 ;; 1128 1129 $(__west_to_extglob "$dir_opts") ) 1130 __set_comp_dirs 1131 return 1132 ;; 1133 1134 $(__west_to_extglob "$file_opts") ) 1135 __set_comp_files 1136 return 1137 ;; 1138 1139 # We don't know how to autocomplete those 1140 $(__west_to_extglob "$other_opts") ) 1141 return 1142 ;; 1143 esac 1144 1145 case "$cur" in 1146 -*) 1147 __set_comp $all_opts 1148 ;; 1149 esac 1150} 1151 1152__comp_west_sdk() 1153{ 1154 local bool_opts=" 1155 --interactive -i 1156 --no-toolchains -T 1157 --no-hosttools -H 1158 " 1159 1160 local dir_opts=" 1161 --install-dir -d 1162 --install-base -b 1163 " 1164 1165 local other_opts=" 1166 --version 1167 --toolchains -t 1168 --personal-access-token 1169 --api-url 1170 " 1171 1172 all_opts="$bool_opts $dir_opts $other_opts" 1173 1174 case "$prev" in 1175 sdk) 1176 __set_comp "list install" 1177 return 1178 ;; 1179 list) 1180 return 1181 ;; 1182 $(__west_to_extglob "$dir_opts") ) 1183 __set_comp_dirs 1184 return 1185 ;; 1186 # We don't know how to autocomplete those 1187 $(__west_to_extglob "$other_opts") ) 1188 return 1189 ;; 1190 esac 1191 1192 case "$cur" in 1193 -*) 1194 __set_comp $all_opts 1195 ;; 1196 esac 1197} 1198 1199__comp_west() 1200{ 1201 local previous_extglob_setting=$(shopt -p extglob) 1202 shopt -s extglob 1203 # Reset to default, to make sure compgen works properly 1204 local IFS=$' \t\n' 1205 1206 local builtin_cmds=( 1207 init 1208 update 1209 list 1210 manifest 1211 diff 1212 status 1213 forall 1214 config 1215 topdir 1216 help 1217 ) 1218 1219 local zephyr_ext_cmds=( 1220 completion 1221 boards 1222 shields 1223 build 1224 sign 1225 flash 1226 debug 1227 debugserver 1228 attach 1229 zephyr-export 1230 spdx 1231 blobs 1232 twister 1233 sdk 1234 ) 1235 1236 local cmds=(${builtin_cmds[*]} ${zephyr_ext_cmds[*]}) 1237 1238 # Global options for all commands 1239 local global_bool_opts=" 1240 --help -h 1241 --verbose -v 1242 --version -V 1243 " 1244 local global_args_opts=" 1245 --zephyr-base -z 1246 " 1247 1248 COMPREPLY=() 1249 local cur words cword prev 1250 _get_comp_words_by_ref -n : cur words cword prev 1251 1252 local command='west' command_pos=0 1253 local counter=1 1254 while [ "$counter" -lt "$cword" ]; do 1255 case "${words[$counter]}" in 1256 west) 1257 return 0 1258 ;; 1259 $(__west_to_extglob "$global_args_opts") ) 1260 (( counter++ )) 1261 ;; 1262 -*) 1263 ;; 1264 =) 1265 (( counter++ )) 1266 ;; 1267 *) 1268 command="${words[$counter]}" 1269 command_pos=$counter 1270 break 1271 ;; 1272 esac 1273 (( counter++ )) 1274 done 1275 1276 1277 # Construct the function name to be called 1278 local completions_func=__comp_west_${command//-/_} 1279 #echo "comp_func: ${completions_func}" 1280 declare -F $completions_func >/dev/null && $completions_func 1281 1282 # Restore the user's extglob setting 1283 eval "$previous_extglob_setting" 1284 return 0 1285} 1286 1287eval "$__west_previous_extglob_setting" 1288unset __west_previous_extglob_setting 1289 1290complete -F __comp_west west 1291