Skip to content
This repository was archived by the owner on Aug 27, 2025. It is now read-only.

Commit 1edfb4e

Browse files
committed
Add bash programmable completion for vcgencmd
The completion file should be renamed "vcgencmd" and installed in /usr/share/bash-completion/completions/.
1 parent 97bc818 commit 1edfb4e

File tree

2 files changed

+288
-0
lines changed

2 files changed

+288
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#!/usr/bin/env bats
2+
# Integration tests for vcgencmd command completion.
3+
# Runs on Raspberry Pi, requires bats-core package.
4+
5+
load /usr/share/bash-completion/bash_completion || true
6+
load /usr/share/bash-completion/completions/vcgencmd
7+
8+
9+
complete_command() {
10+
local cmd="$*"
11+
12+
COMP_LINE="${cmd}"
13+
mapfile -t COMP_WORDS < <( compgen -W "${cmd}" )
14+
15+
# index of current word in $COMP_WORDS array
16+
COMP_CWORD=$(( ${#COMP_WORDS[@]} - 1 ))
17+
if [[ ${cmd: -1} == " " ]]; then
18+
COMP_CWORD=$(( COMP_CWORD + 1 ))
19+
fi
20+
21+
# current pointer position in line
22+
COMP_POINT="${#cmd}"
23+
24+
# name of completion function
25+
complete_func=$(complete -p "${COMP_WORDS[0]}" | sed 's/.*-F \([^ ]*\) .*/\1/')
26+
[[ -n $complete_func ]]
27+
28+
# Run completion function. Sets the COMPREPLY array.
29+
$complete_func "${COMP_WORDS[0]}" || true
30+
31+
if [[ $DEBUG_VCGENCMD_TEST ]]; then
32+
echo >&3
33+
echo "COMP_LINE='${COMP_LINE}'" >&3
34+
echo "COMP_WORDS='${COMP_WORDS[*]}'" >&3
35+
echo "length COMP_WORDS = ${#COMP_WORDS[@]}" >&3
36+
echo "COMP_CWORD=${COMP_CWORD}" >&3
37+
echo "COMP_POINT=${COMP_POINT}" >&3
38+
echo "COMPREPLY=${COMPREPLY[*]}" >&3
39+
echo "length COMPREPLY=${#COMPREPLY[@]}" >&3
40+
fi
41+
}
42+
43+
@test "vcgencmd - -> -t -h --help" {
44+
complete_command "vcgencmd -"
45+
[[ "${COMPREPLY[*]}" == "-t -h --help" ]]
46+
}
47+
48+
@test "--h -> --help" {
49+
complete_command "vcgencmd --h"
50+
[[ "${COMPREPLY[*]}" == "--help" ]]
51+
}
52+
53+
@test "--help -> (nothing)" {
54+
complete_command "vcgencmd --help "
55+
[[ "${#COMPREPLY[@]}" -eq 0 ]]
56+
}
57+
58+
@test "vcgencmd -xxx -> (nothing)" {
59+
complete_command "vcgencmd -xxx "
60+
[[ "${#COMPREPLY[@]}" -eq 0 ]]
61+
}
62+
63+
@test "vcgencmd foobar -> (nothing)" {
64+
complete_command "vcgencmd foobar "
65+
[[ "${#COMPREPLY[@]}" -eq 0 ]]
66+
}
67+
68+
@test "vcgencmd -> commands version get_config measure_temp ..." {
69+
complete_command "vcgencmd "
70+
[[ "${#COMPREPLY[@]}" -gt 60 ]]
71+
echo "${COMPREPLY[*]}" | grep -Ewo "(commands|version|get_config|measure_temp)"
72+
}
73+
74+
@test "vcgencmd -t -> commands version get_config measure_temp ..." {
75+
complete_command "vcgencmd -t "
76+
[[ "${#COMPREPLY[@]}" -gt 60 ]]
77+
echo "${COMPREPLY[*]}" | grep -Ewo "(commands|version|get_config|measure_temp)"
78+
}
79+
80+
@test "codec_enabled -> FLAC MJPG ..." {
81+
complete_command "vcgencmd codec_enabled "
82+
echo "${COMPREPLY[*]}" | grep -Ewo "(FLAC|MJPG|H263|PCM|VORB)"
83+
}
84+
85+
@test "measure_clock -> arm core uart ..." {
86+
complete_command "vcgencmd measure_clock "
87+
echo "${COMPREPLY[*]}" | grep -Ewo "(arm|core|uart|hdmi)"
88+
}
89+
90+
@test "measure_volts -> core sdram_[cip]" {
91+
complete_command "vcgencmd measure_clock "
92+
echo "${COMPREPLY[*]}" | grep -Ewo "(core|sdram_[cip])"
93+
}
94+
95+
@test "get_mem -> arm gpu" {
96+
complete_command "vcgencmd get_mem "
97+
echo "${COMPREPLY[*]}" | grep -Ewo "(arm|gpu)"
98+
}
99+
100+
@test "get_config -> int str arm_freq ..." {
101+
complete_command "vcgencmd get_config "
102+
[[ "${#COMPREPLY[@]}" -gt 30 ]]
103+
echo "${COMPREPLY[*]}" | grep -Ewo "(int|str|device_tree|arm_freq|total_mem|hdmi_cvt:0|enable_tvout)"
104+
}
105+
106+
@test "get_config hdmi_cvt: -> 0 1" {
107+
complete_command "vcgencmd get_config hdmi_cvt:"
108+
[[ "${COMPREPLY[*]}" == "0 1" ]]
109+
}
110+
111+
@test "get_config hdmi_pixel_freq_li -> hdmi_pixel_freq_limit:0" {
112+
complete_command "vcgencmd get_config hdmi_pixel_freq_li"
113+
[[ "${COMPREPLY[*]}" == "hdmi_pixel_freq_limit:0" ]]
114+
}
115+
116+
@test "vcos -> version log" {
117+
complete_command "vcgencmd vcos "
118+
echo "${COMPREPLY[*]}" | grep -Ewo "(version|log)"
119+
}
120+
121+
@test "display_power -> 0 1 -1" {
122+
complete_command "vcgencmd display_power "
123+
[[ "${COMPREPLY[*]}" == "0 1 -1" ]]
124+
}
125+
126+
@test "-t display_power -> 0 1 -1" {
127+
complete_command "vcgencmd -t display_power "
128+
[[ "${COMPREPLY[*]}" == "0 1 -1" ]]
129+
}
130+
131+
@test "display_power [0, 1] -> 0 1 2 3 7" {
132+
local display_nums="0 1 2 3 7"
133+
complete_command "vcgencmd display_power 0 "
134+
[[ "${COMPREPLY[*]}" == "$display_nums" ]]
135+
complete_command "vcgencmd display_power 1 "
136+
[[ "${COMPREPLY[*]}" == "$display_nums" ]]
137+
}
138+
139+
@test "display_power -1 -> 0 1 2 3 7" {
140+
local display_nums="0 1 2 3 7"
141+
complete_command "vcgencmd display_power -1 "
142+
[[ "${COMPREPLY[*]}" == "$display_nums" ]]
143+
}
144+
145+
@test "BADARG display_power -1 -> (nothing)" {
146+
complete_command "vcgencmd BADARG display_power -1 "
147+
echo "${COMPREPLY[*]}"
148+
[[ "${COMPREPLY[*]}" == "" ]]
149+
}
150+
151+
@test "display_power BADARG -1 -> (nothing)" {
152+
complete_command "vcgencmd display_power BADARG -1 "
153+
echo "${COMPREPLY[*]}"
154+
[[ "${COMPREPLY[*]}" == "" ]]
155+
}
156+
157+
@test "-t display_power -1 -> 0 1 2 3 7" {
158+
complete_command "vcgencmd -t display_power -1 "
159+
[[ "${COMPREPLY[*]}" == "0 1 2 3 7" ]]
160+
}
161+
162+
@test "vcos log -> status" {
163+
complete_command "vcgencmd vcos log "
164+
[[ "${COMPREPLY[*]}" == "status" ]]
165+
}
166+
167+
@test "-t vcos log -> status" {
168+
complete_command "vcgencmd -t vcos log "
169+
[[ "${COMPREPLY[*]}" == "status" ]]
170+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# vcgencmd(1) completion -*- shell-script -*-
2+
3+
_vcgencmd_commands()
4+
{
5+
local commands fallback re
6+
commands="$(/usr/bin/vcgencmd commands 2> /dev/null)"
7+
fallback="codec_enabled commands display_power get_camera get_config
8+
get_lcd_info get_mem get_throttled measure_temp measure_volts
9+
mem_oom version"
10+
re='commands="(.*)"'
11+
12+
if [[ $commands =~ $re ]]; then
13+
commands="${BASH_REMATCH[1]}"
14+
commands="${commands//,}"
15+
else
16+
commands="${fallback}"
17+
fi
18+
19+
compgen -W "$commands" -- "$cur"
20+
}
21+
22+
# This function counts the number of args, excluding options,
23+
# providing exceptions for option-like arguments.
24+
# @param $1 chars Characters out of $COMP_WORDBREAKS which should
25+
# NOT be considered word breaks. See __reassemble_comp_words_by_ref.
26+
# @param $2 non_opt_args arguments that look like options, but aren't
27+
_vcgencmd_count_args()
28+
{
29+
local i cword words non_opt_args
30+
__reassemble_comp_words_by_ref "$1" words cword
31+
32+
args=1
33+
non_opt_args="$2"
34+
35+
for i in "${words[@]:1:cword-1}"; do
36+
if [[ "$i" != -* ]]; then
37+
args=$((args+1))
38+
else
39+
for a in $non_opt_args; do
40+
[[ "$i" == "$a" ]] && args=$((args+1))
41+
done
42+
fi
43+
done
44+
}
45+
46+
_vcgencmd() {
47+
local cur prev cword words opts='' args
48+
_init_completion -n ':' || return
49+
_vcgencmd_count_args ':' '-1'
50+
51+
if [[ $cword -eq 1 && $cur == -* ]] ; then
52+
mapfile -t COMPREPLY < <( compgen -W '-t -h --help' -- "$cur" )
53+
return 0
54+
fi
55+
56+
if [[ $args -eq 1 ]]; then
57+
case "$prev" in
58+
-h|--help)
59+
;;
60+
-t|vcgencmd)
61+
mapfile -t COMPREPLY < <( _vcgencmd_commands )
62+
;;
63+
-*)
64+
;;
65+
esac
66+
return 0
67+
fi
68+
69+
if [[ $args -eq 2 ]]; then
70+
case "$prev" in
71+
codec_enabled)
72+
opts='AGIF FLAC H263 H264 MJPA MJPB MJPG MPG2 MPG4 MVC0 PCM
73+
THRA VORB VP6 VP8 WMV9 WVC1'
74+
;;
75+
measure_clock)
76+
opts='arm core h264 isp v3d uart pwm emmc pixel vec hdmi dpi'
77+
;;
78+
measure_volts)
79+
opts='core sdram_c sdram_i sdram_p'
80+
;;
81+
get_mem)
82+
opts='arm gpu'
83+
;;
84+
get_config)
85+
opts='int str'
86+
opts+=" $("$1" get_config str | command sed -e 's/=.*$//')"
87+
opts+=" $("$1" get_config int | command sed -e 's/=.*$//')"
88+
;;
89+
display_power)
90+
opts='0 1 -1'
91+
;;
92+
vcos)
93+
opts='log version'
94+
;;
95+
esac
96+
fi
97+
98+
if [[ $args -eq 3 ]]; then
99+
case "$prev" in
100+
0|1|-1)
101+
opts='0 1 2 3 7'
102+
;;
103+
esac
104+
case "$prev" in
105+
log)
106+
opts='status'
107+
;;
108+
esac
109+
fi
110+
111+
[[ -n $opts ]] && mapfile -t COMPREPLY < <( compgen -W "$opts" -- "$cur" )
112+
[[ $prev == "get_config" ]] && __ltrim_colon_completions "$cur"
113+
114+
return 0
115+
} &&
116+
complete -F _vcgencmd vcgencmd
117+
118+
# ex: filetype=sh

0 commit comments

Comments
 (0)