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"
     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 
    378 if [[ $(type -t compopt) = "builtin" ]]; then
    379     complete -F _adb adb
    380 else
    381     complete -o nospace -F _adb adb
    382 fi
    383