Commit | Line | Data |
---|---|---|
f38ab8af | 1 | # perf bash and zsh completion |
b2441318 | 2 | # SPDX-License-Identifier: GPL-2.0 |
98a4179c | 3 | |
c3fb6717 RR |
4 | # Taken from git.git's completion script. |
5 | __my_reassemble_comp_words_by_ref() | |
6 | { | |
7 | local exclude i j first | |
8 | # Which word separators to exclude? | |
9 | exclude="${1//[^$COMP_WORDBREAKS]}" | |
10 | cword_=$COMP_CWORD | |
11 | if [ -z "$exclude" ]; then | |
12 | words_=("${COMP_WORDS[@]}") | |
13 | return | |
14 | fi | |
15 | # List of word completion separators has shrunk; | |
16 | # re-assemble words to complete. | |
17 | for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do | |
18 | # Append each nonempty word consisting of just | |
19 | # word separator characters to the current word. | |
20 | first=t | |
21 | while | |
22 | [ $i -gt 0 ] && | |
23 | [ -n "${COMP_WORDS[$i]}" ] && | |
24 | # word consists of excluded word separators | |
25 | [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] | |
26 | do | |
27 | # Attach to the previous token, | |
28 | # unless the previous token is the command name. | |
29 | if [ $j -ge 2 ] && [ -n "$first" ]; then | |
30 | ((j--)) | |
31 | fi | |
32 | first= | |
33 | words_[$j]=${words_[j]}${COMP_WORDS[i]} | |
34 | if [ $i = $COMP_CWORD ]; then | |
35 | cword_=$j | |
36 | fi | |
37 | if (($i < ${#COMP_WORDS[@]} - 1)); then | |
38 | ((i++)) | |
39 | else | |
40 | # Done. | |
41 | return | |
42 | fi | |
43 | done | |
44 | words_[$j]=${words_[j]}${COMP_WORDS[i]} | |
45 | if [ $i = $COMP_CWORD ]; then | |
46 | cword_=$j | |
47 | fi | |
48 | done | |
49 | } | |
50 | ||
1312c8a8 YS |
51 | # Define preload_get_comp_words_by_ref="false", if the function |
52 | # __perf_get_comp_words_by_ref() is required instead. | |
53 | preload_get_comp_words_by_ref="true" | |
54 | ||
55 | if [ $preload_get_comp_words_by_ref = "true" ]; then | |
56 | type _get_comp_words_by_ref &>/dev/null || | |
57 | preload_get_comp_words_by_ref="false" | |
58 | fi | |
59 | [ $preload_get_comp_words_by_ref = "true" ] || | |
60 | __perf_get_comp_words_by_ref() | |
c3fb6717 RR |
61 | { |
62 | local exclude cur_ words_ cword_ | |
63 | if [ "$1" = "-n" ]; then | |
64 | exclude=$2 | |
65 | shift 2 | |
66 | fi | |
67 | __my_reassemble_comp_words_by_ref "$exclude" | |
68 | cur_=${words_[cword_]} | |
69 | while [ $# -gt 0 ]; do | |
70 | case "$1" in | |
71 | cur) | |
72 | cur=$cur_ | |
73 | ;; | |
74 | prev) | |
75 | prev=${words_[$cword_-1]} | |
76 | ;; | |
77 | words) | |
78 | words=("${words_[@]}") | |
79 | ;; | |
80 | cword) | |
81 | cword=$cword_ | |
82 | ;; | |
83 | esac | |
84 | shift | |
85 | done | |
86 | } | |
87 | ||
1312c8a8 YS |
88 | # Define preload__ltrim_colon_completions="false", if the function |
89 | # __perf__ltrim_colon_completions() is required instead. | |
90 | preload__ltrim_colon_completions="true" | |
91 | ||
92 | if [ $preload__ltrim_colon_completions = "true" ]; then | |
93 | type __ltrim_colon_completions &>/dev/null || | |
94 | preload__ltrim_colon_completions="false" | |
95 | fi | |
96 | [ $preload__ltrim_colon_completions = "true" ] || | |
97 | __perf__ltrim_colon_completions() | |
ae0c1f99 NK |
98 | { |
99 | if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then | |
100 | # Remove colon-word prefix from COMPREPLY items | |
30079d1d | 101 | local colon_word=${1%"${1##*:}"} |
ae0c1f99 NK |
102 | local i=${#COMPREPLY[*]} |
103 | while [[ $((--i)) -ge 0 ]]; do | |
104 | COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} | |
105 | done | |
106 | fi | |
107 | } | |
108 | ||
12f9dd50 RR |
109 | __perfcomp () |
110 | { | |
111 | COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) | |
112 | } | |
113 | ||
37e72c31 RR |
114 | __perfcomp_colon () |
115 | { | |
116 | __perfcomp "$1" "$2" | |
1312c8a8 YS |
117 | if [ $preload__ltrim_colon_completions = "true" ]; then |
118 | __ltrim_colon_completions $cur | |
119 | else | |
120 | __perf__ltrim_colon_completions $cur | |
121 | fi | |
37e72c31 RR |
122 | } |
123 | ||
67afff48 YS |
124 | __perf_prev_skip_opts () |
125 | { | |
126 | local i cmd_ cmds_ | |
127 | ||
128 | let i=cword-1 | |
eee200a6 | 129 | cmds_=$($cmd $1 --list-cmds) |
67afff48 YS |
130 | prev_skip_opts=() |
131 | while [ $i -ge 0 ]; do | |
eee200a6 YS |
132 | if [[ ${words[i]} == $1 ]]; then |
133 | return | |
134 | fi | |
67afff48 YS |
135 | for cmd_ in $cmds_; do |
136 | if [[ ${words[i]} == $cmd_ ]]; then | |
137 | prev_skip_opts=${words[i]} | |
138 | return | |
139 | fi | |
140 | done | |
141 | ((i--)) | |
142 | done | |
143 | } | |
6fdd9cb7 | 144 | |
2cf025e6 | 145 | __perf_main () |
98a4179c | 146 | { |
2cf025e6 | 147 | local cmd |
98a4179c | 148 | |
6e0dc374 | 149 | cmd=${words[0]} |
2cf025e6 | 150 | COMPREPLY=() |
98a4179c | 151 | |
67afff48 YS |
152 | # Skip options backward and find the last perf command |
153 | __perf_prev_skip_opts | |
35c2fde1 | 154 | # List perf subcommands or long options |
e003ce54 | 155 | if [ -z $prev_skip_opts ]; then |
35c2fde1 | 156 | if [[ $cur == --* ]]; then |
7335399a | 157 | cmds=$($cmd --list-opts) |
35c2fde1 NK |
158 | else |
159 | cmds=$($cmd --list-cmds) | |
35c2fde1 | 160 | fi |
7335399a | 161 | __perfcomp "$cmds" "$cur" |
6fdd9cb7 YS |
162 | # List possible events for -e option |
163 | elif [[ $prev == @("-e"|"--event") && | |
164 | $prev_skip_opts == @(record|stat|top) ]]; then | |
4d8061fa | 165 | evts=$($cmd list --raw-dump) |
37e72c31 | 166 | __perfcomp_colon "$evts" "$cur" |
02fde323 YS |
167 | else |
168 | # List subcommands for perf commands | |
6fdd9cb7 YS |
169 | if [[ $prev_skip_opts == @(kvm|kmem|mem|lock|sched| |
170 | |data|help|script|test|timechart|trace) ]]; then | |
67afff48 | 171 | subcmds=$($cmd $prev_skip_opts --list-cmds) |
02fde323 YS |
172 | __perfcomp_colon "$subcmds" "$cur" |
173 | fi | |
174 | # List long option names | |
175 | if [[ $cur == --* ]]; then | |
eee200a6 YS |
176 | subcmd=$prev_skip_opts |
177 | __perf_prev_skip_opts $subcmd | |
178 | subcmd=$subcmd" "$prev_skip_opts | |
02fde323 YS |
179 | opts=$($cmd $subcmd --list-opts) |
180 | __perfcomp "$opts" "$cur" | |
181 | fi | |
98a4179c | 182 | fi |
2cf025e6 RR |
183 | } |
184 | ||
f38ab8af RR |
185 | if [[ -n ${ZSH_VERSION-} ]]; then |
186 | autoload -U +X compinit && compinit | |
187 | ||
188 | __perfcomp () | |
189 | { | |
190 | emulate -L zsh | |
191 | ||
192 | local c IFS=$' \t\n' | |
193 | local -a array | |
194 | ||
195 | for c in ${=1}; do | |
196 | case $c in | |
197 | --*=*|*.) ;; | |
198 | *) c="$c " ;; | |
199 | esac | |
200 | array[${#array[@]}+1]="$c" | |
201 | done | |
202 | ||
203 | compset -P '*[=:]' | |
204 | compadd -Q -S '' -a -- array && _ret=0 | |
205 | } | |
206 | ||
207 | __perfcomp_colon () | |
208 | { | |
209 | emulate -L zsh | |
210 | ||
211 | local cur_="${2-$cur}" | |
212 | local c IFS=$' \t\n' | |
213 | local -a array | |
214 | ||
215 | if [[ "$cur_" == *:* ]]; then | |
216 | local colon_word=${cur_%"${cur_##*:}"} | |
217 | fi | |
218 | ||
219 | for c in ${=1}; do | |
220 | case $c in | |
221 | --*=*|*.) ;; | |
222 | *) c="$c " ;; | |
223 | esac | |
224 | array[$#array+1]=${c#"$colon_word"} | |
225 | done | |
226 | ||
227 | compset -P '*[=:]' | |
228 | compadd -Q -S '' -a -- array && _ret=0 | |
229 | } | |
230 | ||
231 | _perf () | |
232 | { | |
233 | local _ret=1 cur cword prev | |
234 | cur=${words[CURRENT]} | |
235 | prev=${words[CURRENT-1]} | |
236 | let cword=CURRENT-1 | |
237 | emulate ksh -c __perf_main | |
238 | let _ret && _default && _ret=0 | |
239 | return _ret | |
240 | } | |
241 | ||
242 | compdef _perf perf | |
243 | return | |
244 | fi | |
245 | ||
2cf025e6 RR |
246 | type perf &>/dev/null && |
247 | _perf() | |
248 | { | |
249 | local cur words cword prev | |
1312c8a8 YS |
250 | if [ $preload_get_comp_words_by_ref = "true" ]; then |
251 | _get_comp_words_by_ref -n =: cur words cword prev | |
252 | else | |
253 | __perf_get_comp_words_by_ref -n =: cur words cword prev | |
254 | fi | |
2cf025e6 | 255 | __perf_main |
98a4179c | 256 | } && |
7b6c48e1 RR |
257 | |
258 | complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \ | |
259 | || complete -o default -o nospace -F _perf perf |