diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 5138e03510f..a44d5308304 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -774,10 +774,28 @@ clang::format::FormatStyle overrideStyle(const Utils::FilePath &fileName) return currentSettingsStyle; } -clang::format::FormatStyle ClangFormatBaseIndenter::styleForFile() const +static std::chrono::milliseconds getCacheTimeout() { - if (getCurrentOverriddenSettings(m_fileName)) - return overrideStyle(m_fileName); + using namespace std::chrono_literals; + bool ok = false; + const int envCacheTimeout = qEnvironmentVariableIntValue("CLANG_FORMAT_CACHE_TIMEOUT", &ok); + return ok ? std::chrono::milliseconds(envCacheTimeout) : 1s; +} + +const clang::format::FormatStyle &ClangFormatBaseIndenter::styleForFile() const +{ + using namespace std::chrono_literals; + static const std::chrono::milliseconds cacheTimeout = getCacheTimeout(); + + QDateTime time = QDateTime::currentDateTime(); + if (m_cachedStyle.expirationTime > time && !(m_cachedStyle.style == clang::format::getNoStyle())) + return m_cachedStyle.style; + + if (getCurrentOverriddenSettings(m_fileName)) { + clang::format::FormatStyle style = overrideStyle(m_fileName); + m_cachedStyle.setCache(style, cacheTimeout); + return m_cachedStyle.style; + } llvm::Expected styleFromProjectFolder = clang::format::getStyle("file", @@ -788,14 +806,17 @@ clang::format::FormatStyle ClangFormatBaseIndenter::styleForFile() const if (styleFromProjectFolder && !(*styleFromProjectFolder == clang::format::getNoStyle())) { addQtcStatementMacros(*styleFromProjectFolder); - return *styleFromProjectFolder; + m_cachedStyle.setCache(*styleFromProjectFolder, cacheTimeout); + return m_cachedStyle.style; } handleAllErrors(styleFromProjectFolder.takeError(), [](const llvm::ErrorInfoBase &) { // do nothing }); - return qtcStyle(); + + m_cachedStyle.setCache(qtcStyle(), 0ms); + return m_cachedStyle.style; } } // namespace ClangFormat diff --git a/src/plugins/clangformat/clangformatbaseindenter.h b/src/plugins/clangformat/clangformatbaseindenter.h index b484654a1f7..1f0674dec57 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.h +++ b/src/plugins/clangformat/clangformatbaseindenter.h @@ -46,7 +46,7 @@ public: std::optional margin() const override; - clang::format::FormatStyle styleForFile() const; + const clang::format::FormatStyle &styleForFile() const; protected: virtual bool formatCodeInsteadOfIndent() const { return false; } @@ -71,6 +71,18 @@ private: ReplacementsToKeep replacementsToKeep, const QChar &typedChar = QChar::Null, bool secondTry = false) const; + + struct CachedStyle { + clang::format::FormatStyle style = clang::format::getNoStyle(); + QDateTime expirationTime; + void setCache(clang::format::FormatStyle newStyle, std::chrono::milliseconds timeout) + { + style = newStyle; + expirationTime = QDateTime::currentDateTime() + timeout; + } + }; + + mutable CachedStyle m_cachedStyle; }; } // namespace ClangFormat diff --git a/src/plugins/clangformat/clangformatutils.cpp b/src/plugins/clangformat/clangformatutils.cpp index 9304599d999..1e3e1a72e33 100644 --- a/src/plugins/clangformat/clangformatutils.cpp +++ b/src/plugins/clangformat/clangformatutils.cpp @@ -31,7 +31,7 @@ using namespace Utils; namespace ClangFormat { -clang::format::FormatStyle qtcStyle() +clang::format::FormatStyle calculateQtcStyle() { clang::format::FormatStyle style = getLLVMStyle(); style.Language = FormatStyle::LK_Cpp; @@ -179,6 +179,12 @@ clang::format::FormatStyle qtcStyle() return style; } +clang::format::FormatStyle qtcStyle() +{ + static clang::format::FormatStyle style = calculateQtcStyle(); + return style; +} + QString projectUniqueId(ProjectExplorer::Project *project) { if (!project)