18c2ecf20Sopenharmony_ci# perf bash and zsh completion 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci# Taken from git.git's completion script. 58c2ecf20Sopenharmony_ci__my_reassemble_comp_words_by_ref() 68c2ecf20Sopenharmony_ci{ 78c2ecf20Sopenharmony_ci local exclude i j first 88c2ecf20Sopenharmony_ci # Which word separators to exclude? 98c2ecf20Sopenharmony_ci exclude="${1//[^$COMP_WORDBREAKS]}" 108c2ecf20Sopenharmony_ci cword_=$COMP_CWORD 118c2ecf20Sopenharmony_ci if [ -z "$exclude" ]; then 128c2ecf20Sopenharmony_ci words_=("${COMP_WORDS[@]}") 138c2ecf20Sopenharmony_ci return 148c2ecf20Sopenharmony_ci fi 158c2ecf20Sopenharmony_ci # List of word completion separators has shrunk; 168c2ecf20Sopenharmony_ci # re-assemble words to complete. 178c2ecf20Sopenharmony_ci for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do 188c2ecf20Sopenharmony_ci # Append each nonempty word consisting of just 198c2ecf20Sopenharmony_ci # word separator characters to the current word. 208c2ecf20Sopenharmony_ci first=t 218c2ecf20Sopenharmony_ci while 228c2ecf20Sopenharmony_ci [ $i -gt 0 ] && 238c2ecf20Sopenharmony_ci [ -n "${COMP_WORDS[$i]}" ] && 248c2ecf20Sopenharmony_ci # word consists of excluded word separators 258c2ecf20Sopenharmony_ci [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] 268c2ecf20Sopenharmony_ci do 278c2ecf20Sopenharmony_ci # Attach to the previous token, 288c2ecf20Sopenharmony_ci # unless the previous token is the command name. 298c2ecf20Sopenharmony_ci if [ $j -ge 2 ] && [ -n "$first" ]; then 308c2ecf20Sopenharmony_ci ((j--)) 318c2ecf20Sopenharmony_ci fi 328c2ecf20Sopenharmony_ci first= 338c2ecf20Sopenharmony_ci words_[$j]=${words_[j]}${COMP_WORDS[i]} 348c2ecf20Sopenharmony_ci if [ $i = $COMP_CWORD ]; then 358c2ecf20Sopenharmony_ci cword_=$j 368c2ecf20Sopenharmony_ci fi 378c2ecf20Sopenharmony_ci if (($i < ${#COMP_WORDS[@]} - 1)); then 388c2ecf20Sopenharmony_ci ((i++)) 398c2ecf20Sopenharmony_ci else 408c2ecf20Sopenharmony_ci # Done. 418c2ecf20Sopenharmony_ci return 428c2ecf20Sopenharmony_ci fi 438c2ecf20Sopenharmony_ci done 448c2ecf20Sopenharmony_ci words_[$j]=${words_[j]}${COMP_WORDS[i]} 458c2ecf20Sopenharmony_ci if [ $i = $COMP_CWORD ]; then 468c2ecf20Sopenharmony_ci cword_=$j 478c2ecf20Sopenharmony_ci fi 488c2ecf20Sopenharmony_ci done 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci# Define preload_get_comp_words_by_ref="false", if the function 528c2ecf20Sopenharmony_ci# __perf_get_comp_words_by_ref() is required instead. 538c2ecf20Sopenharmony_cipreload_get_comp_words_by_ref="true" 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciif [ $preload_get_comp_words_by_ref = "true" ]; then 568c2ecf20Sopenharmony_ci type _get_comp_words_by_ref &>/dev/null || 578c2ecf20Sopenharmony_ci preload_get_comp_words_by_ref="false" 588c2ecf20Sopenharmony_cifi 598c2ecf20Sopenharmony_ci[ $preload_get_comp_words_by_ref = "true" ] || 608c2ecf20Sopenharmony_ci__perf_get_comp_words_by_ref() 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci local exclude cur_ words_ cword_ 638c2ecf20Sopenharmony_ci if [ "$1" = "-n" ]; then 648c2ecf20Sopenharmony_ci exclude=$2 658c2ecf20Sopenharmony_ci shift 2 668c2ecf20Sopenharmony_ci fi 678c2ecf20Sopenharmony_ci __my_reassemble_comp_words_by_ref "$exclude" 688c2ecf20Sopenharmony_ci cur_=${words_[cword_]} 698c2ecf20Sopenharmony_ci while [ $# -gt 0 ]; do 708c2ecf20Sopenharmony_ci case "$1" in 718c2ecf20Sopenharmony_ci cur) 728c2ecf20Sopenharmony_ci cur=$cur_ 738c2ecf20Sopenharmony_ci ;; 748c2ecf20Sopenharmony_ci prev) 758c2ecf20Sopenharmony_ci prev=${words_[$cword_-1]} 768c2ecf20Sopenharmony_ci ;; 778c2ecf20Sopenharmony_ci words) 788c2ecf20Sopenharmony_ci words=("${words_[@]}") 798c2ecf20Sopenharmony_ci ;; 808c2ecf20Sopenharmony_ci cword) 818c2ecf20Sopenharmony_ci cword=$cword_ 828c2ecf20Sopenharmony_ci ;; 838c2ecf20Sopenharmony_ci esac 848c2ecf20Sopenharmony_ci shift 858c2ecf20Sopenharmony_ci done 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci# Define preload__ltrim_colon_completions="false", if the function 898c2ecf20Sopenharmony_ci# __perf__ltrim_colon_completions() is required instead. 908c2ecf20Sopenharmony_cipreload__ltrim_colon_completions="true" 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ciif [ $preload__ltrim_colon_completions = "true" ]; then 938c2ecf20Sopenharmony_ci type __ltrim_colon_completions &>/dev/null || 948c2ecf20Sopenharmony_ci preload__ltrim_colon_completions="false" 958c2ecf20Sopenharmony_cifi 968c2ecf20Sopenharmony_ci[ $preload__ltrim_colon_completions = "true" ] || 978c2ecf20Sopenharmony_ci__perf__ltrim_colon_completions() 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then 1008c2ecf20Sopenharmony_ci # Remove colon-word prefix from COMPREPLY items 1018c2ecf20Sopenharmony_ci local colon_word=${1%"${1##*:}"} 1028c2ecf20Sopenharmony_ci local i=${#COMPREPLY[*]} 1038c2ecf20Sopenharmony_ci while [[ $((--i)) -ge 0 ]]; do 1048c2ecf20Sopenharmony_ci COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} 1058c2ecf20Sopenharmony_ci done 1068c2ecf20Sopenharmony_ci fi 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci__perfcomp () 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci__perfcomp_colon () 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci __perfcomp "$1" "$2" 1178c2ecf20Sopenharmony_ci if [ $preload__ltrim_colon_completions = "true" ]; then 1188c2ecf20Sopenharmony_ci __ltrim_colon_completions $cur 1198c2ecf20Sopenharmony_ci else 1208c2ecf20Sopenharmony_ci __perf__ltrim_colon_completions $cur 1218c2ecf20Sopenharmony_ci fi 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci__perf_prev_skip_opts () 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci local i cmd_ cmds_ 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci let i=cword-1 1298c2ecf20Sopenharmony_ci cmds_=$($cmd $1 --list-cmds) 1308c2ecf20Sopenharmony_ci prev_skip_opts=() 1318c2ecf20Sopenharmony_ci while [ $i -ge 0 ]; do 1328c2ecf20Sopenharmony_ci if [[ ${words[i]} == $1 ]]; then 1338c2ecf20Sopenharmony_ci return 1348c2ecf20Sopenharmony_ci fi 1358c2ecf20Sopenharmony_ci for cmd_ in $cmds_; do 1368c2ecf20Sopenharmony_ci if [[ ${words[i]} == $cmd_ ]]; then 1378c2ecf20Sopenharmony_ci prev_skip_opts=${words[i]} 1388c2ecf20Sopenharmony_ci return 1398c2ecf20Sopenharmony_ci fi 1408c2ecf20Sopenharmony_ci done 1418c2ecf20Sopenharmony_ci ((i--)) 1428c2ecf20Sopenharmony_ci done 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci__perf_main () 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci local cmd 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci cmd=${words[0]} 1508c2ecf20Sopenharmony_ci COMPREPLY=() 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci # Skip options backward and find the last perf command 1538c2ecf20Sopenharmony_ci __perf_prev_skip_opts 1548c2ecf20Sopenharmony_ci # List perf subcommands or long options 1558c2ecf20Sopenharmony_ci if [ -z $prev_skip_opts ]; then 1568c2ecf20Sopenharmony_ci if [[ $cur == --* ]]; then 1578c2ecf20Sopenharmony_ci cmds=$($cmd --list-opts) 1588c2ecf20Sopenharmony_ci else 1598c2ecf20Sopenharmony_ci cmds=$($cmd --list-cmds) 1608c2ecf20Sopenharmony_ci fi 1618c2ecf20Sopenharmony_ci __perfcomp "$cmds" "$cur" 1628c2ecf20Sopenharmony_ci # List possible events for -e option 1638c2ecf20Sopenharmony_ci elif [[ $prev == @("-e"|"--event") && 1648c2ecf20Sopenharmony_ci $prev_skip_opts == @(record|stat|top) ]]; then 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci local cur1=${COMP_WORDS[COMP_CWORD]} 1678c2ecf20Sopenharmony_ci local raw_evts=$($cmd list --raw-dump) 1688c2ecf20Sopenharmony_ci local arr s tmp result cpu_evts 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci # aarch64 doesn't have /sys/bus/event_source/devices/cpu/events 1718c2ecf20Sopenharmony_ci if [[ `uname -m` != aarch64 ]]; then 1728c2ecf20Sopenharmony_ci cpu_evts=$(ls /sys/bus/event_source/devices/cpu/events) 1738c2ecf20Sopenharmony_ci fi 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci if [[ "$cur1" == */* && ${cur1#*/} =~ ^[A-Z] ]]; then 1768c2ecf20Sopenharmony_ci OLD_IFS="$IFS" 1778c2ecf20Sopenharmony_ci IFS=" " 1788c2ecf20Sopenharmony_ci arr=($raw_evts) 1798c2ecf20Sopenharmony_ci IFS="$OLD_IFS" 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci for s in ${arr[@]} 1828c2ecf20Sopenharmony_ci do 1838c2ecf20Sopenharmony_ci if [[ "$s" == *cpu/* ]]; then 1848c2ecf20Sopenharmony_ci tmp=${s#*cpu/} 1858c2ecf20Sopenharmony_ci result=$result" ""cpu/"${tmp^^} 1868c2ecf20Sopenharmony_ci else 1878c2ecf20Sopenharmony_ci result=$result" "$s 1888c2ecf20Sopenharmony_ci fi 1898c2ecf20Sopenharmony_ci done 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci evts=${result}" "${cpu_evts} 1928c2ecf20Sopenharmony_ci else 1938c2ecf20Sopenharmony_ci evts=${raw_evts}" "${cpu_evts} 1948c2ecf20Sopenharmony_ci fi 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci if [[ "$cur1" == , ]]; then 1978c2ecf20Sopenharmony_ci __perfcomp_colon "$evts" "" 1988c2ecf20Sopenharmony_ci else 1998c2ecf20Sopenharmony_ci __perfcomp_colon "$evts" "$cur1" 2008c2ecf20Sopenharmony_ci fi 2018c2ecf20Sopenharmony_ci else 2028c2ecf20Sopenharmony_ci # List subcommands for perf commands 2038c2ecf20Sopenharmony_ci if [[ $prev_skip_opts == @(kvm|kmem|mem|lock|sched| 2048c2ecf20Sopenharmony_ci |data|help|script|test|timechart|trace) ]]; then 2058c2ecf20Sopenharmony_ci subcmds=$($cmd $prev_skip_opts --list-cmds) 2068c2ecf20Sopenharmony_ci __perfcomp_colon "$subcmds" "$cur" 2078c2ecf20Sopenharmony_ci fi 2088c2ecf20Sopenharmony_ci # List long option names 2098c2ecf20Sopenharmony_ci if [[ $cur == --* ]]; then 2108c2ecf20Sopenharmony_ci subcmd=$prev_skip_opts 2118c2ecf20Sopenharmony_ci __perf_prev_skip_opts $subcmd 2128c2ecf20Sopenharmony_ci subcmd=$subcmd" "$prev_skip_opts 2138c2ecf20Sopenharmony_ci opts=$($cmd $subcmd --list-opts) 2148c2ecf20Sopenharmony_ci __perfcomp "$opts" "$cur" 2158c2ecf20Sopenharmony_ci fi 2168c2ecf20Sopenharmony_ci fi 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ciif [[ -n ${ZSH_VERSION-} ]]; then 2208c2ecf20Sopenharmony_ci autoload -U +X compinit && compinit 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci __perfcomp () 2238c2ecf20Sopenharmony_ci { 2248c2ecf20Sopenharmony_ci emulate -L zsh 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci local c IFS=$' \t\n' 2278c2ecf20Sopenharmony_ci local -a array 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci for c in ${=1}; do 2308c2ecf20Sopenharmony_ci case $c in 2318c2ecf20Sopenharmony_ci --*=*|*.) ;; 2328c2ecf20Sopenharmony_ci *) c="$c " ;; 2338c2ecf20Sopenharmony_ci esac 2348c2ecf20Sopenharmony_ci array[${#array[@]}+1]="$c" 2358c2ecf20Sopenharmony_ci done 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci compset -P '*[=:]' 2388c2ecf20Sopenharmony_ci compadd -Q -S '' -a -- array && _ret=0 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci __perfcomp_colon () 2428c2ecf20Sopenharmony_ci { 2438c2ecf20Sopenharmony_ci emulate -L zsh 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci local cur_="${2-$cur}" 2468c2ecf20Sopenharmony_ci local c IFS=$' \t\n' 2478c2ecf20Sopenharmony_ci local -a array 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci if [[ "$cur_" == *:* ]]; then 2508c2ecf20Sopenharmony_ci local colon_word=${cur_%"${cur_##*:}"} 2518c2ecf20Sopenharmony_ci fi 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci for c in ${=1}; do 2548c2ecf20Sopenharmony_ci case $c in 2558c2ecf20Sopenharmony_ci --*=*|*.) ;; 2568c2ecf20Sopenharmony_ci *) c="$c " ;; 2578c2ecf20Sopenharmony_ci esac 2588c2ecf20Sopenharmony_ci array[$#array+1]=${c#"$colon_word"} 2598c2ecf20Sopenharmony_ci done 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci compset -P '*[=:]' 2628c2ecf20Sopenharmony_ci compadd -Q -S '' -a -- array && _ret=0 2638c2ecf20Sopenharmony_ci } 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci _perf () 2668c2ecf20Sopenharmony_ci { 2678c2ecf20Sopenharmony_ci local _ret=1 cur cword prev 2688c2ecf20Sopenharmony_ci cur=${words[CURRENT]} 2698c2ecf20Sopenharmony_ci prev=${words[CURRENT-1]} 2708c2ecf20Sopenharmony_ci let cword=CURRENT-1 2718c2ecf20Sopenharmony_ci emulate ksh -c __perf_main 2728c2ecf20Sopenharmony_ci let _ret && _default && _ret=0 2738c2ecf20Sopenharmony_ci return _ret 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci compdef _perf perf 2778c2ecf20Sopenharmony_ci return 2788c2ecf20Sopenharmony_cifi 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_citype perf &>/dev/null && 2818c2ecf20Sopenharmony_ci_perf() 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci if [[ "$COMP_WORDBREAKS" != *,* ]]; then 2848c2ecf20Sopenharmony_ci COMP_WORDBREAKS="${COMP_WORDBREAKS}," 2858c2ecf20Sopenharmony_ci export COMP_WORDBREAKS 2868c2ecf20Sopenharmony_ci fi 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci if [[ "$COMP_WORDBREAKS" == *:* ]]; then 2898c2ecf20Sopenharmony_ci COMP_WORDBREAKS="${COMP_WORDBREAKS/:/}" 2908c2ecf20Sopenharmony_ci export COMP_WORDBREAKS 2918c2ecf20Sopenharmony_ci fi 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci local cur words cword prev 2948c2ecf20Sopenharmony_ci if [ $preload_get_comp_words_by_ref = "true" ]; then 2958c2ecf20Sopenharmony_ci _get_comp_words_by_ref -n =:, cur words cword prev 2968c2ecf20Sopenharmony_ci else 2978c2ecf20Sopenharmony_ci __perf_get_comp_words_by_ref -n =:, cur words cword prev 2988c2ecf20Sopenharmony_ci fi 2998c2ecf20Sopenharmony_ci __perf_main 3008c2ecf20Sopenharmony_ci} && 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cicomplete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \ 3038c2ecf20Sopenharmony_ci || complete -o default -o nospace -F _perf perf 304