Skip to content

Commit 9cdbc47

Browse files
authored
[clangd] Add HeaderInsertion config option (#128503)
This is the config file equivalent of the `--header-insertion` command line option Fixes clangd/clangd#2032
1 parent b44b72e commit 9cdbc47

File tree

9 files changed

+48
-10
lines changed

9 files changed

+48
-10
lines changed

Diff for: clang-tools-extra/clangd/ClangdServer.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
455455
CodeCompleteOpts.MainFileSignals = IP->Signals;
456456
CodeCompleteOpts.AllScopes = Config::current().Completion.AllScopes;
457457
CodeCompleteOpts.ArgumentLists = Config::current().Completion.ArgumentLists;
458+
CodeCompleteOpts.InsertIncludes =
459+
Config::current().Completion.HeaderInsertion;
458460
// FIXME(ibiryukov): even if Preamble is non-null, we may want to check
459461
// both the old and the new version in case only one of them matches.
460462
CodeCompleteResult Result = clangd::codeComplete(

Diff for: clang-tools-extra/clangd/CodeComplete.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ struct CompletionCandidate {
294294
std::optional<llvm::StringRef>
295295
headerToInsertIfAllowed(const CodeCompleteOptions &Opts,
296296
CodeCompletionContext::Kind ContextKind) const {
297-
if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
297+
if (Opts.InsertIncludes == Config::HeaderInsertionPolicy::NeverInsert ||
298298
RankedIncludeHeaders.empty() ||
299299
!contextAllowsHeaderInsertion(ContextKind))
300300
return std::nullopt;

Diff for: clang-tools-extra/clangd/CodeComplete.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,8 @@ struct CodeCompleteOptions {
7171
/// Whether to present doc comments as plain-text or markdown.
7272
MarkupKind DocumentationFormat = MarkupKind::PlainText;
7373

74-
enum IncludeInsertion {
75-
IWYU,
76-
NeverInsert,
77-
} InsertIncludes = IncludeInsertion::IWYU;
74+
Config::HeaderInsertionPolicy InsertIncludes =
75+
Config::HeaderInsertionPolicy::IWYU;
7876

7977
/// Whether include insertions for Objective-C code should use #import instead
8078
/// of #include.

Diff for: clang-tools-extra/clangd/Config.h

+7
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,20 @@ struct Config {
147147
FullPlaceholders,
148148
};
149149

150+
enum class HeaderInsertionPolicy {
151+
IWYU, // Include what you use
152+
NeverInsert // Never insert headers as part of code completion
153+
};
154+
150155
/// Configures code completion feature.
151156
struct {
152157
/// Whether code completion includes results that are not visible in current
153158
/// scopes.
154159
bool AllScopes = true;
155160
/// controls the completion options for argument lists.
156161
ArgumentListsPolicy ArgumentLists = ArgumentListsPolicy::FullPlaceholders;
162+
/// Controls if headers should be inserted when completions are accepted
163+
HeaderInsertionPolicy HeaderInsertion = HeaderInsertionPolicy::IWYU;
157164
} Completion;
158165

159166
/// Configures hover feature.

Diff for: clang-tools-extra/clangd/ConfigCompile.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,17 @@ struct FragmentCompiler {
697697
C.Completion.ArgumentLists = *Val;
698698
});
699699
}
700+
if (F.HeaderInsertion) {
701+
if (auto Val =
702+
compileEnum<Config::HeaderInsertionPolicy>("HeaderInsertion",
703+
*F.HeaderInsertion)
704+
.map("IWYU", Config::HeaderInsertionPolicy::IWYU)
705+
.map("Never", Config::HeaderInsertionPolicy::NeverInsert)
706+
.value())
707+
Out.Apply.push_back([Val](const Params &, Config &C) {
708+
C.Completion.HeaderInsertion = *Val;
709+
});
710+
}
700711
}
701712

702713
void compile(Fragment::HoverBlock &&F) {

Diff for: clang-tools-extra/clangd/ConfigFragment.h

+8
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,14 @@ struct Fragment {
341341
/// Delimiters: empty pair of delimiters "()" or "<>"
342342
/// FullPlaceholders: full name of both type and parameter
343343
std::optional<Located<std::string>> ArgumentLists;
344+
/// Add #include directives when accepting code completions. Config
345+
/// equivalent of the CLI option '--header-insertion'
346+
/// Valid values are enum Config::HeaderInsertionPolicy values:
347+
/// "IWYU": Include what you use. Insert the owning header for top-level
348+
/// symbols, unless the header is already directly included or the
349+
/// symbol is forward-declared
350+
/// "NeverInsert": Never insert headers
351+
std::optional<Located<std::string>> HeaderInsertion;
344352
};
345353
CompletionBlock Completion;
346354

Diff for: clang-tools-extra/clangd/ConfigYAML.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ class Parser {
245245
if (auto ArgumentLists = scalarValue(N, "ArgumentLists"))
246246
F.ArgumentLists = *ArgumentLists;
247247
});
248+
Dict.handle("HeaderInsertion", [&](Node &N) {
249+
if (auto HeaderInsertion = scalarValue(N, "HeaderInsertion"))
250+
F.HeaderInsertion = *HeaderInsertion;
251+
});
248252
Dict.parse(N);
249253
}
250254

Diff for: clang-tools-extra/clangd/tool/ClangdMain.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -251,19 +251,19 @@ opt<std::string> EnableFunctionArgSnippets{
251251
init("-1"),
252252
};
253253

254-
opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
254+
opt<Config::HeaderInsertionPolicy> HeaderInsertion{
255255
"header-insertion",
256256
cat(Features),
257257
desc("Add #include directives when accepting code completions"),
258258
init(CodeCompleteOptions().InsertIncludes),
259259
values(
260-
clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
260+
clEnumValN(Config::HeaderInsertionPolicy::IWYU, "iwyu",
261261
"Include what you use. "
262262
"Insert the owning header for top-level symbols, unless the "
263263
"header is already directly included or the symbol is "
264264
"forward-declared"),
265265
clEnumValN(
266-
CodeCompleteOptions::NeverInsert, "never",
266+
Config::HeaderInsertionPolicy::NeverInsert, "never",
267267
"Never insert #include directives as part of code completion")),
268268
};
269269

@@ -668,6 +668,7 @@ class FlagsConfigProvider : public config::Provider {
668668
std::optional<Config::ExternalIndexSpec> IndexSpec;
669669
std::optional<Config::BackgroundPolicy> BGPolicy;
670670
std::optional<Config::ArgumentListsPolicy> ArgumentLists;
671+
std::optional<Config::HeaderInsertionPolicy> HeaderInsertionPolicy;
671672

672673
// If --compile-commands-dir arg was invoked, check value and override
673674
// default path.
@@ -712,6 +713,11 @@ class FlagsConfigProvider : public config::Provider {
712713
BGPolicy = Config::BackgroundPolicy::Skip;
713714
}
714715

716+
// If CLI has set never, use that regardless of what the config files have
717+
if (HeaderInsertion == Config::HeaderInsertionPolicy::NeverInsert) {
718+
HeaderInsertionPolicy = Config::HeaderInsertionPolicy::NeverInsert;
719+
}
720+
715721
if (std::optional<bool> Enable = shouldEnableFunctionArgSnippets()) {
716722
ArgumentLists = *Enable ? Config::ArgumentListsPolicy::FullPlaceholders
717723
: Config::ArgumentListsPolicy::Delimiters;
@@ -726,6 +732,8 @@ class FlagsConfigProvider : public config::Provider {
726732
C.Index.Background = *BGPolicy;
727733
if (ArgumentLists)
728734
C.Completion.ArgumentLists = *ArgumentLists;
735+
if (HeaderInsertionPolicy)
736+
C.Completion.HeaderInsertion = *HeaderInsertionPolicy;
729737
if (AllScopesCompletion.getNumOccurrences())
730738
C.Completion.AllScopes = AllScopesCompletion;
731739

Diff for: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
882882
ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
883883
// Can be disabled via option.
884884
CodeCompleteOptions NoInsertion;
885-
NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
885+
NoInsertion.InsertIncludes = Config::HeaderInsertionPolicy::NeverInsert;
886886
Results = completions(TU, Test.point(), {Sym}, NoInsertion);
887887
EXPECT_THAT(Results.Completions,
888888
ElementsAre(AllOf(named("X"), Not(insertInclude()))));
@@ -1191,7 +1191,7 @@ TEST(CompletionTest, CommentsOnMembersFromHeaderOverloadBundling) {
11911191
int delta(int i);
11921192
11931193
void epsilon(long l);
1194-
1194+
11951195
/// This one has a comment.
11961196
void epsilon(int i);
11971197
};

0 commit comments

Comments
 (0)