diff options
author | Yuka Takahashi <yukatkh@gmail.com> | 2017-05-23 18:39:08 +0000 |
---|---|---|
committer | Yuka Takahashi <yukatkh@gmail.com> | 2017-05-23 18:39:08 +0000 |
commit | c8068dbb071725ec8be6c53420138964726cdc38 (patch) | |
tree | 192f34ad42a4c07b778b770b221dc6438df7cb9e | |
parent | 7b0a6aa6426ed1abd844d109ad0b56f6743736b8 (diff) |
[GSoC] Shell autocompletion for clang
Summary:
This is a first patch for GSoC project, bash-completion for clang.
To use this on bash, please run `source clang/utils/bash-autocomplete.sh`.
bash-autocomplete.sh is code for bash-completion.
Simple flag completion and path completion is available in this patch.
Reviewers: teemperor, v.g.vassilev, ruiu, Bigcheese, efriedma
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D33237
llvm-svn: 303670
-rw-r--r-- | clang/CMakeLists.txt | 4 | ||||
-rw-r--r-- | clang/include/clang/Driver/Options.td | 1 | ||||
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 7 | ||||
-rw-r--r-- | clang/test/Driver/autocomplete.c | 6 | ||||
-rw-r--r-- | clang/utils/bash-autocomplete.sh | 14 | ||||
-rw-r--r-- | llvm/include/llvm/Option/OptTable.h | 8 | ||||
-rw-r--r-- | llvm/lib/Option/OptTable.cpp | 14 |
7 files changed, 54 insertions, 0 deletions
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 9e43a103b2bc..c163a2b50429 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -359,6 +359,10 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) PATTERN "*.inc" PATTERN "*.h" ) + + install(PROGRAMS utils/bash-autocomplete.sh + DESTINATION share/clang + ) endif() add_definitions( -D_GNU_SOURCE ) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d812bd8ec032..4f1ea08dfe9f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -469,6 +469,7 @@ def arch__errors__fatal : Flag<["-"], "arch_errors_fatal">; def arch : Separate<["-"], "arch">, Flags<[DriverOption]>; def arch__only : Separate<["-"], "arch_only">; def a : Joined<["-"], "a">; +def autocomplete : Joined<["--"], "autocomplete=">; def bind__at__load : Flag<["-"], "bind_at_load">; def bundle__loader : Separate<["-"], "bundle_loader">; def bundle : Flag<["-"], "bundle">; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f36deff5d734..bec4bf49281e 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1216,6 +1216,13 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { return false; } + if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) { + // Print out all options that start with a given argument. This is used for + // shell autocompletion. + llvm::outs() << llvm::join(Opts->findByPrefix(A->getValue()), " ") << '\n'; + return false; + } + if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) { ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs()); switch (RLT) { diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c new file mode 100644 index 000000000000..94649f243738 --- /dev/null +++ b/clang/test/Driver/autocomplete.c @@ -0,0 +1,6 @@ +// RUN: %clang --autocomplete=-fsyn | FileCheck %s -check-prefix=FSYN +// FSYN: -fsyntax-only +// RUN: %clang --autocomplete=-s | FileCheck %s -check-prefix=STD +// STD: -std={{.*}}-stdlib= +// RUN: %clang --autocomplete=foo | not FileCheck %s -check-prefix=NONE +// NONE: foo diff --git a/clang/utils/bash-autocomplete.sh b/clang/utils/bash-autocomplete.sh new file mode 100644 index 000000000000..a90671251475 --- /dev/null +++ b/clang/utils/bash-autocomplete.sh @@ -0,0 +1,14 @@ +# Please add "source /path/to/bash-autocomplete.sh" to your .bashrc to use this. +_clang() +{ + local cur prev words cword flags + _init_completion -n : || return + + flags=$( clang --autocomplete="$cur" ) + if [[ "$flags" == "" || "$cur" == "" ]]; then + _filedir + else + COMPREPLY=( $( compgen -W "$flags" -- "$cur" ) ) + fi +} +complete -F _clang clang diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h index 390e52774fea..8a323a255ca1 100644 --- a/llvm/include/llvm/Option/OptTable.h +++ b/llvm/include/llvm/Option/OptTable.h @@ -113,6 +113,14 @@ public: return getInfo(id).MetaVar; } + /// Find flags from OptTable which starts with Cur. + /// + /// \param [in] Cur - String prefix that all returned flags need + // to start with. + /// + /// \return The vector of flags which start with Cur. + std::vector<std::string> findByPrefix(StringRef Cur) const; + /// \brief Parse a single argument; returning the new argument and /// updating Index. /// diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp index 7eafb00855d7..b00d21ec8f67 100644 --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -186,6 +186,20 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str, return 0; } +std::vector<std::string> OptTable::findByPrefix(StringRef Cur) const { + std::vector<std::string> Ret; + for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) { + if (!In.Prefixes) + continue; + for (int I = 0; In.Prefixes[I]; I++) { + std::string S = std::string(In.Prefixes[I]) + std::string(In.Name); + if (StringRef(S).startswith(Cur)) + Ret.push_back(S); + } + } + return Ret; +} + Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, unsigned FlagsToInclude, unsigned FlagsToExclude) const { |