|  | # perf bash and zsh completion | 
|  |  | 
|  | # Taken from git.git's completion script. | 
|  | __my_reassemble_comp_words_by_ref() | 
|  | { | 
|  | local exclude i j first | 
|  | # Which word separators to exclude? | 
|  | exclude="${1//[^$COMP_WORDBREAKS]}" | 
|  | cword_=$COMP_CWORD | 
|  | if [ -z "$exclude" ]; then | 
|  | words_=("${COMP_WORDS[@]}") | 
|  | return | 
|  | fi | 
|  | # List of word completion separators has shrunk; | 
|  | # re-assemble words to complete. | 
|  | for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do | 
|  | # Append each nonempty word consisting of just | 
|  | # word separator characters to the current word. | 
|  | first=t | 
|  | while | 
|  | [ $i -gt 0 ] && | 
|  | [ -n "${COMP_WORDS[$i]}" ] && | 
|  | # word consists of excluded word separators | 
|  | [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] | 
|  | do | 
|  | # Attach to the previous token, | 
|  | # unless the previous token is the command name. | 
|  | if [ $j -ge 2 ] && [ -n "$first" ]; then | 
|  | ((j--)) | 
|  | fi | 
|  | first= | 
|  | words_[$j]=${words_[j]}${COMP_WORDS[i]} | 
|  | if [ $i = $COMP_CWORD ]; then | 
|  | cword_=$j | 
|  | fi | 
|  | if (($i < ${#COMP_WORDS[@]} - 1)); then | 
|  | ((i++)) | 
|  | else | 
|  | # Done. | 
|  | return | 
|  | fi | 
|  | done | 
|  | words_[$j]=${words_[j]}${COMP_WORDS[i]} | 
|  | if [ $i = $COMP_CWORD ]; then | 
|  | cword_=$j | 
|  | fi | 
|  | done | 
|  | } | 
|  |  | 
|  | type _get_comp_words_by_ref &>/dev/null || | 
|  | _get_comp_words_by_ref() | 
|  | { | 
|  | local exclude cur_ words_ cword_ | 
|  | if [ "$1" = "-n" ]; then | 
|  | exclude=$2 | 
|  | shift 2 | 
|  | fi | 
|  | __my_reassemble_comp_words_by_ref "$exclude" | 
|  | cur_=${words_[cword_]} | 
|  | while [ $# -gt 0 ]; do | 
|  | case "$1" in | 
|  | cur) | 
|  | cur=$cur_ | 
|  | ;; | 
|  | prev) | 
|  | prev=${words_[$cword_-1]} | 
|  | ;; | 
|  | words) | 
|  | words=("${words_[@]}") | 
|  | ;; | 
|  | cword) | 
|  | cword=$cword_ | 
|  | ;; | 
|  | esac | 
|  | shift | 
|  | done | 
|  | } | 
|  |  | 
|  | type __ltrim_colon_completions &>/dev/null || | 
|  | __ltrim_colon_completions() | 
|  | { | 
|  | if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then | 
|  | # Remove colon-word prefix from COMPREPLY items | 
|  | local colon_word=${1%"${1##*:}"} | 
|  | local i=${#COMPREPLY[*]} | 
|  | while [[ $((--i)) -ge 0 ]]; do | 
|  | COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} | 
|  | done | 
|  | fi | 
|  | } | 
|  |  | 
|  | __perfcomp () | 
|  | { | 
|  | COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) | 
|  | } | 
|  |  | 
|  | __perfcomp_colon () | 
|  | { | 
|  | __perfcomp "$1" "$2" | 
|  | __ltrim_colon_completions $cur | 
|  | } | 
|  |  | 
|  | __perf_main () | 
|  | { | 
|  | local cmd | 
|  |  | 
|  | cmd=${words[0]} | 
|  | COMPREPLY=() | 
|  |  | 
|  | # List perf subcommands or long options | 
|  | if [ $cword -eq 1 ]; then | 
|  | if [[ $cur == --* ]]; then | 
|  | __perfcomp '--help --version \ | 
|  | --exec-path --html-path --paginate --no-pager \ | 
|  | --perf-dir --work-tree --debugfs-dir' -- "$cur" | 
|  | else | 
|  | cmds=$($cmd --list-cmds) | 
|  | __perfcomp "$cmds" "$cur" | 
|  | fi | 
|  | # List possible events for -e option | 
|  | elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then | 
|  | evts=$($cmd list --raw-dump) | 
|  | __perfcomp_colon "$evts" "$cur" | 
|  | # List subcommands for perf commands | 
|  | elif [[ $prev == @(kvm|kmem|mem|lock|sched) ]]; then | 
|  | subcmds=$($cmd $prev --list-cmds) | 
|  | __perfcomp_colon "$subcmds" "$cur" | 
|  | # List long option names | 
|  | elif [[ $cur == --* ]];  then | 
|  | subcmd=${words[1]} | 
|  | opts=$($cmd $subcmd --list-opts) | 
|  | __perfcomp "$opts" "$cur" | 
|  | fi | 
|  | } | 
|  |  | 
|  | if [[ -n ${ZSH_VERSION-} ]]; then | 
|  | autoload -U +X compinit && compinit | 
|  |  | 
|  | __perfcomp () | 
|  | { | 
|  | emulate -L zsh | 
|  |  | 
|  | local c IFS=$' \t\n' | 
|  | local -a array | 
|  |  | 
|  | for c in ${=1}; do | 
|  | case $c in | 
|  | --*=*|*.) ;; | 
|  | *) c="$c " ;; | 
|  | esac | 
|  | array[${#array[@]}+1]="$c" | 
|  | done | 
|  |  | 
|  | compset -P '*[=:]' | 
|  | compadd -Q -S '' -a -- array && _ret=0 | 
|  | } | 
|  |  | 
|  | __perfcomp_colon () | 
|  | { | 
|  | emulate -L zsh | 
|  |  | 
|  | local cur_="${2-$cur}" | 
|  | local c IFS=$' \t\n' | 
|  | local -a array | 
|  |  | 
|  | if [[ "$cur_" == *:* ]]; then | 
|  | local colon_word=${cur_%"${cur_##*:}"} | 
|  | fi | 
|  |  | 
|  | for c in ${=1}; do | 
|  | case $c in | 
|  | --*=*|*.) ;; | 
|  | *) c="$c " ;; | 
|  | esac | 
|  | array[$#array+1]=${c#"$colon_word"} | 
|  | done | 
|  |  | 
|  | compset -P '*[=:]' | 
|  | compadd -Q -S '' -a -- array && _ret=0 | 
|  | } | 
|  |  | 
|  | _perf () | 
|  | { | 
|  | local _ret=1 cur cword prev | 
|  | cur=${words[CURRENT]} | 
|  | prev=${words[CURRENT-1]} | 
|  | let cword=CURRENT-1 | 
|  | emulate ksh -c __perf_main | 
|  | let _ret && _default && _ret=0 | 
|  | return _ret | 
|  | } | 
|  |  | 
|  | compdef _perf perf | 
|  | return | 
|  | fi | 
|  |  | 
|  | type perf &>/dev/null && | 
|  | _perf() | 
|  | { | 
|  | local cur words cword prev | 
|  | _get_comp_words_by_ref -n =: cur words cword prev | 
|  | __perf_main | 
|  | } && | 
|  |  | 
|  | complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \ | 
|  | || complete -o default -o nospace -F _perf perf |