perf-completion.sh 3.9 KB
Newer Older
1
# perf bash and zsh completion
2

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
# 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
}

79
type __ltrim_colon_completions &>/dev/null ||
80 81 82 83
__ltrim_colon_completions()
{
	if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
		# Remove colon-word prefix from COMPREPLY items
84
		local colon_word=${1%"${1##*:}"}
85 86 87 88 89 90 91
		local i=${#COMPREPLY[*]}
		while [[ $((--i)) -ge 0 ]]; do
			COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
		done
	fi
}

92 93 94 95 96
__perfcomp ()
{
	COMPREPLY=( $( compgen -W "$1" -- "$2" ) )
}

97 98 99 100 101 102
__perfcomp_colon ()
{
	__perfcomp "$1" "$2"
	__ltrim_colon_completions $cur
}

103
__perf_main ()
104
{
105
	local cmd
106

107
	cmd=${words[0]}
108
	COMPREPLY=()
109

110
	# List perf subcommands or long options
111
	if [ $cword -eq 1 ]; then
112
		if [[ $cur == --* ]]; then
113
			cmds=$($cmd --list-opts)
114 115 116
		else
			cmds=$($cmd --list-cmds)
		fi
117
		__perfcomp "$cmds" "$cur"
118
	# List possible events for -e option
119
	elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
120
		evts=$($cmd list --raw-dump)
121
		__perfcomp_colon "$evts" "$cur"
122
	# List subcommands for perf commands
123
	elif [[ $prev == @(kvm|kmem|mem|lock|sched) ]]; then
124
		subcmds=$($cmd $prev --list-cmds)
125
		__perfcomp_colon "$subcmds" "$cur"
126 127
	# List long option names
	elif [[ $cur == --* ]];  then
128
		subcmd=${words[1]}
129
		opts=$($cmd $subcmd --list-opts)
130
		__perfcomp "$opts" "$cur"
131
	fi
132 133
}

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
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

195 196 197 198 199 200
type perf &>/dev/null &&
_perf()
{
	local cur words cword prev
	_get_comp_words_by_ref -n =: cur words cword prev
	__perf_main
201
} &&
202 203 204

complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \
	|| complete -o default -o nospace -F _perf perf