mirror of https://github.com/microsoft/clang.git
[Bash-autocompletion] Pass all flags in shell command-line to Clang
Previously, we passed "#" to --autocomplete to indicate to enable cc1 flags. For example, when -cc1 or -Xclang was passed to bash, bash executed `clang --autocomplete=#-<flag they want to complete>`. However, this was not a good implementation because it depends -Xclang and -cc1 parsing to shell. So I changed this to pass all flags shell has, so that Clang can handle them internally. I had to change many testcases because API spec changed quite a lot. Reviewers: teemperor, v.g.vassilev Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D39342 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326684 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
33cab62ae4
commit
1f37c19ade
|
@ -442,9 +442,9 @@ public:
|
||||||
// FIXME: This should be in CompilationInfo.
|
// FIXME: This should be in CompilationInfo.
|
||||||
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
|
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
|
||||||
|
|
||||||
/// handleAutocompletions - Handle --autocomplete by searching and printing
|
/// HandleAutocompletions - Handle --autocomplete by searching and printing
|
||||||
/// possible flags, descriptions, and its arguments.
|
/// possible flags, descriptions, and its arguments.
|
||||||
void handleAutocompletions(StringRef PassedFlags) const;
|
void HandleAutocompletions(StringRef PassedFlags) const;
|
||||||
|
|
||||||
/// HandleImmediateArgs - Handle any arguments which should be
|
/// HandleImmediateArgs - Handle any arguments which should be
|
||||||
/// treated before building actions or binding tools.
|
/// treated before building actions or binding tools.
|
||||||
|
|
|
@ -1419,44 +1419,56 @@ static void PrintDiagnosticCategories(raw_ostream &OS) {
|
||||||
OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n';
|
OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void Driver::handleAutocompletions(StringRef PassedFlags) const {
|
void Driver::HandleAutocompletions(StringRef PassedFlags) const {
|
||||||
|
if (PassedFlags == "") return;
|
||||||
// Print out all options that start with a given argument. This is used for
|
// Print out all options that start with a given argument. This is used for
|
||||||
// shell autocompletion.
|
// shell autocompletion.
|
||||||
std::vector<std::string> SuggestedCompletions;
|
std::vector<std::string> SuggestedCompletions;
|
||||||
|
std::vector<std::string> Flags;
|
||||||
|
|
||||||
unsigned short DisableFlags =
|
unsigned short DisableFlags =
|
||||||
options::NoDriverOption | options::Unsupported | options::Ignored;
|
options::NoDriverOption | options::Unsupported | options::Ignored;
|
||||||
// We want to show cc1-only options only when clang is invoked as "clang
|
|
||||||
// -cc1". When clang is invoked as "clang -cc1", we add "#" to the beginning
|
// Parse PassedFlags by "," as all the command-line flags are passed to this
|
||||||
// of an --autocomplete option so that the clang driver can distinguish
|
// function separated by ","
|
||||||
// whether it is requested to show cc1-only options or not.
|
StringRef TargetFlags = PassedFlags;
|
||||||
if (PassedFlags.size() > 0 && PassedFlags[0] == '#') {
|
while (TargetFlags != "") {
|
||||||
DisableFlags &= ~options::NoDriverOption;
|
StringRef CurFlag;
|
||||||
PassedFlags = PassedFlags.substr(1);
|
std::tie(CurFlag, TargetFlags) = TargetFlags.split(",");
|
||||||
|
Flags.push_back(std::string(CurFlag));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PassedFlags.find(',') == StringRef::npos) {
|
// We want to show cc1-only options only when clang is invoked with -cc1 or
|
||||||
|
// -Xclang.
|
||||||
|
if (std::find(Flags.begin(), Flags.end(), "-Xclang") != Flags.end() || std::find(Flags.begin(), Flags.end(), "-cc1") != Flags.end())
|
||||||
|
DisableFlags &= ~options::NoDriverOption;
|
||||||
|
|
||||||
|
StringRef Cur;
|
||||||
|
Cur = Flags.at(Flags.size() - 1);
|
||||||
|
StringRef Prev;
|
||||||
|
if (Flags.size() >= 2) {
|
||||||
|
Prev = Flags.at(Flags.size() - 2);
|
||||||
|
SuggestedCompletions = Opts->suggestValueCompletions(Prev, Cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SuggestedCompletions.empty())
|
||||||
|
SuggestedCompletions = Opts->suggestValueCompletions(Cur, "");
|
||||||
|
|
||||||
|
if (SuggestedCompletions.empty()) {
|
||||||
// If the flag is in the form of "--autocomplete=-foo",
|
// If the flag is in the form of "--autocomplete=-foo",
|
||||||
// we were requested to print out all option names that start with "-foo".
|
// we were requested to print out all option names that start with "-foo".
|
||||||
// For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only".
|
// For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only".
|
||||||
SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags);
|
SuggestedCompletions = Opts->findByPrefix(Cur, DisableFlags);
|
||||||
|
|
||||||
// We have to query the -W flags manually as they're not in the OptTable.
|
// We have to query the -W flags manually as they're not in the OptTable.
|
||||||
// TODO: Find a good way to add them to OptTable instead and them remove
|
// TODO: Find a good way to add them to OptTable instead and them remove
|
||||||
// this code.
|
// this code.
|
||||||
for (StringRef S : DiagnosticIDs::getDiagnosticFlags())
|
for (StringRef S : DiagnosticIDs::getDiagnosticFlags())
|
||||||
if (S.startswith(PassedFlags))
|
if (S.startswith(Cur))
|
||||||
SuggestedCompletions.push_back(S);
|
SuggestedCompletions.push_back(S);
|
||||||
} else {
|
|
||||||
// If the flag is in the form of "--autocomplete=foo,bar", we were
|
|
||||||
// requested to print out all option values for "-foo" that start with
|
|
||||||
// "bar". For example,
|
|
||||||
// "--autocomplete=-stdlib=,l" is expanded to "libc++" and "libstdc++".
|
|
||||||
StringRef Option, Arg;
|
|
||||||
std::tie(Option, Arg) = PassedFlags.split(',');
|
|
||||||
SuggestedCompletions = Opts->suggestValueCompletions(Option, Arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sort the autocomplete candidates so that shells print them out in a
|
// Sort the autocomplete candidates so that shells print them out in a
|
||||||
// deterministic order. We could sort in any way, but we chose
|
// deterministic order. We could sort in any way, but we chose
|
||||||
// case-insensitive sorting for consistency with the -help option
|
// case-insensitive sorting for consistency with the -help option
|
||||||
|
@ -1574,7 +1586,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
|
||||||
|
|
||||||
if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) {
|
if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) {
|
||||||
StringRef PassedFlags = A->getValue();
|
StringRef PassedFlags = A->getValue();
|
||||||
handleAutocompletions(PassedFlags);
|
HandleAutocompletions(PassedFlags);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,8 @@
|
||||||
// add/modify flags, change HelpTexts or the values of some flags.
|
// add/modify flags, change HelpTexts or the values of some flags.
|
||||||
|
|
||||||
// Some corner cases.
|
// Some corner cases.
|
||||||
// RUN: %clang --autocomplete= | FileCheck %s -check-prefix=ALL_FLAGS
|
|
||||||
// RUN: %clang --autocomplete=# | FileCheck %s -check-prefix=ALL_FLAGS
|
|
||||||
// Let's pick some example flags that are hopefully unlikely to change.
|
|
||||||
// ALL_FLAGS: -fast
|
|
||||||
// ALL_FLAGS: -fastcp
|
|
||||||
// ALL_FLAGS: -fastf
|
|
||||||
// Just test that this doesn't crash:
|
// Just test that this doesn't crash:
|
||||||
|
// RUN: %clang --autocomplete=
|
||||||
// RUN: %clang --autocomplete=,
|
// RUN: %clang --autocomplete=,
|
||||||
// RUN: %clang --autocomplete==
|
// RUN: %clang --autocomplete==
|
||||||
// RUN: %clang --autocomplete=,,
|
// RUN: %clang --autocomplete=,,
|
||||||
|
@ -17,27 +12,27 @@
|
||||||
|
|
||||||
// RUN: %clang --autocomplete=-fsyn | FileCheck %s -check-prefix=FSYN
|
// RUN: %clang --autocomplete=-fsyn | FileCheck %s -check-prefix=FSYN
|
||||||
// FSYN: -fsyntax-only
|
// FSYN: -fsyntax-only
|
||||||
// RUN: %clang --autocomplete=-std= | FileCheck %s -check-prefix=STD
|
// RUN: %clang --autocomplete=-std | FileCheck %s -check-prefix=STD
|
||||||
// STD: -std= Language standard to compile for
|
// STD: -std= Language standard to compile for
|
||||||
// RUN: %clang --autocomplete=foo | FileCheck %s -check-prefix=FOO
|
// RUN: %clang --autocomplete=foo | FileCheck %s -check-prefix=FOO
|
||||||
// FOO-NOT: foo
|
// FOO-NOT: foo
|
||||||
// RUN: %clang --autocomplete=-stdlib=,l | FileCheck %s -check-prefix=STDLIB
|
// RUN: %clang --autocomplete=-stdlib=,l | FileCheck %s -check-prefix=STDLIB
|
||||||
// STDLIB: libc++
|
// STDLIB: libc++
|
||||||
// STDLIB-NEXT: libstdc++
|
// STDLIB-NEXT: libstdc++
|
||||||
// RUN: %clang --autocomplete=-stdlib=, | FileCheck %s -check-prefix=STDLIBALL
|
// RUN: %clang --autocomplete=-stdlib= | FileCheck %s -check-prefix=STDLIBALL
|
||||||
// STDLIBALL: libc++
|
// STDLIBALL: libc++
|
||||||
// STDLIBALL-NEXT: libstdc++
|
// STDLIBALL-NEXT: libstdc++
|
||||||
// STDLIBALL-NEXT: platform
|
// STDLIBALL-NEXT: platform
|
||||||
// RUN: %clang --autocomplete=-meabi,d | FileCheck %s -check-prefix=MEABI
|
// RUN: %clang --autocomplete=-meabi,d | FileCheck %s -check-prefix=MEABI
|
||||||
// MEABI: default
|
// MEABI: default
|
||||||
// RUN: %clang --autocomplete=-meabi, | FileCheck %s -check-prefix=MEABIALL
|
// RUN: %clang --autocomplete=-meabi | FileCheck %s -check-prefix=MEABIALL
|
||||||
// MEABIALL: 4
|
// MEABIALL: 4
|
||||||
// MEABIALL-NEXT: 5
|
// MEABIALL-NEXT: 5
|
||||||
// MEABIALL-NEXT: default
|
// MEABIALL-NEXT: default
|
||||||
// MEABIALL-NEXT: gnu
|
// MEABIALL-NEXT: gnu
|
||||||
// RUN: %clang --autocomplete=-cl-std=,CL2 | FileCheck %s -check-prefix=CLSTD
|
// RUN: %clang --autocomplete=-cl-std=,CL2 | FileCheck %s -check-prefix=CLSTD
|
||||||
// CLSTD: CL2.0
|
// CLSTD: CL2.0
|
||||||
// RUN: %clang --autocomplete=-cl-std=, | FileCheck %s -check-prefix=CLSTDALL
|
// RUN: %clang --autocomplete=-cl-std= | FileCheck %s -check-prefix=CLSTDALL
|
||||||
// CLSTDALL: cl
|
// CLSTDALL: cl
|
||||||
// CLSTDALL-NEXT: CL
|
// CLSTDALL-NEXT: CL
|
||||||
// CLSTDALL-NEXT: cl1.1
|
// CLSTDALL-NEXT: cl1.1
|
||||||
|
@ -48,7 +43,7 @@
|
||||||
// CLSTDALL-NEXT: CL2.0
|
// CLSTDALL-NEXT: CL2.0
|
||||||
// RUN: %clang --autocomplete=-fno-sanitize-coverage=,f | FileCheck %s -check-prefix=FNOSANICOVER
|
// RUN: %clang --autocomplete=-fno-sanitize-coverage=,f | FileCheck %s -check-prefix=FNOSANICOVER
|
||||||
// FNOSANICOVER: func
|
// FNOSANICOVER: func
|
||||||
// RUN: %clang --autocomplete=-fno-sanitize-coverage=, | FileCheck %s -check-prefix=FNOSANICOVERALL
|
// RUN: %clang --autocomplete=-fno-sanitize-coverage= | FileCheck %s -check-prefix=FNOSANICOVERALL
|
||||||
// FNOSANICOVERALL: 8bit-counters
|
// FNOSANICOVERALL: 8bit-counters
|
||||||
// FNOSANICOVERALL-NEXT: bb
|
// FNOSANICOVERALL-NEXT: bb
|
||||||
// FNOSANICOVERALL-NEXT: edge
|
// FNOSANICOVERALL-NEXT: edge
|
||||||
|
@ -62,41 +57,37 @@
|
||||||
// FNOSANICOVERALL-NEXT: trace-gep
|
// FNOSANICOVERALL-NEXT: trace-gep
|
||||||
// FNOSANICOVERALL-NEXT: trace-pc
|
// FNOSANICOVERALL-NEXT: trace-pc
|
||||||
// FNOSANICOVERALL-NEXT: trace-pc-guard
|
// FNOSANICOVERALL-NEXT: trace-pc-guard
|
||||||
// RUN: %clang --autocomplete=-ffp-contract=, | FileCheck %s -check-prefix=FFPALL
|
// RUN: %clang --autocomplete=-ffp-contract= | FileCheck %s -check-prefix=FFPALL
|
||||||
// FFPALL: fast
|
// FFPALL: fast
|
||||||
// FFPALL-NEXT: off
|
// FFPALL-NEXT: off
|
||||||
// FFPALL-NEXT: on
|
// FFPALL-NEXT: on
|
||||||
// RUN: %clang --autocomplete=-flto=, | FileCheck %s -check-prefix=FLTOALL
|
// RUN: %clang --autocomplete=-flto= | FileCheck %s -check-prefix=FLTOALL
|
||||||
// FLTOALL: full
|
// FLTOALL: full
|
||||||
// FLTOALL-NEXT: thin
|
// FLTOALL-NEXT: thin
|
||||||
// RUN: %clang --autocomplete=-fveclib=, | FileCheck %s -check-prefix=FVECLIBALL
|
// RUN: %clang --autocomplete=-fveclib= | FileCheck %s -check-prefix=FVECLIBALL
|
||||||
// FVECLIBALL: Accelerate
|
// FVECLIBALL: Accelerate
|
||||||
// FVECLIBALL-NEXT: none
|
// FVECLIBALL-NEXT: none
|
||||||
// FVECLIBALL-NEXT: SVML
|
// FVECLIBALL-NEXT: SVML
|
||||||
// RUN: %clang --autocomplete=-fshow-overloads=, | FileCheck %s -check-prefix=FSOVERALL
|
// RUN: %clang --autocomplete=-fshow-overloads= | FileCheck %s -check-prefix=FSOVERALL
|
||||||
// FSOVERALL: all
|
// FSOVERALL: all
|
||||||
// FSOVERALL-NEXT: best
|
// FSOVERALL-NEXT: best
|
||||||
// RUN: %clang --autocomplete=-fvisibility=, | FileCheck %s -check-prefix=FVISIBILITYALL
|
// RUN: %clang --autocomplete=-fvisibility= | FileCheck %s -check-prefix=FVISIBILITYALL
|
||||||
// FVISIBILITYALL: default
|
// FVISIBILITYALL: default
|
||||||
// FVISIBILITYALL-NEXT: hidden
|
// FVISIBILITYALL-NEXT: hidden
|
||||||
// RUN: %clang --autocomplete=-mfloat-abi=, | FileCheck %s -check-prefix=MFLOATABIALL
|
// RUN: %clang --autocomplete=-mfloat-abi= | FileCheck %s -check-prefix=MFLOATABIALL
|
||||||
// MFLOATABIALL: hard
|
// MFLOATABIALL: hard
|
||||||
// MFLOATABIALL-NEXT: soft
|
// MFLOATABIALL-NEXT: soft
|
||||||
// MFLOATABIALL-NEXT: softfp
|
// MFLOATABIALL-NEXT: softfp
|
||||||
// RUN: %clang --autocomplete=-mthread-model, | FileCheck %s -check-prefix=MTHREADMODELALL
|
// RUN: %clang --autocomplete=-mthread-model | FileCheck %s -check-prefix=MTHREADMODELALL
|
||||||
// MTHREADMODELALL: posix
|
// MTHREADMODELALL: posix
|
||||||
// MTHREADMODELALL-NEXT: single
|
// MTHREADMODELALL-NEXT: single
|
||||||
// RUN: %clang --autocomplete=-mrelocation-model, | FileCheck %s -check-prefix=MRELOCMODELALL
|
// RUN: %clang --autocomplete=-mrelocation-model | FileCheck %s -check-prefix=MRELOCMODELALL
|
||||||
// MRELOCMODELALL: dynamic-no-pic
|
// MRELOCMODELALL: dynamic-no-pic
|
||||||
// MRELOCMODELALL-NEXT: pic
|
// MRELOCMODELALL-NEXT: pic
|
||||||
// MRELOCMODELALL-NEXT: ropi
|
// MRELOCMODELALL-NEXT: ropi
|
||||||
// MRELOCMODELALL-NEXT: ropi-rwpi
|
// MRELOCMODELALL-NEXT: ropi-rwpi
|
||||||
// MRELOCMODELALL-NEXT: rwpi
|
// MRELOCMODELALL-NEXT: rwpi
|
||||||
// MRELOCMODELALL-NEXT: static
|
// MRELOCMODELALL-NEXT: static
|
||||||
// RUN: %clang --autocomplete=-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CLANG
|
|
||||||
// MRELOCMODEL_CLANG-NOT: -mrelocation-model
|
|
||||||
// RUN: %clang --autocomplete=#-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1
|
|
||||||
// MRELOCMODEL_CC1: -mrelocation-model
|
|
||||||
// RUN: %clang --autocomplete=-Wma | FileCheck %s -check-prefix=WARNING
|
// RUN: %clang --autocomplete=-Wma | FileCheck %s -check-prefix=WARNING
|
||||||
// WARNING: -Wmacro-redefined
|
// WARNING: -Wmacro-redefined
|
||||||
// WARNING-NEXT: -Wmain
|
// WARNING-NEXT: -Wmain
|
||||||
|
@ -106,7 +97,20 @@
|
||||||
// WARNING-NEXT: -Wmax-unsigned-zero
|
// WARNING-NEXT: -Wmax-unsigned-zero
|
||||||
// RUN: %clang --autocomplete=-Wno-invalid-pp- | FileCheck %s -check-prefix=NOWARNING
|
// RUN: %clang --autocomplete=-Wno-invalid-pp- | FileCheck %s -check-prefix=NOWARNING
|
||||||
// NOWARNING: -Wno-invalid-pp-token
|
// NOWARNING: -Wno-invalid-pp-token
|
||||||
// RUN: %clang --autocomplete=-analyzer-checker, | FileCheck %s -check-prefix=ANALYZER
|
// RUN: %clang --autocomplete=-analyzer-checker | FileCheck %s -check-prefix=ANALYZER
|
||||||
// ANALYZER: unix.Malloc
|
// ANALYZER: unix.Malloc
|
||||||
// RUN: %clang --autocomplete=-std=, | FileCheck %s -check-prefix=STDVAL
|
// RUN: %clang --autocomplete=-std= | FileCheck %s -check-prefix=STDVAL
|
||||||
// STDVAL: c99
|
// STDVAL: c99
|
||||||
|
//
|
||||||
|
// Clang shouldn't autocomplete CC1 options unless -cc1 or -Xclang were provided
|
||||||
|
// RUN: %clang --autocomplete=-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CLANG
|
||||||
|
// MRELOCMODEL_CLANG-NOT: -mrelocation-model
|
||||||
|
// RUN: %clang --autocomplete=-Xclang,-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1
|
||||||
|
// RUN: %clang --autocomplete=-cc1,-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1
|
||||||
|
// MRELOCMODEL_CC1: -mrelocation-model
|
||||||
|
// Make sure it ignores passed flags unlesss they are -Xclang or -cc1
|
||||||
|
// RUN: %clang --autocomplete=foo,bar,,-fsyn | FileCheck %s -check-prefix=FSYN-CORON
|
||||||
|
// FSYN-CORON: -fsyntax-only
|
||||||
|
// Check if they can autocomplete values with coron
|
||||||
|
// RUN: %clang --autocomplete=foo,bar,,,-fno-sanitize-coverage=,f | FileCheck %s -check-prefix=FNOSANICOVER-CORON
|
||||||
|
// FNOSANICOVER-CORON: func
|
||||||
|
|
|
@ -25,35 +25,16 @@ _clang()
|
||||||
w2="${COMP_WORDS[$cword - 2]}"
|
w2="${COMP_WORDS[$cword - 2]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Clang want to know if -cc1 or -Xclang option is specified or not, because we don't want to show
|
# Pass all the current command-line flags to clang, so that clang can handle
|
||||||
# cc1 options otherwise.
|
# these internally.
|
||||||
if [[ "${COMP_WORDS[1]}" == "-cc1" || "$w1" == "-Xclang" ]]; then
|
# '=' is separated differently by bash, so we have to concat them without ','
|
||||||
arg="#"
|
for i in `seq 1 $cword`; do
|
||||||
fi
|
if [[ $i == $cword || "${COMP_WORDS[$(($i+1))]}" == '=' ]]; then
|
||||||
|
arg="$arg${COMP_WORDS[$i]}"
|
||||||
# bash always separates '=' as a token even if there's no space before/after '='.
|
else
|
||||||
# On the other hand, '=' is just a regular character for clang options that
|
arg="$arg${COMP_WORDS[$i]},"
|
||||||
# contain '='. For example, "-stdlib=" is defined as is, instead of "-stdlib" and "=".
|
fi
|
||||||
# So, we need to partially undo bash tokenization here for integrity.
|
done
|
||||||
if [[ "$cur" == -* ]]; then
|
|
||||||
# -foo<tab>
|
|
||||||
arg="$arg$cur"
|
|
||||||
elif [[ "$w1" == -* && "$cur" == '=' ]]; then
|
|
||||||
# -foo=<tab>
|
|
||||||
arg="$arg$w1=,"
|
|
||||||
elif [[ "$cur" == -*= ]]; then
|
|
||||||
# -foo=<tab>
|
|
||||||
arg="$arg$cur,"
|
|
||||||
elif [[ "$w1" == -* ]]; then
|
|
||||||
# -foo <tab> or -foo bar<tab>
|
|
||||||
arg="$arg$w1,$cur"
|
|
||||||
elif [[ "$w2" == -* && "$w1" == '=' ]]; then
|
|
||||||
# -foo=bar<tab>
|
|
||||||
arg="$arg$w2=,$cur"
|
|
||||||
elif [[ ${cur: -1} != '=' && ${cur/=} != $cur ]]; then
|
|
||||||
# -foo=bar<tab>
|
|
||||||
arg="$arg${cur%=*}=,${cur#*=}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# expand ~ to $HOME
|
# expand ~ to $HOME
|
||||||
eval local path=${COMP_WORDS[0]}
|
eval local path=${COMP_WORDS[0]}
|
||||||
|
@ -67,7 +48,7 @@ _clang()
|
||||||
|
|
||||||
# When clang does not emit any possible autocompletion, or user pushed tab after " ",
|
# When clang does not emit any possible autocompletion, or user pushed tab after " ",
|
||||||
# just autocomplete files.
|
# just autocomplete files.
|
||||||
if [[ "$flags" == "$(echo -e '\n')" || "$arg" == "" ]]; then
|
if [[ "$flags" == "$(echo -e '\n')" ]]; then
|
||||||
# If -foo=<tab> and there was no possible values, autocomplete files.
|
# If -foo=<tab> and there was no possible values, autocomplete files.
|
||||||
[[ "$cur" == '=' || "$cur" == -*= ]] && cur=""
|
[[ "$cur" == '=' || "$cur" == -*= ]] && cur=""
|
||||||
_clang_filedir
|
_clang_filedir
|
||||||
|
|
Loading…
Reference in New Issue