From 20a304c8e09029c122aa583f5e3337b3ebe92111 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 21 Aug 2019 14:33:13 +0200 Subject: [PATCH] CppEditor: Reuse document for search results Instead of open a document for every entry we do open it only once per search. For that we sort the entries by file path, so that they are clustered together and reuse the last document if the path hasn't changed. This can improve the calculations of the search results drastically. Change-Id: I9c9c1e387624297d84c6a2ca6edb6130f739d295 Reviewed-by: Nikolai Kosjar --- src/plugins/cppeditor/cppeditorwidget.cpp | 67 ++++++++++++++++------- src/plugins/cpptools/usages.h | 6 ++ 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 68774978849..678d5299656 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -346,18 +346,16 @@ void CppEditorWidget::onShowInfoBarAction(const Id &id, bool show) action->setVisible(show); } -static QString getDocumentLine(const QTextDocument &document, int line) +static QString getDocumentLine(QTextDocument *document, int line) { - return document.findBlockByNumber(line - 1).text(); + if (document) + return document->findBlockByNumber(line - 1).text(); + + return {}; } -static QString getFileLine(const QString &path, int line) +static std::unique_ptr getCurrentDocument(const QString &path) { - const IDocument *document = DocumentModel::documentForFilePath(path); - const auto textDocument = qobject_cast(document); - if (textDocument) - return getDocumentLine(*textDocument->document(), line); - const QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec(); QString contents; Utils::TextFileFormat format; @@ -365,11 +363,10 @@ static QString getFileLine(const QString &path, int line) if (Utils::TextFileFormat::readFile(path, defaultCodec, &contents, &format, &error) != Utils::TextFileFormat::ReadSuccess) { qWarning() << "Error reading file " << path << " : " << error; - return QString(); + return {}; } - const QTextDocument tmpDocument{contents}; - return getDocumentLine(tmpDocument, line); + return std::make_unique(contents); } static void onReplaceUsagesClicked(const QString &text, @@ -387,6 +384,43 @@ static void onReplaceUsagesClicked(const QString &text, } } +static QTextDocument *getOpenDocument(const QString &path) +{ + const IDocument *document = DocumentModel::documentForFilePath(path); + if (document) + return qobject_cast(document)->document(); + + return {}; +} + +static void addSearchResults(CppTools::Usages usages, SearchResult &search, const QString &text) +{ + std::sort(usages.begin(), usages.end()); + + std::unique_ptr currentDocument; + QString lastPath; + + for (const CppTools::Usage &usage : usages) { + QTextDocument *document = getOpenDocument(usage.path); + + if (!document) { + if (usage.path != lastPath) { + currentDocument = getCurrentDocument(usage.path); + lastPath = usage.path; + } + document = currentDocument.get(); + } + + const QString lineContent = getDocumentLine(document, usage.line); + + if (lineContent.size()) { + Search::TextRange range{Search::TextPosition(usage.line, usage.column - 1), + Search::TextPosition(usage.line, usage.column + text.length() - 1)}; + search.addResult(usage.path, lineContent, range); + } + } +} + static void findRenameCallback(CppEditorWidget *widget, const QTextCursor &baseCursor, const CppTools::Usages &usages, @@ -413,14 +447,9 @@ static void findRenameCallback(CppEditorWidget *widget, [widget, rename, replacement, baseCursor]() { rename ? widget->renameUsages(replacement, baseCursor) : widget->findUsages(baseCursor); }); - for (const CppTools::Usage &usage : usages) { - const QString lineStr = getFileLine(usage.path, usage.line); - if (lineStr.isEmpty()) - continue; - Search::TextRange range{Search::TextPosition(usage.line, usage.column - 1), - Search::TextPosition(usage.line, usage.column + text.length() - 1)}; - search->addResult(usage.path, lineStr, range); - } + + addSearchResults(usages, *search, text); + search->finishSearch(false); QObject::connect(search, &SearchResult::activated, [](const Core::SearchResultItem& item) { diff --git a/src/plugins/cpptools/usages.h b/src/plugins/cpptools/usages.h index 1e0f502c5e3..3248fc4e905 100644 --- a/src/plugins/cpptools/usages.h +++ b/src/plugins/cpptools/usages.h @@ -51,6 +51,12 @@ public: && first.path == second.path; } + friend bool operator<(const Usage &first, const Usage &second) + { + return std::tie(first.path, first.line, first.column) + < std::tie(second.path, second.line, second.column); + } + public: QString path; int line = 0;