forked from qt-creator/qt-creator
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 <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -346,18 +346,16 @@ void CppEditorWidget::onShowInfoBarAction(const Id &id, bool show)
|
|||||||
action->setVisible(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<QTextDocument> getCurrentDocument(const QString &path)
|
||||||
{
|
{
|
||||||
const IDocument *document = DocumentModel::documentForFilePath(path);
|
|
||||||
const auto textDocument = qobject_cast<const TextDocument *>(document);
|
|
||||||
if (textDocument)
|
|
||||||
return getDocumentLine(*textDocument->document(), line);
|
|
||||||
|
|
||||||
const QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec();
|
const QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec();
|
||||||
QString contents;
|
QString contents;
|
||||||
Utils::TextFileFormat format;
|
Utils::TextFileFormat format;
|
||||||
@@ -365,11 +363,10 @@ static QString getFileLine(const QString &path, int line)
|
|||||||
if (Utils::TextFileFormat::readFile(path, defaultCodec, &contents, &format, &error)
|
if (Utils::TextFileFormat::readFile(path, defaultCodec, &contents, &format, &error)
|
||||||
!= Utils::TextFileFormat::ReadSuccess) {
|
!= Utils::TextFileFormat::ReadSuccess) {
|
||||||
qWarning() << "Error reading file " << path << " : " << error;
|
qWarning() << "Error reading file " << path << " : " << error;
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const QTextDocument tmpDocument{contents};
|
return std::make_unique<QTextDocument>(contents);
|
||||||
return getDocumentLine(tmpDocument, line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onReplaceUsagesClicked(const QString &text,
|
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<const TextDocument *>(document)->document();
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addSearchResults(CppTools::Usages usages, SearchResult &search, const QString &text)
|
||||||
|
{
|
||||||
|
std::sort(usages.begin(), usages.end());
|
||||||
|
|
||||||
|
std::unique_ptr<QTextDocument> 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,
|
static void findRenameCallback(CppEditorWidget *widget,
|
||||||
const QTextCursor &baseCursor,
|
const QTextCursor &baseCursor,
|
||||||
const CppTools::Usages &usages,
|
const CppTools::Usages &usages,
|
||||||
@@ -413,14 +447,9 @@ static void findRenameCallback(CppEditorWidget *widget,
|
|||||||
[widget, rename, replacement, baseCursor]() {
|
[widget, rename, replacement, baseCursor]() {
|
||||||
rename ? widget->renameUsages(replacement, baseCursor) : widget->findUsages(baseCursor);
|
rename ? widget->renameUsages(replacement, baseCursor) : widget->findUsages(baseCursor);
|
||||||
});
|
});
|
||||||
for (const CppTools::Usage &usage : usages) {
|
|
||||||
const QString lineStr = getFileLine(usage.path, usage.line);
|
addSearchResults(usages, *search, text);
|
||||||
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);
|
|
||||||
}
|
|
||||||
search->finishSearch(false);
|
search->finishSearch(false);
|
||||||
QObject::connect(search, &SearchResult::activated,
|
QObject::connect(search, &SearchResult::activated,
|
||||||
[](const Core::SearchResultItem& item) {
|
[](const Core::SearchResultItem& item) {
|
||||||
|
@@ -51,6 +51,12 @@ public:
|
|||||||
&& first.path == second.path;
|
&& 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:
|
public:
|
||||||
QString path;
|
QString path;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
|
Reference in New Issue
Block a user