From ed5e509966fcdb775926b5650ef71df0b6bd7d45 Mon Sep 17 00:00:00 2001 From: yamaguchi1024 Date: Wed, 16 Aug 2017 07:23:25 +0000 Subject: [PATCH 1/3] clang: new completion A new autocompletion feature for clang, by using its new --autocomplete API to get possible flags dynamically. --- completions/clang | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 completions/clang diff --git a/completions/clang b/completions/clang new file mode 100644 index 00000000000..4a56c4bc2a4 --- /dev/null +++ b/completions/clang @@ -0,0 +1,81 @@ +_clang_filedir() +{ + # _filedir function provided by recent versions of bash-completion package is + # better than "compgen -f" because the former honors spaces in pathnames while + # the latter doesn't. So we use compgen only when _filedir is not provided. + _filedir 2> /dev/null || COMPREPLY=( $( compgen -f ) ) +} + +_clang() +{ + local cur prev words cword arg flags w1 w2 + # If latest bash-completion is not supported just initialize COMPREPLY and + # initialize variables by setting manualy. + _init_completion -n 2> /dev/null + if [[ "$?" != 0 ]]; then + COMPREPLY=() + cword=$COMP_CWORD + cur="${COMP_WORDS[$cword]}" + fi + + w1="${COMP_WORDS[$cword - 1]}" + if [[ $cword > 1 ]]; then + w2="${COMP_WORDS[$cword - 2]}" + fi + + # Clang want to know if -cc1 or -Xclang option is specified or not, because we don't want to show + # cc1 options otherwise. + if [[ "${COMP_WORDS[1]}" == "-cc1" || "$w1" == "-Xclang" ]]; then + arg="#" + fi + + # bash always separates '=' as a token even if there's no space before/after '='. + # On the other hand, '=' is just a regular character for clang options that + # contain '='. For example, "-stdlib=" is defined as is, instead of "-stdlib" and "=". + # So, we need to partially undo bash tokenization here for integrity. + if [[ "$cur" == -* ]]; then + # -foo + arg="$arg$cur" + elif [[ "$w1" == -* && "$cur" == '=' ]]; then + # -foo= + arg="$arg$w1=," + elif [[ "$cur" == -*= ]]; then + # -foo= + arg="$arg$cur," + elif [[ "$w1" == -* ]]; then + # -foo or -foo bar + arg="$arg$w1,$cur" + elif [[ "$w2" == -* && "$w1" == '=' ]]; then + # -foo=bar + arg="$arg$w2=,$cur" + elif [[ ${cur: -1} != '=' && ${cur/=} != $cur ]]; then + # -foo=bar + arg="$arg${cur%=*}=,${cur#*=}" + fi + + # expand ~ to $HOME + eval local path=${COMP_WORDS[0]} + flags=$( "$path" --autocomplete="$arg" 2>/dev/null | sed -e 's/\t.*//' ) + # If clang is old that it does not support --autocomplete, + # fall back to the filename completion. + if [[ "$?" != 0 ]]; then + _clang_filedir + return + fi + + # When clang does not emit any possible autocompletion, or user pushed tab after " ", + # just autocomplete files. + if [[ "$flags" == "$(echo -e '\n')" || "$arg" == "" ]]; then + # If -foo= and there was no possible values, autocomplete files. + [[ "$cur" == '=' || "$cur" == -*= ]] && cur="" + _clang_filedir + elif [[ "$cur" == '=' ]]; then + COMPREPLY=( $( compgen -W "$flags" -- "") ) + else + # Bash automatically appends a space after '=' by default. + # Disable it so that it works nicely for options in the form of -foo=bar. + [[ "${flags: -1}" == '=' ]] && compopt -o nospace 2> /dev/null + COMPREPLY=( $( compgen -W "$flags" -- "$cur" ) ) + fi +} +complete -F _clang clang From 5a7d378aeb722c3c05d1f602444dadd6f327a38e Mon Sep 17 00:00:00 2001 From: yamaguchi1024 Date: Wed, 16 Aug 2017 07:23:25 +0000 Subject: [PATCH 2/3] clang: new completion A new autocompletion feature for clang, by using its new --autocomplete API to get possible flags dynamically. --- completions/Makefile.am | 1 + completions/clang | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 completions/clang diff --git a/completions/Makefile.am b/completions/Makefile.am index d528da6f507..5d3a29a3e98 100644 --- a/completions/Makefile.am +++ b/completions/Makefile.am @@ -53,6 +53,7 @@ bashcomp_DATA = 2to3 \ chrpath \ _chsh \ cksfv \ + clang \ cleanarch \ clisp \ clone_member \ diff --git a/completions/clang b/completions/clang new file mode 100644 index 00000000000..ee1b84e17dc --- /dev/null +++ b/completions/clang @@ -0,0 +1,67 @@ +# clang(1) completion -*- shell-script -*- +_clang() +{ + local cur prev words cword arg flags prev2 + _init_completion || return + + if [[ $cword > 1 ]]; then + prev2="${COMP_WORDS[$cword - 2]}" + fi + + # Clang want to know if -cc1 or -Xclang option is specified or not, because we don't want to show + # cc1 options otherwise. + if [[ "${COMP_WORDS[1]}" == "-cc1" || "$prev" == "-Xclang" ]]; then + arg="#" + fi + + # bash always separates '=' as a token even if there's no space before/after '='. + # On the other hand, '=' is just a regular character for clang options that + # contain '='. For example, "-stdlib=" is defined as is, instead of "-stdlib" and "=". + # So, we need to partially undo bash tokenization here for integrity. + if [[ "$cur" == -* ]]; then + # -foo + arg="$arg$cur" + elif [[ "$prev" == -* && "$cur" == '=' ]]; then + # -foo= + arg="$arg$prev=," + elif [[ "$cur" == -*= ]]; then + # -foo= + arg="$arg$cur," + elif [[ "$prev" == -* ]]; then + # -foo or -foo bar + arg="$arg$prev,$cur" + elif [[ "$prev2" == -* && "$prev" == '=' ]]; then + # -foo=bar + arg="$arg$prev2=,$cur" + elif [[ ${cur: -1} != '=' && ${cur/=} != $cur ]]; then + # -foo=bar + arg="$arg${cur%=*}=,${cur#*=}" + fi + + # expand ~ to $HOME + eval local path=${COMP_WORDS[0]} + flags=$( "$path" --autocomplete="$arg" 2>/dev/null | sed -e 's/\t.*//' ) + # If clang is old that it does not support --autocomplete, + # fall back to the filename completion. + if [[ $? -ne 0 ]]; then + _filedir + return + fi + + # When clang does not emit any possible autocompletion, or user pushed tab after " ", + # just autocomplete files. + if [[ "$flags" == $'\n' || "$arg" == "" ]]; then + # If -foo= and there was no possible values, autocomplete files. + [[ "$cur" == '=' || "$cur" == -*= ]] && cur="" + _filedir + elif [[ "$cur" == '=' ]]; then + COMPREPLY=( $( compgen -W "$flags" -- "") ) + else + # Bash automatically appends a space after '=' by default. + # Disable it so that it works nicely for options in the form of -foo=bar. + [[ "${flags: -1}" == '=' ]] && compopt -o nospace 2> /dev/null + COMPREPLY=( $( compgen -W "$flags" -- "$cur" ) ) + fi +} && +complete -F _clang clang +# ex: filetype=sh From 50ead93133a402a5b5767c99e4a82ddc11ebbafe Mon Sep 17 00:00:00 2001 From: yamaguchi1024 Date: Sun, 17 Sep 2017 11:58:14 +0900 Subject: [PATCH 3/3] Add clang to ubuntu Dockerfile --- test/docker/Dockerfile-ubuntu14 | 1 + 1 file changed, 1 insertion(+) diff --git a/test/docker/Dockerfile-ubuntu14 b/test/docker/Dockerfile-ubuntu14 index dc84ea47058..97761acbca0 100644 --- a/test/docker/Dockerfile-ubuntu14 +++ b/test/docker/Dockerfile-ubuntu14 @@ -39,6 +39,7 @@ RUN dpkg --add-architecture i386 && \ chrpath \ cksfv \ clisp \ + clang \ cowsay \ cppcheck \ cryptsetup-bin \