diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h --- a/clang-tools-extra/clangd/Config.h +++ b/clang-tools-extra/clangd/Config.h @@ -147,6 +147,8 @@ bool Parameters = true; bool DeducedTypes = true; bool Designators = true; + // Limit the length of type names in inlay hints. (0 means no limit) + uint32_t TypeNameLimit = 32; } InlayHints; }; diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -611,6 +611,11 @@ Out.Apply.push_back([Value(**F.Designators)](const Params &, Config &C) { C.InlayHints.Designators = Value; }); + if (F.TypeNameLimit) + Out.Apply.push_back( + [Value(**F.TypeNameLimit)](const Params &, Config &C) { + C.InlayHints.TypeNameLimit = Value; + }); } constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error; diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -322,6 +322,8 @@ std::optional> DeducedTypes; /// Show designators in aggregate initialization. std::optional> Designators; + /// Limit the length of type name hints. (0 means no limit) + std::optional> TypeNameLimit; }; InlayHintsBlock InlayHints; }; diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -254,6 +254,10 @@ if (auto Value = boolValue(N, "Designators")) F.Designators = *Value; }); + Dict.handle("TypeNameLimit", [&](Node &N) { + if (auto Value = uint32Value(N, "TypeNameLimit")) + F.TypeNameLimit = *Value; + }); Dict.parse(N); } @@ -375,6 +379,17 @@ return std::nullopt; } + std::optional> uint32Value(Node &N, llvm::StringRef Desc) { + if (auto Scalar = scalarValue(N, Desc)) { + unsigned long long Num; + if (!llvm::getAsUnsignedInteger(**Scalar, 0, Num)) { + return Located(Num, Scalar->Range); + } + } + warning(Desc + " invalid number", N); + return std::nullopt; + } + // Try to parse a list of single scalar values, or just a single value. std::optional>> scalarValues(Node &N) { std::vector> Result; diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -688,7 +688,8 @@ return; std::string TypeName = T.getAsString(Policy); - if (TypeName.length() < TypeNameLimit) + if (Cfg.InlayHints.TypeNameLimit == 0 || + TypeName.length() < Cfg.InlayHints.TypeNameLimit) addInlayHint(R, HintSide::Right, InlayHintKind::Type, Prefix, TypeName, /*Suffix=*/""); } @@ -714,8 +715,6 @@ // the policies are initialized for more details.) PrintingPolicy TypeHintPolicy; PrintingPolicy StructuredBindingPolicy; - - static const size_t TypeNameLimit = 32; }; } // namespace diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -77,6 +77,7 @@ C.InlayHints.Parameters = false; C.InlayHints.DeducedTypes = false; C.InlayHints.Designators = false; + C.InlayHints.TypeNameLimit = 1; return C; } @@ -1324,6 +1325,21 @@ // Omit type hint past a certain length (currently 32) auto var = foo(); )cpp"); + + Config Cfg; + Cfg.InlayHints.TypeNameLimit = 0; + WithContextValue WithCfg(Config::Key, std::move(Cfg)); + + assertTypeHints( + R"cpp( + template + struct A {}; + struct MultipleWords {}; + A foo(); + // Should have type hint with TypeNameLimit = 0 + auto $var[[var]] = foo(); + )cpp", + ExpectedHint{": A", "var"}); } TEST(TypeHints, DefaultTemplateArgs) {