blob: 12b36ef5684a9014740bb48b3b2bd1bd57cc4ca7 [file] [log] [blame]
Kenny Root3bf0a012011-07-15 16:30:56 -07001# /* vim: set ai ts=4 ft=sh: */
2#
3# Copyright 2011, The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18_adb() {
19 unset -v have
20 type $1 &> /dev/null && have="yes"
21
22 if [ "$have" != "yes" ]; then
23 return
24 fi
25
26 local where i cur serial
27 COMPREPLY=()
28
29 serial="${ANDROID_SERIAL:-none}"
30 where=OPTIONS
31 for ((i=1; i <= COMP_CWORD; i++)); do
32 cur="${COMP_WORDS[i]}"
33 case "${cur}" in
34 -s)
35 where=OPT_SERIAL
36 ;;
37 -p)
38 where=OPT_PATH
39 ;;
40 -*)
41 where=OPTIONS
42 ;;
43 *)
44 if [[ $where == OPT_SERIAL ]]; then
45 where=OPT_SERIAL_ARG
46 elif [[ $where == OPT_SERIAL_ARG ]]; then
47 serial=${cur}
48 where=OPTIONS
49 else
50 where=COMMAND
51 break
52 fi
53 ;;
54 esac
55 done
56
57 if [[ $where == COMMAND && $i -ge $COMP_CWORD ]]; then
58 where=OPTIONS
59 fi
60
61 OPTIONS="-d -e -s -p"
62 COMMAND="devices connect disconnect push pull sync shell emu logcat lolcat forward jdwp install uninstall bugreport help version start-server kill-server get-state get-serialno status-window remount reboot reboot-bootloader root usb tcpip"
63
64 case $where in
65 OPTIONS|OPT_SERIAL|OPT_PATH)
66 COMPREPLY=( $(compgen -W "$OPTIONS $COMMAND" -- "$cur") )
67 ;;
68 OPT_SERIAL_ARG)
69 local devices=$(command adb devices '2>' /dev/null | grep -v "List of devices" | awk '{ print $1 }')
70 COMPREPLY=( $(compgen -W "${devices}" -- ${cur}) )
71 ;;
72 COMMAND)
73 if [[ $i -eq $COMP_CWORD ]]; then
74 COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur") )
75 else
76 i=$((i+1))
77 case "${cur}" in
78 install)
79 _adb_cmd_install "$serial" $i
80 ;;
81 pull)
82 _adb_cmd_pull "$serial" $i
83 ;;
84 push)
85 _adb_cmd_push "$serial" $i
86 ;;
87 reboot)
88 if [[ $COMP_CWORD == $i ]]; then
89 args="bootloader recovery"
90 COMPREPLY=( $(compgen -W "${args}" -- "${COMP_WORDS[i]}") )
91 fi
92 ;;
93 shell)
94 _adb_cmd_shell "$serial" $i
95 ;;
96 uninstall)
97 _adb_cmd_uninstall "$serial" $i
98 ;;
99 esac
100 fi
101 ;;
102 esac
103
104 return 0
105}
106
107_adb_cmd_install() {
108 local serial i cur where
109
110 serial=$1
111 i=$2
112
113 where=OPTIONS
114 for ((; i <= COMP_CWORD; i++)); do
115 cur="${COMP_WORDS[i]}"
116 case "${cur}" in
117 -*)
118 where=OPTIONS
119 ;;
120 *)
121 where=FILE
122 break
123 ;;
124 esac
125 done
126
127 cur="${COMP_WORDS[COMP_CWORD]}"
128 if [[ $where == OPTIONS ]]; then
129 COMPREPLY=( $(compgen -W "-l -r -s" -- "${cur}") )
130 return
131 fi
132
133 _adb_util_complete_local_file "${cur}" '!*.apk'
134}
135
136_adb_cmd_push() {
137 local serial IFS=$'\n' i cur
138
139 serial=$1
140 i=$2
141
142 cur="${COMP_WORDS[COMP_CWORD]}"
143
144 if [[ $COMP_CWORD == $i ]]; then
145 _adb_util_complete_local_file "${cur}"
146 elif [[ $COMP_CWORD == $(($i+1)) ]]; then
147 if [ "${cur}" == "" ]; then
148 cur="/"
149 fi
150 _adb_util_list_files $serial "${cur}"
151 fi
152}
153
154_adb_cmd_pull() {
155 local serial IFS=$'\n' i cur
156
157 serial=$1
158 i=$2
159
160 cur="${COMP_WORDS[COMP_CWORD]}"
161
162 if [[ $COMP_CWORD == $i ]]; then
163 if [ "${cur}" == "" ]; then
164 cur="/"
165 fi
166 _adb_util_list_files $serial "${cur}"
167 elif [[ $COMP_CWORD == $(($i+1)) ]]; then
168 _adb_util_complete_local_file "${cur}"
169 fi
170}
171
172_adb_cmd_shell() {
173 local serial IFS=$'\n' i cur
174 local -a args
175
176 serial=$1
177 i=$2
178
179 cur="${COMP_WORDS[i]}"
180 if [ "$serial" != "none" ]; then
181 args=(-s $serial)
182 fi
183
184 if [[ $i -eq $COMP_CWORD && ${cur:0:1} != "/" ]]; then
185 paths=$(command adb ${args[@]} shell echo '$'PATH 2> /dev/null | tr -d '\r' | tr : '\n')
186 COMMAND=$(command adb ${args[@]} shell ls $paths '2>' /dev/null | tr -d '\r' | {
187 while read -r tmp; do
188 command=${tmp##*/}
189 printf '%s\n' "$command"
190 done
191 })
192 COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur") )
193 return 0
194 fi
195
196 i=$((i+1))
197 case "$cur" in
198 ls)
199 _adb_shell_ls $serial $i
200 ;;
201 /*)
202 _adb_util_list_files $serial "$cur"
203 ;;
204 *)
205 COMPREPLY=( )
206 ;;
207 esac
208
209 return 0
210}
211
212_adb_cmd_uninstall() {
213 local serial i where cur packages
214
215 serial=$1
216 i=$2
217 if [ "$serial" != "none" ]; then
218 args=(-s $serial)
219 fi
220
221 where=OPTIONS
222 for ((; i <= COMP_CWORD; i++)); do
223 cur="${COMP_WORDS[i]}"
224 case "${cur}" in
225 -*)
226 where=OPTIONS
227 ;;
228 *)
229 where=FILE
230 break
231 ;;
232 esac
233 done
234
235 cur="${COMP_WORDS[COMP_CWORD]}"
236 if [[ $where == OPTIONS ]]; then
237 COMPREPLY=( $(compgen -W "-k" -- "${cur}") )
238 fi
239
240 packages="$(
241 command adb ${args[@]} shell pm list packages '2>' /dev/null 2> /dev/null | tr -d '\r' | {
242 while read -r tmp; do
243 local package=${tmp#package:}
244 echo -n "${package} "
245 done
246 }
247 )"
248
249 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${packages}" -- "${cur}") )
250}
251
252_adb_shell_ls() {
253 local serial i cur file
254 local -a args
255
256 serial=$1
257 i=$2
258 if [ "$serial" != "none" ]; then
259 args=(-s $serial)
260 fi
261
262 where=OPTIONS
263 for ((; i <= COMP_CWORD; i++)); do
264 cur="${COMP_WORDS[i]}"
265 case "${cur}" in
266 -*)
267 where=OPTIONS
268 ;;
269 *)
270 where=FILE
271 break
272 ;;
273 esac
274 done
275
276 file="${COMP_WORDS[COMP_CWORD]}"
277 if [[ ${file} == "" ]]; then
278 file="/"
279 fi
280
281 case $where in
282 OPTIONS)
283 COMPREPLY=( $(compgen -W "$OPTIONS" -- "$cur") )
284 _adb_util_list_files $serial "$file"
285 ;;
286 FILE)
287 _adb_util_list_files $serial "$file"
288 ;;
289 esac
290
291 return 0
292}
293
294_adb_util_list_files() {
295 local serial dir IFS=$'\n'
296 local -a toks
297 local -a args
298
299 serial="$1"
300 file="$2"
301
302 if [ "$serial" != "none" ]; then
303 args=(-s $serial)
304 fi
305
306 toks=( ${toks[@]-} $(
307 command adb ${args[@]} shell ls -dF ${file}"*" '2>' /dev/null 2> /dev/null | tr -d '\r' | {
308 while read -r tmp; do
309 filetype=${tmp%% *}
310 filename=${tmp:${#filetype}+1}
311 if [[ ${filetype:${#filetype}-1:1} == d ]]; then
312 printf '%s/\n' "$filename"
313 else
314 printf '%s\n' "$filename"
315 fi
316 done
317 }
318 ))
319
320 # Since we're probably doing file completion here, don't add a space after.
321 if [[ $(type -t compopt) = "builtin" ]]; then
322 compopt -o nospace
323 fi
324
325 COMPREPLY=( ${COMPREPLY[@]:-} "${toks[@]}" )
326}
327
328_adb_util_complete_local_file()
329{
330 local file xspec i j
331 local -a dirs files
332
333 file=$1
334 xspec=$2
335
336 # Since we're probably doing file completion here, don't add a space after.
337 if [[ $(type -t compopt) = "builtin" ]]; then
338 compopt -o plusdirs
339 if [[ "${xspec}" == "" ]]; then
340 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") )
341 else
342 compopt +o filenames
343 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") )
344 fi
345 else
346 # Work-around for shells with no compopt
347
348 dirs=( $(compgen -d -- "${cur}" ) )
349
350 if [[ "${xspec}" == "" ]]; then
351 files=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") )
352 else
353 files=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") )
354 fi
355
356 COMPREPLY=( $(
357 for i in "${files[@]}"; do
358 local skip=
359 for j in "${dirs[@]}"; do
360 if [[ $i == $j ]]; then
361 skip=1
362 break
363 fi
364 done
365 [[ -n $skip ]] || printf "%s\n" "$i"
366 done
367 ))
368
369 COMPREPLY=( ${COMPREPLY[@]:-} $(
370 for i in "${dirs[@]}"; do
371 printf "%s/\n" "$i"
372 done
373 ))
374 fi
375}
376
377
378if [[ $(type -t compopt) = "builtin" ]]; then
379 complete -F _adb adb
380else
381 complete -o nospace -F _adb adb
382fi