perf-completion.sh 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. # perf bash and zsh completion
  2. # Taken from git.git's completion script.
  3. __my_reassemble_comp_words_by_ref()
  4. {
  5. local exclude i j first
  6. # Which word separators to exclude?
  7. exclude="${1//[^$COMP_WORDBREAKS]}"
  8. cword_=$COMP_CWORD
  9. if [ -z "$exclude" ]; then
  10. words_=("${COMP_WORDS[@]}")
  11. return
  12. fi
  13. # List of word completion separators has shrunk;
  14. # re-assemble words to complete.
  15. for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
  16. # Append each nonempty word consisting of just
  17. # word separator characters to the current word.
  18. first=t
  19. while
  20. [ $i -gt 0 ] &&
  21. [ -n "${COMP_WORDS[$i]}" ] &&
  22. # word consists of excluded word separators
  23. [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
  24. do
  25. # Attach to the previous token,
  26. # unless the previous token is the command name.
  27. if [ $j -ge 2 ] && [ -n "$first" ]; then
  28. ((j--))
  29. fi
  30. first=
  31. words_[$j]=${words_[j]}${COMP_WORDS[i]}
  32. if [ $i = $COMP_CWORD ]; then
  33. cword_=$j
  34. fi
  35. if (($i < ${#COMP_WORDS[@]} - 1)); then
  36. ((i++))
  37. else
  38. # Done.
  39. return
  40. fi
  41. done
  42. words_[$j]=${words_[j]}${COMP_WORDS[i]}
  43. if [ $i = $COMP_CWORD ]; then
  44. cword_=$j
  45. fi
  46. done
  47. }
  48. type _get_comp_words_by_ref &>/dev/null ||
  49. _get_comp_words_by_ref()
  50. {
  51. local exclude cur_ words_ cword_
  52. if [ "$1" = "-n" ]; then
  53. exclude=$2
  54. shift 2
  55. fi
  56. __my_reassemble_comp_words_by_ref "$exclude"
  57. cur_=${words_[cword_]}
  58. while [ $# -gt 0 ]; do
  59. case "$1" in
  60. cur)
  61. cur=$cur_
  62. ;;
  63. prev)
  64. prev=${words_[$cword_-1]}
  65. ;;
  66. words)
  67. words=("${words_[@]}")
  68. ;;
  69. cword)
  70. cword=$cword_
  71. ;;
  72. esac
  73. shift
  74. done
  75. }
  76. type __ltrim_colon_completions &>/dev/null ||
  77. __ltrim_colon_completions()
  78. {
  79. if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
  80. # Remove colon-word prefix from COMPREPLY items
  81. local colon_word=${1%"${1##*:}"}
  82. local i=${#COMPREPLY[*]}
  83. while [[ $((--i)) -ge 0 ]]; do
  84. COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
  85. done
  86. fi
  87. }
  88. __perfcomp ()
  89. {
  90. COMPREPLY=( $( compgen -W "$1" -- "$2" ) )
  91. }
  92. __perfcomp_colon ()
  93. {
  94. __perfcomp "$1" "$2"
  95. __ltrim_colon_completions $cur
  96. }
  97. __perf_main ()
  98. {
  99. local cmd
  100. cmd=${words[0]}
  101. COMPREPLY=()
  102. # List perf subcommands or long options
  103. if [ $cword -eq 1 ]; then
  104. if [[ $cur == --* ]]; then
  105. __perfcomp '--help --version \
  106. --exec-path --html-path --paginate --no-pager \
  107. --perf-dir --work-tree --debugfs-dir' -- "$cur"
  108. else
  109. cmds=$($cmd --list-cmds)
  110. __perfcomp "$cmds" "$cur"
  111. fi
  112. # List possible events for -e option
  113. elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
  114. evts=$($cmd list --raw-dump)
  115. __perfcomp_colon "$evts" "$cur"
  116. # List subcommands for perf commands
  117. elif [[ $prev == @(kvm|kmem|mem|lock|sched) ]]; then
  118. subcmds=$($cmd $prev --list-cmds)
  119. __perfcomp_colon "$subcmds" "$cur"
  120. # List long option names
  121. elif [[ $cur == --* ]]; then
  122. subcmd=${words[1]}
  123. opts=$($cmd $subcmd --list-opts)
  124. __perfcomp "$opts" "$cur"
  125. fi
  126. }
  127. if [[ -n ${ZSH_VERSION-} ]]; then
  128. autoload -U +X compinit && compinit
  129. __perfcomp ()
  130. {
  131. emulate -L zsh
  132. local c IFS=$' \t\n'
  133. local -a array
  134. for c in ${=1}; do
  135. case $c in
  136. --*=*|*.) ;;
  137. *) c="$c " ;;
  138. esac
  139. array[${#array[@]}+1]="$c"
  140. done
  141. compset -P '*[=:]'
  142. compadd -Q -S '' -a -- array && _ret=0
  143. }
  144. __perfcomp_colon ()
  145. {
  146. emulate -L zsh
  147. local cur_="${2-$cur}"
  148. local c IFS=$' \t\n'
  149. local -a array
  150. if [[ "$cur_" == *:* ]]; then
  151. local colon_word=${cur_%"${cur_##*:}"}
  152. fi
  153. for c in ${=1}; do
  154. case $c in
  155. --*=*|*.) ;;
  156. *) c="$c " ;;
  157. esac
  158. array[$#array+1]=${c#"$colon_word"}
  159. done
  160. compset -P '*[=:]'
  161. compadd -Q -S '' -a -- array && _ret=0
  162. }
  163. _perf ()
  164. {
  165. local _ret=1 cur cword prev
  166. cur=${words[CURRENT]}
  167. prev=${words[CURRENT-1]}
  168. let cword=CURRENT-1
  169. emulate ksh -c __perf_main
  170. let _ret && _default && _ret=0
  171. return _ret
  172. }
  173. compdef _perf perf
  174. return
  175. fi
  176. type perf &>/dev/null &&
  177. _perf()
  178. {
  179. local cur words cword prev
  180. _get_comp_words_by_ref -n =: cur words cword prev
  181. __perf_main
  182. } &&
  183. complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \
  184. || complete -o default -o nospace -F _perf perf