1 # perf bash and zsh completion 1 # perf bash and zsh completion 2 # SPDX-License-Identifier: GPL-2.0 << 3 2 4 # Taken from git.git's completion script. 3 # Taken from git.git's completion script. 5 __my_reassemble_comp_words_by_ref() 4 __my_reassemble_comp_words_by_ref() 6 { 5 { 7 local exclude i j first 6 local exclude i j first 8 # Which word separators to exclude? 7 # Which word separators to exclude? 9 exclude="${1//[^$COMP_WORDBREAKS]}" 8 exclude="${1//[^$COMP_WORDBREAKS]}" 10 cword_=$COMP_CWORD 9 cword_=$COMP_CWORD 11 if [ -z "$exclude" ]; then 10 if [ -z "$exclude" ]; then 12 words_=("${COMP_WORDS[@]}") 11 words_=("${COMP_WORDS[@]}") 13 return 12 return 14 fi 13 fi 15 # List of word completion separators h 14 # List of word completion separators has shrunk; 16 # re-assemble words to complete. 15 # re-assemble words to complete. 17 for ((i=0, j=0; i < ${#COMP_WORDS[@]}; 16 for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do 18 # Append each nonempty word co 17 # Append each nonempty word consisting of just 19 # word separator characters to 18 # word separator characters to the current word. 20 first=t 19 first=t 21 while 20 while 22 [ $i -gt 0 ] && 21 [ $i -gt 0 ] && 23 [ -n "${COMP_WORDS[$i] 22 [ -n "${COMP_WORDS[$i]}" ] && 24 # word consists of exc 23 # word consists of excluded word separators 25 [ "${COMP_WORDS[$i]//[ 24 [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] 26 do 25 do 27 # Attach to the previo 26 # Attach to the previous token, 28 # unless the previous 27 # unless the previous token is the command name. 29 if [ $j -ge 2 ] && [ - 28 if [ $j -ge 2 ] && [ -n "$first" ]; then 30 ((j--)) 29 ((j--)) 31 fi 30 fi 32 first= 31 first= 33 words_[$j]=${words_[j] 32 words_[$j]=${words_[j]}${COMP_WORDS[i]} 34 if [ $i = $COMP_CWORD 33 if [ $i = $COMP_CWORD ]; then 35 cword_=$j 34 cword_=$j 36 fi 35 fi 37 if (($i < ${#COMP_WORD 36 if (($i < ${#COMP_WORDS[@]} - 1)); then 38 ((i++)) 37 ((i++)) 39 else 38 else 40 # Done. 39 # Done. 41 return 40 return 42 fi 41 fi 43 done 42 done 44 words_[$j]=${words_[j]}${COMP_ 43 words_[$j]=${words_[j]}${COMP_WORDS[i]} 45 if [ $i = $COMP_CWORD ]; then 44 if [ $i = $COMP_CWORD ]; then 46 cword_=$j 45 cword_=$j 47 fi 46 fi 48 done 47 done 49 } 48 } 50 49 51 # Define preload_get_comp_words_by_ref="false" 50 # Define preload_get_comp_words_by_ref="false", if the function 52 # __perf_get_comp_words_by_ref() is required i 51 # __perf_get_comp_words_by_ref() is required instead. 53 preload_get_comp_words_by_ref="true" 52 preload_get_comp_words_by_ref="true" 54 53 55 if [ $preload_get_comp_words_by_ref = "true" ] 54 if [ $preload_get_comp_words_by_ref = "true" ]; then 56 type _get_comp_words_by_ref &>/dev/nul 55 type _get_comp_words_by_ref &>/dev/null || 57 preload_get_comp_words_by_ref="false" 56 preload_get_comp_words_by_ref="false" 58 fi 57 fi 59 [ $preload_get_comp_words_by_ref = "true" ] || 58 [ $preload_get_comp_words_by_ref = "true" ] || 60 __perf_get_comp_words_by_ref() 59 __perf_get_comp_words_by_ref() 61 { 60 { 62 local exclude cur_ words_ cword_ 61 local exclude cur_ words_ cword_ 63 if [ "$1" = "-n" ]; then 62 if [ "$1" = "-n" ]; then 64 exclude=$2 63 exclude=$2 65 shift 2 64 shift 2 66 fi 65 fi 67 __my_reassemble_comp_words_by_ref "$ex 66 __my_reassemble_comp_words_by_ref "$exclude" 68 cur_=${words_[cword_]} 67 cur_=${words_[cword_]} 69 while [ $# -gt 0 ]; do 68 while [ $# -gt 0 ]; do 70 case "$1" in 69 case "$1" in 71 cur) 70 cur) 72 cur=$cur_ 71 cur=$cur_ 73 ;; 72 ;; 74 prev) 73 prev) 75 prev=${words_[$cword_- 74 prev=${words_[$cword_-1]} 76 ;; 75 ;; 77 words) 76 words) 78 words=("${words_[@]}") 77 words=("${words_[@]}") 79 ;; 78 ;; 80 cword) 79 cword) 81 cword=$cword_ 80 cword=$cword_ 82 ;; 81 ;; 83 esac 82 esac 84 shift 83 shift 85 done 84 done 86 } 85 } 87 86 88 # Define preload__ltrim_colon_completions="fal 87 # Define preload__ltrim_colon_completions="false", if the function 89 # __perf__ltrim_colon_completions() is require 88 # __perf__ltrim_colon_completions() is required instead. 90 preload__ltrim_colon_completions="true" 89 preload__ltrim_colon_completions="true" 91 90 92 if [ $preload__ltrim_colon_completions = "true 91 if [ $preload__ltrim_colon_completions = "true" ]; then 93 type __ltrim_colon_completions &>/dev/ 92 type __ltrim_colon_completions &>/dev/null || 94 preload__ltrim_colon_completions="fals 93 preload__ltrim_colon_completions="false" 95 fi 94 fi 96 [ $preload__ltrim_colon_completions = "true" ] 95 [ $preload__ltrim_colon_completions = "true" ] || 97 __perf__ltrim_colon_completions() 96 __perf__ltrim_colon_completions() 98 { 97 { 99 if [[ "$1" == *:* && "$COMP_WORDBREAKS 98 if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then 100 # Remove colon-word prefix fro 99 # Remove colon-word prefix from COMPREPLY items 101 local colon_word=${1%"${1##*:} 100 local colon_word=${1%"${1##*:}"} 102 local i=${#COMPREPLY[*]} 101 local i=${#COMPREPLY[*]} 103 while [[ $((--i)) -ge 0 ]]; do 102 while [[ $((--i)) -ge 0 ]]; do 104 COMPREPLY[$i]=${COMPRE 103 COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} 105 done 104 done 106 fi 105 fi 107 } 106 } 108 107 109 __perfcomp () 108 __perfcomp () 110 { 109 { 111 # Expansion of spaces to array is deli << 112 # shellcheck disable=SC2207 << 113 COMPREPLY=( $( compgen -W "$1" -- "$2" 110 COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) 114 } 111 } 115 112 116 __perfcomp_colon () 113 __perfcomp_colon () 117 { 114 { 118 __perfcomp "$1" "$2" 115 __perfcomp "$1" "$2" 119 if [ $preload__ltrim_colon_completions 116 if [ $preload__ltrim_colon_completions = "true" ]; then 120 __ltrim_colon_completions $cur 117 __ltrim_colon_completions $cur 121 else 118 else 122 __perf__ltrim_colon_completion 119 __perf__ltrim_colon_completions $cur 123 fi 120 fi 124 } 121 } 125 122 126 __perf_prev_skip_opts () 123 __perf_prev_skip_opts () 127 { 124 { 128 local i cmd_ cmds_ 125 local i cmd_ cmds_ 129 126 130 let i=cword-1 127 let i=cword-1 131 cmds_=$($cmd $1 --list-cmds) 128 cmds_=$($cmd $1 --list-cmds) 132 prev_skip_opts="" !! 129 prev_skip_opts=() 133 while [ $i -ge 0 ]; do 130 while [ $i -ge 0 ]; do 134 if [[ ${words[i]} == "$1" ]]; !! 131 if [[ ${words[i]} == $1 ]]; then 135 return 132 return 136 fi 133 fi 137 for cmd_ in $cmds_; do 134 for cmd_ in $cmds_; do 138 if [[ ${words[i]} == " !! 135 if [[ ${words[i]} == $cmd_ ]]; then 139 prev_skip_opts 136 prev_skip_opts=${words[i]} 140 return 137 return 141 fi 138 fi 142 done 139 done 143 ((i--)) 140 ((i--)) 144 done 141 done 145 } 142 } 146 143 147 __perf_main () 144 __perf_main () 148 { 145 { 149 local cmd 146 local cmd 150 147 151 cmd=${words[0]} 148 cmd=${words[0]} 152 COMPREPLY=() 149 COMPREPLY=() 153 150 154 # Skip options backward and find the l 151 # Skip options backward and find the last perf command 155 __perf_prev_skip_opts 152 __perf_prev_skip_opts 156 # List perf subcommands or long option 153 # List perf subcommands or long options 157 if [ -z $prev_skip_opts ]; then 154 if [ -z $prev_skip_opts ]; then 158 if [[ $cur == --* ]]; then 155 if [[ $cur == --* ]]; then 159 cmds=$($cmd --list-opt 156 cmds=$($cmd --list-opts) 160 else 157 else 161 cmds=$($cmd --list-cmd 158 cmds=$($cmd --list-cmds) 162 fi 159 fi 163 __perfcomp "$cmds" "$cur" 160 __perfcomp "$cmds" "$cur" 164 # List possible events for -e option 161 # List possible events for -e option 165 elif [[ $prev == @("-e"|"--event") && 162 elif [[ $prev == @("-e"|"--event") && 166 $prev_skip_opts == @(record|st 163 $prev_skip_opts == @(record|stat|top) ]]; then 167 !! 164 evts=$($cmd list --raw-dump) 168 local cur1=${COMP_WORDS[COMP_C !! 165 __perfcomp_colon "$evts" "$cur" 169 local raw_evts << 170 local arr s tmp result cpu_evt << 171 << 172 raw_evts=$($cmd list --raw-dum << 173 # aarch64 doesn't have /sys/bu << 174 if [[ `uname -m` != aarch64 ]] << 175 cpu_evts=$(ls /sys/bus << 176 fi << 177 << 178 if [[ "$cur1" == */* && ${cur1 << 179 OLD_IFS="$IFS" << 180 IFS=" " << 181 # Expansion of spaces << 182 # shellcheck disable=S << 183 arr=($raw_evts) << 184 IFS="$OLD_IFS" << 185 << 186 for s in "${arr[@]}" << 187 do << 188 if [[ "$s" == << 189 tmp=${ << 190 result << 191 else << 192 result << 193 fi << 194 done << 195 << 196 evts=${result}" "${cpu << 197 else << 198 evts=${raw_evts}" "${c << 199 fi << 200 << 201 if [[ "$cur1" == , ]]; then << 202 __perfcomp_colon "$evt << 203 else << 204 __perfcomp_colon "$evt << 205 fi << 206 elif [[ $prev == @("--pfm-events") && << 207 $prev_skip_opts == @(record|st << 208 local evts << 209 evts=$($cmd list --raw-dump pf << 210 __perfcomp "$evts" "$cur" << 211 elif [[ $prev == @("-M"|"--metrics") & << 212 $prev_skip_opts == @(stat) ]]; << 213 local metrics << 214 metrics=$($cmd list --raw-dump << 215 __perfcomp "$metrics" "$cur" << 216 else 166 else 217 # List subcommands for perf co 167 # List subcommands for perf commands 218 if [[ $prev_skip_opts == @(kvm 168 if [[ $prev_skip_opts == @(kvm|kmem|mem|lock|sched| 219 |data|help|script|test 169 |data|help|script|test|timechart|trace) ]]; then 220 subcmds=$($cmd $prev_s 170 subcmds=$($cmd $prev_skip_opts --list-cmds) 221 __perfcomp_colon "$sub 171 __perfcomp_colon "$subcmds" "$cur" 222 fi 172 fi 223 # List long option names 173 # List long option names 224 if [[ $cur == --* ]]; then 174 if [[ $cur == --* ]]; then 225 subcmd=$prev_skip_opts 175 subcmd=$prev_skip_opts 226 __perf_prev_skip_opts 176 __perf_prev_skip_opts $subcmd 227 subcmd=$subcmd" "$prev 177 subcmd=$subcmd" "$prev_skip_opts 228 opts=$($cmd $subcmd -- 178 opts=$($cmd $subcmd --list-opts) 229 __perfcomp "$opts" "$c 179 __perfcomp "$opts" "$cur" 230 fi 180 fi 231 fi 181 fi 232 } 182 } 233 183 234 if [[ -n ${ZSH_VERSION-} ]]; then 184 if [[ -n ${ZSH_VERSION-} ]]; then 235 autoload -U +X compinit && compinit 185 autoload -U +X compinit && compinit 236 186 237 __perfcomp () 187 __perfcomp () 238 { 188 { 239 emulate -L zsh 189 emulate -L zsh 240 190 241 local c IFS=$' \t\n' 191 local c IFS=$' \t\n' 242 local -a array 192 local -a array 243 193 244 for c in ${=1}; do 194 for c in ${=1}; do 245 case $c in 195 case $c in 246 --*=*|*.) ;; 196 --*=*|*.) ;; 247 *) c="$c " ;; 197 *) c="$c " ;; 248 esac 198 esac 249 array[${#array[@]}+1]= 199 array[${#array[@]}+1]="$c" 250 done 200 done 251 201 252 compset -P '*[=:]' 202 compset -P '*[=:]' 253 compadd -Q -S '' -a -- array & 203 compadd -Q -S '' -a -- array && _ret=0 254 } 204 } 255 205 256 __perfcomp_colon () 206 __perfcomp_colon () 257 { 207 { 258 emulate -L zsh 208 emulate -L zsh 259 209 260 local cur_="${2-$cur}" 210 local cur_="${2-$cur}" 261 local c IFS=$' \t\n' 211 local c IFS=$' \t\n' 262 local -a array 212 local -a array 263 213 264 if [[ "$cur_" == *:* ]]; then 214 if [[ "$cur_" == *:* ]]; then 265 local colon_word=${cur 215 local colon_word=${cur_%"${cur_##*:}"} 266 fi 216 fi 267 217 268 for c in ${=1}; do 218 for c in ${=1}; do 269 case $c in 219 case $c in 270 --*=*|*.) ;; 220 --*=*|*.) ;; 271 *) c="$c " ;; 221 *) c="$c " ;; 272 esac 222 esac 273 array[$#array+1]=${c#" 223 array[$#array+1]=${c#"$colon_word"} 274 done 224 done 275 225 276 compset -P '*[=:]' 226 compset -P '*[=:]' 277 compadd -Q -S '' -a -- array & 227 compadd -Q -S '' -a -- array && _ret=0 278 } 228 } 279 229 280 _perf () 230 _perf () 281 { 231 { 282 local _ret=1 cur cword prev 232 local _ret=1 cur cword prev 283 cur=${words[CURRENT]} 233 cur=${words[CURRENT]} 284 prev=${words[CURRENT-1]} 234 prev=${words[CURRENT-1]} 285 let cword=CURRENT-1 235 let cword=CURRENT-1 286 emulate ksh -c __perf_main 236 emulate ksh -c __perf_main 287 let _ret && _default && _ret=0 237 let _ret && _default && _ret=0 288 # _ret is only assigned 0 or 1 << 289 # shellcheck disable=SC2152 << 290 return _ret 238 return _ret 291 } 239 } 292 240 293 compdef _perf perf 241 compdef _perf perf 294 return 242 return 295 fi 243 fi 296 244 297 type perf &>/dev/null && 245 type perf &>/dev/null && 298 _perf() 246 _perf() 299 { 247 { 300 if [[ "$COMP_WORDBREAKS" != *,* ]]; th << 301 COMP_WORDBREAKS="${COMP_WORDBR << 302 export COMP_WORDBREAKS << 303 fi << 304 << 305 if [[ "$COMP_WORDBREAKS" == *:* ]]; th << 306 COMP_WORDBREAKS="${COMP_WORDBR << 307 export COMP_WORDBREAKS << 308 fi << 309 << 310 local cur words cword prev 248 local cur words cword prev 311 if [ $preload_get_comp_words_by_ref = 249 if [ $preload_get_comp_words_by_ref = "true" ]; then 312 _get_comp_words_by_ref -n =:, !! 250 _get_comp_words_by_ref -n =: cur words cword prev 313 else 251 else 314 __perf_get_comp_words_by_ref - !! 252 __perf_get_comp_words_by_ref -n =: cur words cword prev 315 fi 253 fi 316 __perf_main 254 __perf_main 317 } && 255 } && 318 256 319 complete -o bashdefault -o default -o nospace 257 complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \ 320 || complete -o default -o nospace -F _ 258 || complete -o default -o nospace -F _perf perf
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.