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