xref: /llvm-project/clang/utils/bash-autocomplete.sh (revision 0486c8c3af7bc43415d4a996c07736fefa2ad42d)
1c8068dbbSYuka Takahashi# Please add "source /path/to/bash-autocomplete.sh" to your .bashrc to use this.
24776cb07SYuka Takahashi
34776cb07SYuka Takahashi_clang_filedir()
44776cb07SYuka Takahashi{
54776cb07SYuka Takahashi  # _filedir function provided by recent versions of bash-completion package is
64776cb07SYuka Takahashi  # better than "compgen -f" because the former honors spaces in pathnames while
74776cb07SYuka Takahashi  # the latter doesn't. So we use compgen only when _filedir is not provided.
84776cb07SYuka Takahashi  _filedir 2> /dev/null || COMPREPLY=( $( compgen -f ) )
94776cb07SYuka Takahashi}
104776cb07SYuka Takahashi
11c8068dbbSYuka Takahashi_clang()
12c8068dbbSYuka Takahashi{
134776cb07SYuka Takahashi  local cur prev words cword arg flags w1 w2
144776cb07SYuka Takahashi  # If latest bash-completion is not supported just initialize COMPREPLY and
152a8c18d9SAlexander Kornienko  # initialize variables by setting manually.
164776cb07SYuka Takahashi  _init_completion -n 2> /dev/null
174776cb07SYuka Takahashi  if [[ "$?" != 0 ]]; then
184776cb07SYuka Takahashi    COMPREPLY=()
194776cb07SYuka Takahashi    cword=$COMP_CWORD
204776cb07SYuka Takahashi    cur="${COMP_WORDS[$cword]}"
214776cb07SYuka Takahashi  fi
22c8068dbbSYuka Takahashi
234776cb07SYuka Takahashi  w1="${COMP_WORDS[$cword - 1]}"
244776cb07SYuka Takahashi  if [[ $cword > 1 ]]; then
254776cb07SYuka Takahashi    w2="${COMP_WORDS[$cword - 2]}"
268561c2e2SYuka Takahashi  fi
278561c2e2SYuka Takahashi
2841789e46SYuka Takahashi  # Pass all the current command-line flags to clang, so that clang can handle
2941789e46SYuka Takahashi  # these internally.
3041789e46SYuka Takahashi  # '=' is separated differently by bash, so we have to concat them without ','
3141789e46SYuka Takahashi  for i in `seq 1 $cword`; do
3241789e46SYuka Takahashi    if [[ $i == $cword || "${COMP_WORDS[$(($i+1))]}" == '=' ]]; then
3341789e46SYuka Takahashi      arg="$arg${COMP_WORDS[$i]}"
3441789e46SYuka Takahashi    else
3541789e46SYuka Takahashi      arg="$arg${COMP_WORDS[$i]},"
364776cb07SYuka Takahashi    fi
3741789e46SYuka Takahashi  done
38ba5d4af4SYuka Takahashi
39558f3dd5SYuka Takahashi  # expand ~ to $HOME
40558f3dd5SYuka Takahashi  eval local path=${COMP_WORDS[0]}
41*0486c8c3SBen Langmuir  # Use $'\t' so that bash expands the \t for older versions of sed.
42*0486c8c3SBen Langmuir  flags=$( "$path" --autocomplete="$arg" 2>/dev/null | sed -e $'s/\t.*//' )
4379d21c2aSYuka Takahashi  # If clang is old that it does not support --autocomplete,
4479d21c2aSYuka Takahashi  # fall back to the filename completion.
4579d21c2aSYuka Takahashi  if [[ "$?" != 0 ]]; then
464776cb07SYuka Takahashi    _clang_filedir
4779d21c2aSYuka Takahashi    return
4879d21c2aSYuka Takahashi  fi
4979d21c2aSYuka Takahashi
508c000110SYuka Takahashi  # When clang does not emit any possible autocompletion, or user pushed tab after " ",
518c000110SYuka Takahashi  # just autocomplete files.
5241789e46SYuka Takahashi  if [[ "$flags" == "$(echo -e '\n')" ]]; then
538c000110SYuka Takahashi    # If -foo=<tab> and there was no possible values, autocomplete files.
548c000110SYuka Takahashi    [[ "$cur" == '=' || "$cur" == -*= ]] && cur=""
554776cb07SYuka Takahashi    _clang_filedir
568c000110SYuka Takahashi  elif [[ "$cur" == '=' ]]; then
578c000110SYuka Takahashi    COMPREPLY=( $( compgen -W "$flags" -- "") )
58c8068dbbSYuka Takahashi  else
59a4a87802SYuka Takahashi    # Bash automatically appends a space after '=' by default.
60a4a87802SYuka Takahashi    # Disable it so that it works nicely for options in the form of -foo=bar.
614776cb07SYuka Takahashi    [[ "${flags: -1}" == '=' ]] && compopt -o nospace 2> /dev/null
62c8068dbbSYuka Takahashi    COMPREPLY=( $( compgen -W "$flags" -- "$cur" ) )
63c8068dbbSYuka Takahashi  fi
64c8068dbbSYuka Takahashi}
65c8068dbbSYuka Takahashicomplete -F _clang clang
66