Home | History | Annotate | Download | only in bash_completion
      1 # /* 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 disable-verity"
     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                     sideload)
     82                         _adb_cmd_sideload "$serial" $i
     83                         ;;
     84                     pull)
     85                         _adb_cmd_pull "$serial" $i
     86                         ;;
     87                     push)
     88                         _adb_cmd_push "$serial" $i
     89                         ;;
     90                     reboot)
     91                         if [[ $COMP_CWORD == $i ]]; then
     92                             args="bootloader recovery"
     93                             COMPREPLY=( $(compgen -W "${args}" -- "${COMP_WORDS[i]}") )
     94                         fi
     95                         ;;
     96                     shell)
     97                         _adb_cmd_shell "$serial" $i
     98                         ;;
     99                     uninstall)
    100                         _adb_cmd_uninstall "$serial" $i
    101                         ;;
    102                 esac
    103             fi
    104             ;;
    105     esac
    106 
    107     return 0
    108 }
    109 
    110 _adb_cmd_install() {
    111     local serial i cur where
    112 
    113     serial=$1
    114     i=$2
    115 
    116     where=OPTIONS
    117     for ((; i <= COMP_CWORD; i++)); do
    118         cur="${COMP_WORDS[i]}"
    119         case "${cur}" in
    120             -*)
    121                 where=OPTIONS
    122                 ;;
    123             *)
    124                 where=FILE
    125                 break
    126                 ;;
    127         esac
    128     done
    129 
    130     cur="${COMP_WORDS[COMP_CWORD]}"
    131     if [[ $where == OPTIONS ]]; then
    132         COMPREPLY=( $(compgen -W "-d -l -r -s" -- "${cur}") )
    133         return
    134     fi
    135 
    136     _adb_util_complete_local_file "${cur}" '!*.apk'
    137 }
    138 
    139 _adb_cmd_sideload() {
    140     local serial i cur
    141 
    142     serial=$1
    143     i=$2
    144 
    145     cur="${COMP_WORDS[COMP_CWORD]}"
    146 
    147     _adb_util_complete_local_file "${cur}" '!*.zip'
    148 }
    149 
    150 _adb_cmd_push() {
    151     local serial IFS=$'\n' i cur
    152 
    153     serial=$1
    154     i=$2
    155 
    156     cur="${COMP_WORDS[COMP_CWORD]}"
    157 
    158     if [[ $COMP_CWORD == $i ]]; then
    159         _adb_util_complete_local_file "${cur}"
    160     elif [[ $COMP_CWORD == $(($i+1)) ]]; then
    161         if [ "${cur}" == "" ]; then
    162             cur="/"
    163         fi
    164         _adb_util_list_files $serial "${cur}"
    165     fi
    166 }
    167 
    168 _adb_cmd_pull() {
    169     local serial IFS=$'\n' i cur
    170 
    171     serial=$1
    172     i=$2
    173 
    174     cur="${COMP_WORDS[COMP_CWORD]}"
    175 
    176     if [[ $COMP_CWORD == $i ]]; then
    177         if [ "${cur}" == "" ]; then
    178             cur="/"
    179         fi
    180         _adb_util_list_files $serial "${cur}"
    181     elif [[ $COMP_CWORD == $(($i+1)) ]]; then
    182         _adb_util_complete_local_file "${cur}"
    183     fi
    184 }
    185 
    186 _adb_cmd_shell() {
    187     local serial IFS=$'\n' i cur
    188     local -a args
    189 
    190     serial=$1
    191     i=$2
    192 
    193     cur="${COMP_WORDS[i]}"
    194     if [ "$serial" != "none" ]; then
    195         args=(-s $serial)
    196     fi
    197 
    198     if [[ $i -eq $COMP_CWORD && ${cur:0:1} != "/" ]]; then
    199         paths=$(command adb ${args[@]} shell echo '$'PATH 2> /dev/null | tr -d '\r' | tr : '\n')
    200         COMMAND=$(command adb ${args[@]} shell ls $paths '2>' /dev/null | tr -d '\r' | {
    201             while read -r tmp; do
    202                 command=${tmp##*/}
    203                 printf '%s\n' "$command"
    204             done
    205         })
    206         COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur") )
    207         return 0
    208     fi
    209 
    210     i=$((i+1))
    211     case "$cur" in
    212         ls)
    213             _adb_shell_ls $serial $i
    214             ;;
    215         /*)
    216             _adb_util_list_files $serial "$cur"
    217             ;;
    218         *)
    219             COMPREPLY=( )
    220             ;;
    221     esac
    222 
    223     return 0
    224 }
    225 
    226 _adb_cmd_uninstall() {
    227     local serial i where cur packages
    228 
    229     serial=$1
    230     i=$2
    231     if [ "$serial" != "none" ]; then
    232         args=(-s $serial)
    233     fi
    234 
    235     where=OPTIONS
    236     for ((; i <= COMP_CWORD; i++)); do
    237         cur="${COMP_WORDS[i]}"
    238         case "${cur}" in
    239             -*)
    240                 where=OPTIONS
    241                 ;;
    242             *)
    243                 where=FILE
    244                 break
    245                 ;;
    246         esac
    247     done
    248 
    249     cur="${COMP_WORDS[COMP_CWORD]}"
    250     if [[ $where == OPTIONS ]]; then
    251         COMPREPLY=( $(compgen -W "-k" -- "${cur}") )
    252     fi
    253 
    254     packages="$(
    255         command adb ${args[@]} shell pm list packages '2>' /dev/null 2> /dev/null | tr -d '\r' | {
    256             while read -r tmp; do
    257                 local package=${tmp#package:}
    258                 echo -n "${package} "
    259             done
    260         }
    261     )"
    262 
    263     COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${packages}" -- "${cur}") )
    264 }
    265 
    266 _adb_shell_ls() {
    267     local serial i cur file
    268     local -a args
    269 
    270     serial=$1
    271     i=$2
    272     if [ "$serial" != "none" ]; then
    273         args=(-s $serial)
    274     fi
    275 
    276     where=OPTIONS
    277     for ((; i <= COMP_CWORD; i++)); do
    278         cur="${COMP_WORDS[i]}"
    279         case "${cur}" in
    280             -*)
    281                 where=OPTIONS
    282                 ;;
    283             *)
    284                 where=FILE
    285                 break
    286                 ;;
    287         esac
    288     done
    289 
    290     file="${COMP_WORDS[COMP_CWORD]}"
    291     if [[ ${file} == "" ]]; then
    292         file="/"
    293     fi
    294 
    295     case $where in
    296         OPTIONS)
    297             COMPREPLY=( $(compgen -W "$OPTIONS" -- "$cur") )
    298             _adb_util_list_files $serial "$file"
    299             ;;
    300         FILE)
    301             _adb_util_list_files $serial "$file"
    302             ;;
    303     esac
    304 
    305     return 0
    306 }
    307 
    308 _adb_util_list_files() {
    309     local serial dir IFS=$'\n'
    310     local -a toks
    311     local -a args
    312 
    313     serial="$1"
    314     file="$2"
    315 
    316     if [ "$serial" != "none" ]; then
    317         args=(-s $serial)
    318     fi
    319 
    320     toks=( ${toks[@]-} $(
    321         command adb ${args[@]} shell ls -dF ${file}"*" '2>' /dev/null 2> /dev/null | tr -d '\r' | {
    322             while read -r tmp; do
    323                 filetype=${tmp%% *}
    324                 filename=${tmp:${#filetype}+1}
    325                 if [[ ${filetype:${#filetype}-1:1} == d ]]; then
    326                     printf '%s/\n' "$filename"
    327                 else
    328                     printf '%s\n' "$filename"
    329                 fi
    330             done
    331         }
    332     ))
    333 
    334     # Since we're probably doing file completion here, don't add a space after.
    335     if [[ $(type -t compopt) = "builtin" ]]; then
    336         compopt -o nospace
    337     fi
    338 
    339     COMPREPLY=( ${COMPREPLY[@]:-} "${toks[@]}" )
    340 }
    341 
    342 _adb_util_complete_local_file()
    343 {
    344     local file xspec i j IFS=$'\n'
    345     local -a dirs files
    346 
    347     file=$1
    348     xspec=$2
    349 
    350     # Since we're probably doing file completion here, don't add a space after.
    351     if [[ $(type -t compopt) = "builtin" ]]; then
    352         compopt -o plusdirs
    353         if [[ "${xspec}" == "" ]]; then
    354             COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") )
    355         else
    356             compopt +o filenames
    357             COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") )
    358         fi
    359     else
    360         # Work-around for shells with no compopt
    361 
    362         dirs=( $(compgen -d -- "${cur}" ) )
    363 
    364         if [[ "${xspec}" == "" ]]; then
    365             files=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") )
    366         else
    367             files=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") )
    368         fi
    369 
    370         COMPREPLY=( $(
    371             for i in "${files[@]}"; do
    372                 local skip=
    373                 for j in "${dirs[@]}"; do
    374                     if [[ $i == $j ]]; then
    375                         skip=1
    376                         break
    377                     fi
    378                 done
    379                 [[ -n $skip ]] || printf "%s\n" "$i"
    380             done
    381         ))
    382 
    383         COMPREPLY=( ${COMPREPLY[@]:-} $(
    384             for i in "${dirs[@]}"; do
    385                 printf "%s/\n" "$i"
    386             done
    387         ))
    388     fi
    389 }
    390 
    391 
    392 if [[ $(type -t compopt) = "builtin" ]]; then
    393     complete -F _adb adb
    394 else
    395     complete -o nospace -F _adb adb
    396 fi
    397