aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2024-03-13 14:57:59 +0100
committerDavid Schulz <david.schulz@qt.io>2024-03-25 08:57:37 +0000
commitd4e775ebc6052bb82000110233fd9852715c4094 (patch)
tree59a914c74275ea2247500ffd5bf53ccf74d039b9 /src
parent8500dd03bfb574d13ae1b02ff62d093eac221214 (diff)
TextEditor: handle syntax highlight in batches
Use an elapsed timer in the syntax highlighter to periodically return from the highlight and push a continue highlight to the end of the event loop. This allows the user to interact with the editor in between those batches. If the user modifies the document in between highlighting batches, the area that still needs a rehighlight is increased if needed. This also reverts 62ea85ee6ad15c8e4d9cb5e35b1f10bee3c49ac7 and the related changes. Task-number: QTCREATORBUG-28727 Change-Id: I7c394dbdff658330bb72f3b68b9928980947db75 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/cppeditor/cppautocompleter.cpp18
-rw-r--r--src/plugins/cppeditor/cppcompletion_test.cpp8
-rw-r--r--src/plugins/cppeditor/cppeditordocument.cpp5
-rw-r--r--src/plugins/cppeditor/cpphighlighter.cpp12
-rw-r--r--src/plugins/cppeditor/cpptoolstestcase.cpp6
-rw-r--r--src/plugins/cppeditor/semantichighlighter.cpp10
-rw-r--r--src/plugins/fakevim/fakevim_test.cpp10
-rw-r--r--src/plugins/glsleditor/glslhighlighter.cpp3
-rw-r--r--src/plugins/languageclient/semantichighlightsupport.cpp6
-rw-r--r--src/plugins/qmljseditor/qmljssemantichighlighter.cpp4
-rw-r--r--src/plugins/texteditor/CMakeLists.txt1
-rw-r--r--src/plugins/texteditor/highlighter_test.cpp7
-rw-r--r--src/plugins/texteditor/highlighterhelper.cpp5
-rw-r--r--src/plugins/texteditor/semantichighlighter.cpp30
-rw-r--r--src/plugins/texteditor/semantichighlighter.h7
-rw-r--r--src/plugins/texteditor/syntaxhighlighter.cpp223
-rw-r--r--src/plugins/texteditor/syntaxhighlighter.h78
-rw-r--r--src/plugins/texteditor/syntaxhighlighterrunner.cpp385
-rw-r--r--src/plugins/texteditor/syntaxhighlighterrunner.h79
-rw-r--r--src/plugins/texteditor/textdocument.cpp49
-rw-r--r--src/plugins/texteditor/textdocument.h5
-rw-r--r--src/plugins/texteditor/texteditor.cpp33
-rw-r--r--src/plugins/texteditor/texteditor.qbs2
-rw-r--r--src/plugins/vcsbase/baseannotationhighlighter.cpp3
-rw-r--r--src/plugins/vcsbase/vcsbaseeditor.cpp6
25 files changed, 224 insertions, 771 deletions
diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp
index 07101318628..e5560e9d969 100644
--- a/src/plugins/cppeditor/cppautocompleter.cpp
+++ b/src/plugins/cppeditor/cppautocompleter.cpp
@@ -6,7 +6,6 @@
#include <cplusplus/MatchingText.h>
#include <texteditor/tabsettings.h>
-#include <texteditor/syntaxhighlighterrunner.h>
#include <QTextBlock>
#include <QTextCursor>
@@ -17,6 +16,7 @@
#include <coreplugin/editormanager/editormanager.h>
#include <texteditor/icodestylepreferences.h>
+#include <texteditor/syntaxhighlighter.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
#include <texteditor/texteditorsettings.h>
@@ -276,9 +276,9 @@ void AutoCompleterTest::testAutoComplete()
TextEditor::BaseTextEditor *cppEditor = creteCppEditor(text);
QVERIFY(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QTextCursor tc = openEditor(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QVERIFY(!tc.isNull());
@@ -339,9 +339,9 @@ void AutoCompleterTest::testSurroundWithSelection()
const QScopeGuard cleanup([] { Core::EditorManager::closeAllEditors(false); });
TextEditor::BaseTextEditor *cppEditor = creteCppEditor(text);
QVERIFY(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QTextCursor tc = openEditor(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QVERIFY(!tc.isNull());
@@ -376,9 +376,9 @@ void AutoCompleterTest::testAutoBackspace()
const QScopeGuard cleanup([] { Core::EditorManager::closeAllEditors(false); });
TextEditor::BaseTextEditor *cppEditor = creteCppEditor(text);
QVERIFY(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QTextCursor tc = openEditor(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QVERIFY(!tc.isNull());
@@ -420,9 +420,9 @@ void AutoCompleterTest::testInsertParagraph()
const QScopeGuard cleanup([] { Core::EditorManager::closeAllEditors(false); });
TextEditor::BaseTextEditor *cppEditor = creteCppEditor(text);
QVERIFY(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QTextCursor tc = openEditor(cppEditor);
- QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
QVERIFY(!tc.isNull());
diff --git a/src/plugins/cppeditor/cppcompletion_test.cpp b/src/plugins/cppeditor/cppcompletion_test.cpp
index cf8b163ab4e..fdc30e16be3 100644
--- a/src/plugins/cppeditor/cppcompletion_test.cpp
+++ b/src/plugins/cppeditor/cppcompletion_test.cpp
@@ -10,7 +10,7 @@
#include <coreplugin/editormanager/editormanager.h>
#include <texteditor/codeassist/iassistproposal.h>
-#include <texteditor/syntaxhighlighterrunner.h>
+#include <texteditor/syntaxhighlighter.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
@@ -146,12 +146,10 @@ public:
TextEditor::BaseTextEditor *cppEditor = qobject_cast<TextEditor::BaseTextEditor *>(m_editor);
if (!cppEditor)
return false;
- if (cppEditor->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated())
+ if (cppEditor->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate())
return true;
return ::CppEditor::Tests::waitForSignalOrTimeout(
- cppEditor->textDocument()->syntaxHighlighterRunner(),
- &SyntaxHighlighterRunner::highlightingFinished,
- 5000);
+ cppEditor->textDocument()->syntaxHighlighter(), &SyntaxHighlighter::finished, 5000);
}
private:
diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp
index 459ae32977a..6f2a67fede4 100644
--- a/src/plugins/cppeditor/cppeditordocument.cpp
+++ b/src/plugins/cppeditor/cppeditordocument.cpp
@@ -20,7 +20,6 @@
#include <texteditor/storagesettings.h>
#include <texteditor/textdocumentlayout.h>
#include <texteditor/texteditorsettings.h>
-#include <texteditor/syntaxhighlighterrunner.h>
#include <utils/infobar.h>
#include <utils/mimeconstants.h>
@@ -164,7 +163,7 @@ QByteArray CppEditorDocument::contentsText() const
void CppEditorDocument::applyFontSettings()
{
- if (TextEditor::SyntaxHighlighterRunner *highlighter = syntaxHighlighterRunner())
+ if (TextEditor::SyntaxHighlighter *highlighter = syntaxHighlighter())
highlighter->clearAllExtraFormats(); // Clear all additional formats since they may have changed
TextDocument::applyFontSettings(); // rehighlights and updates additional formats
if (m_processor)
@@ -408,7 +407,7 @@ BaseEditorDocumentProcessor *CppEditorDocument::processor()
connect(m_processor.data(), &BaseEditorDocumentProcessor::cppDocumentUpdated, this,
[this](const CPlusPlus::Document::Ptr document) {
// Update syntax highlighter
- if (SyntaxHighlighterRunner *highlighter = syntaxHighlighterRunner())
+ if (SyntaxHighlighter *highlighter = syntaxHighlighter())
highlighter->setLanguageFeaturesFlags(document->languageFeatures().flags);
m_overviewModel.update(usesClangd() ? nullptr : document);
diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp
index becebd11886..952d74707a2 100644
--- a/src/plugins/cppeditor/cpphighlighter.cpp
+++ b/src/plugins/cppeditor/cpphighlighter.cpp
@@ -84,8 +84,13 @@ void CppHighlighter::highlightBlock(const QString &text)
const int firstNonSpace = tokens.first().utf16charsBegin();
// Keep "semantic parentheses".
- Parentheses parentheses = Utils::filtered(TextDocumentLayout::parentheses(currentBlock()),
- [](const Parenthesis &p) { return p.source.isValid(); });
+ Parentheses parentheses;
+ if (TextBlockUserData *userData = TextDocumentLayout::textUserData(currentBlock())) {
+ parentheses = Utils::filtered(userData->parentheses(), [](const Parenthesis &p) {
+ return p.source.isValid();
+ });
+ }
+
const auto insertParen = [&parentheses](const Parenthesis &p) { insertSorted(parentheses, p); };
parentheses.reserve(5);
@@ -235,7 +240,8 @@ void CppHighlighter::highlightBlock(const QString &text)
// if the block is ifdefed out, we only store the parentheses, but
// do not adjust the brace depth.
- if (TextDocumentLayout::ifdefedOut(currentBlock())) {
+ if (TextBlockUserData *userData = TextDocumentLayout::textUserData(currentBlock());
+ userData && userData->ifdefedOut()) {
braceDepth = initialBraceDepth;
foldingIndent = initialBraceDepth;
}
diff --git a/src/plugins/cppeditor/cpptoolstestcase.cpp b/src/plugins/cppeditor/cpptoolstestcase.cpp
index b0151e7a813..869bbf9b84d 100644
--- a/src/plugins/cppeditor/cpptoolstestcase.cpp
+++ b/src/plugins/cppeditor/cpptoolstestcase.cpp
@@ -26,7 +26,7 @@
#include <texteditor/codeassist/iassistproposal.h>
#include <texteditor/codeassist/iassistproposalmodel.h>
#include <texteditor/storagesettings.h>
-#include <texteditor/syntaxhighlighterrunner.h>
+#include <texteditor/syntaxhighlighter.h>
#include <texteditor/texteditor.h>
#include <utils/environment.h>
@@ -238,8 +238,8 @@ bool TestCase::openCppEditor(const FilePath &filePath, TextEditor::BaseTextEdito
[e] {
return e->editorWidget()
->textDocument()
- ->syntaxHighlighterRunner()
- ->syntaxInfoUpdated();
+ ->syntaxHighlighter()
+ ->syntaxHighlighterUpToDate();
},
5000))
return false;
diff --git a/src/plugins/cppeditor/semantichighlighter.cpp b/src/plugins/cppeditor/semantichighlighter.cpp
index d841ae19c4e..a2ae3becb79 100644
--- a/src/plugins/cppeditor/semantichighlighter.cpp
+++ b/src/plugins/cppeditor/semantichighlighter.cpp
@@ -8,7 +8,6 @@
#include <texteditor/syntaxhighlighter.h>
#include <texteditor/textdocument.h>
#include <texteditor/textdocumentlayout.h>
-#include <texteditor/syntaxhighlighterrunner.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -67,12 +66,15 @@ void SemanticHighlighter::run()
Parentheses SemanticHighlighter::getClearedParentheses(const QTextBlock &block)
{
- Parentheses parens = TextDocumentLayout::parentheses(block);
+ Parentheses parens;
+ if (TextBlockUserData *userData = TextDocumentLayout::textUserData(block))
+ parens = userData->parentheses();
if (m_seenBlocks.insert(block.blockNumber()).second) {
parens = Utils::filtered(parens, [](const Parenthesis &p) {
return p.source != parenSource();
});
}
+
return parens;
}
@@ -107,7 +109,7 @@ void SemanticHighlighter::handleHighlighterResults()
QElapsedTimer t;
t.start();
- SyntaxHighlighterRunner *highlighter = m_baseTextDocument->syntaxHighlighterRunner();
+ SyntaxHighlighter *highlighter = m_baseTextDocument->syntaxHighlighter();
QTC_ASSERT(highlighter, return);
incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap);
@@ -195,7 +197,7 @@ void SemanticHighlighter::onHighlighterFinished()
t.start();
if (!m_watcher->isCanceled() && documentRevision() == m_revision) {
- SyntaxHighlighterRunner *highlighter = m_baseTextDocument->syntaxHighlighterRunner();
+ SyntaxHighlighter *highlighter = m_baseTextDocument->syntaxHighlighter();
if (QTC_GUARD(highlighter)) {
qCDebug(log) << "onHighlighterFinished() - clearing formats";
clearExtraAdditionalFormatsUntilEnd(highlighter, m_watcher->future());
diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp
index c81a40a2280..ac1f0a5797c 100644
--- a/src/plugins/fakevim/fakevim_test.cpp
+++ b/src/plugins/fakevim/fakevim_test.cpp
@@ -9,9 +9,9 @@
#include "fakevimhandler.h"
#include <coreplugin/editormanager/editormanager.h>
-#include <texteditor/texteditor.h>
+#include <texteditor/syntaxhighlighter.h>
#include <texteditor/textdocument.h>
-#include <texteditor/syntaxhighlighterrunner.h>
+#include <texteditor/texteditor.h>
#include <QtTest>
#include <QTextEdit>
@@ -350,7 +350,7 @@ struct FakeVimTester::TestData
void doCommand(const char *cmd) { doCommand(_(cmd)); }
void doKeys(const QString &keys) {
handler->handleInput(keys);
- QTRY_VERIFY(editor()->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(editor()->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
}
void doKeys(const char *keys) { doKeys(_(keys)); }
@@ -364,7 +364,7 @@ struct FakeVimTester::TestData
else
i = 0;
editor()->document()->setPlainText(_(str));
- QTRY_VERIFY(editor()->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(editor()->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
setPosition(i);
QCOMPARE(position(), i);
}
@@ -375,7 +375,7 @@ struct FakeVimTester::TestData
QTextCursor tc = editor()->textCursor();
tc.insertText(_(text));
editor()->setTextCursor(tc);
- QTRY_VERIFY(editor()->textDocument()->syntaxHighlighterRunner()->syntaxInfoUpdated());
+ QTRY_VERIFY(editor()->textDocument()->syntaxHighlighter()->syntaxHighlighterUpToDate());
}
// Simulate external position change.
diff --git a/src/plugins/glsleditor/glslhighlighter.cpp b/src/plugins/glsleditor/glslhighlighter.cpp
index eae8419a049..a6da1d6221a 100644
--- a/src/plugins/glsleditor/glslhighlighter.cpp
+++ b/src/plugins/glsleditor/glslhighlighter.cpp
@@ -190,7 +190,8 @@ void GlslHighlighter::highlightBlock(const QString &text)
// if the block is ifdefed out, we only store the parentheses, but
// do not adjust the brace depth.
- if (TextDocumentLayout::ifdefedOut(currentBlock())) {
+ if (TextBlockUserData *userData = TextDocumentLayout::textUserData(currentBlock());
+ userData && userData->ifdefedOut()) {
braceDepth = initialBraceDepth;
foldingIndent = initialBraceDepth;
}
diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp
index b7434de18e0..431d84279df 100644
--- a/src/plugins/languageclient/semantichighlightsupport.cpp
+++ b/src/plugins/languageclient/semantichighlightsupport.cpp
@@ -10,7 +10,7 @@
#include <texteditor/syntaxhighlighter.h>
#include <texteditor/texteditor.h>
#include <texteditor/texteditorsettings.h>
-#include <texteditor/syntaxhighlighterrunner.h>
+#include <texteditor/syntaxhighlighter.h>
#include <utils/algorithm.h>
#include <utils/mimeutils.h>
@@ -183,7 +183,7 @@ void SemanticTokenSupport::queueDocumentReload(TextEditor::TextDocument *doc)
void SemanticTokenSupport::clearHighlight(TextEditor::TextDocument *doc)
{
if (m_tokens.contains(doc->filePath())){
- if (TextEditor::SyntaxHighlighterRunner *highlighter = doc->syntaxHighlighterRunner())
+ if (TextEditor::SyntaxHighlighter *highlighter = doc->syntaxHighlighter())
highlighter->clearAllExtraFormats();
}
}
@@ -413,7 +413,7 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath, bool force
TextDocument *doc = TextDocument::textDocumentForFilePath(filePath);
if (!doc || LanguageClientManager::clientForDocument(doc) != m_client)
return;
- SyntaxHighlighterRunner *highlighter = doc->syntaxHighlighterRunner();
+ SyntaxHighlighter *highlighter = doc->syntaxHighlighter();
if (!highlighter)
return;
const VersionedTokens versionedTokens = m_tokens.value(filePath);
diff --git a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
index c414684df7a..67e14dfbcd5 100644
--- a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
+++ b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
@@ -569,7 +569,7 @@ void SemanticHighlighter::applyResults(int from, int to)
if (m_enableHighlighting)
TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
- m_document->syntaxHighlighterRunner(), m_watcher.future(), from, to, m_extraFormats);
+ m_document->syntaxHighlighter(), m_watcher.future(), from, to, m_extraFormats);
}
void SemanticHighlighter::finished()
@@ -584,7 +584,7 @@ void SemanticHighlighter::finished()
if (m_enableHighlighting)
TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
- m_document->syntaxHighlighterRunner(), m_watcher.future());
+ m_document->syntaxHighlighter(), m_watcher.future());
}
void SemanticHighlighter::run(QPromise<Use> &promise,
diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt
index c36d4121ece..e766ec06a10 100644
--- a/src/plugins/texteditor/CMakeLists.txt
+++ b/src/plugins/texteditor/CMakeLists.txt
@@ -96,7 +96,6 @@ add_qtc_plugin(TextEditor
snippets/snippetssettingspage.cpp snippets/snippetssettingspage.h
storagesettings.cpp storagesettings.h
syntaxhighlighter.cpp syntaxhighlighter.h
- syntaxhighlighterrunner.cpp syntaxhighlighterrunner.h
tabsettings.cpp tabsettings.h
tabsettingswidget.cpp tabsettingswidget.h
textdocument.cpp textdocument.h
diff --git a/src/plugins/texteditor/highlighter_test.cpp b/src/plugins/texteditor/highlighter_test.cpp
index d50c560e23a..2cbd2b75d57 100644
--- a/src/plugins/texteditor/highlighter_test.cpp
+++ b/src/plugins/texteditor/highlighter_test.cpp
@@ -1,11 +1,10 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include "syntaxhighlighterrunner.h"
-
#include "highlighter_test.h"
#include "fontsettings.h"
+#include "syntaxhighlighter.h"
#include "textdocument.h"
#include "texteditor.h"
#include "texteditorsettings.h"
@@ -61,7 +60,7 @@ void GenerigHighlighterTests::initTestCase()
m_editor->editorWidget()->configureGenericHighlighter(
Utils::mimeTypeForName(Utils::Constants::JSON_MIMETYPE));
QVERIFY(m_editor);
- m_editor->textDocument()->syntaxHighlighterRunner()->rehighlight();
+ m_editor->textDocument()->syntaxHighlighter()->rehighlight();
}
using FormatRanges = QList<QTextLayout::FormatRange>;
@@ -214,7 +213,7 @@ void GenerigHighlighterTests::testPreeditText()
block.layout()->setPreeditArea(7, "uaf");
c.endEditBlock();
- m_editor->textDocument()->syntaxHighlighterRunner()->rehighlight();
+ m_editor->textDocument()->syntaxHighlighter()->rehighlight();
const FormatRanges formatRanges = {{0, 4, toFormat(C_VISUAL_WHITESPACE)},
{4, 3, toFormat(C_TYPE)},
diff --git a/src/plugins/texteditor/highlighterhelper.cpp b/src/plugins/texteditor/highlighterhelper.cpp
index 6aa98439c05..e25b935f8ac 100644
--- a/src/plugins/texteditor/highlighterhelper.cpp
+++ b/src/plugins/texteditor/highlighterhelper.cpp
@@ -9,7 +9,6 @@
#include "texteditor.h"
#include "texteditorsettings.h"
#include "texteditortr.h"
-#include "syntaxhighlighterrunner.h"
#include <coreplugin/editormanager/documentmodel.h>
#include <coreplugin/icore.h>
@@ -210,8 +209,8 @@ void reload()
highlightRepository()->reload();
for (auto editor : Core::DocumentModel::editorsForOpenedDocuments()) {
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) {
- if (auto highlighterRunner = textEditor->textDocument()->syntaxHighlighterRunner();
- highlighterRunner && highlighterRunner->useGenericHighlighter()) {
+ if (auto highlighter = textEditor->textDocument()->syntaxHighlighter();
+ highlighter && qobject_cast<SyntaxHighlighter*>(highlighter)) {
textEditor->editorWidget()->configureGenericHighlighter();
}
}
diff --git a/src/plugins/texteditor/semantichighlighter.cpp b/src/plugins/texteditor/semantichighlighter.cpp
index 9cee346d8b0..0c385d2e4b5 100644
--- a/src/plugins/texteditor/semantichighlighter.cpp
+++ b/src/plugins/texteditor/semantichighlighter.cpp
@@ -5,7 +5,6 @@
#include "syntaxhighlighter.h"
#include "texteditorsettings.h"
-#include "syntaxhighlighterrunner.h"
#include <utils/qtcassert.h>
@@ -75,7 +74,7 @@ const Ranges rangesForResult(
}
void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
- SyntaxHighlighterRunner *highlighter,
+ SyntaxHighlighter *highlighter,
const QFuture<HighlightingResult> &future,
int from,
int to,
@@ -114,21 +113,17 @@ void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
formatRanges[range.block].append(range.formatRange);
}
- QList<int> clearBlockNumberVector;
- QMap<int, QList<QTextLayout::FormatRange>> blockNumberMap;
for (auto &[block, ranges] : formatRanges) {
while (currentBlock < block) {
- clearBlockNumberVector.append(currentBlock.blockNumber());
+ highlighter->clearExtraFormats(currentBlock);
currentBlock = currentBlock.next();
}
- blockNumberMap[block.blockNumber()] = ranges;
+ highlighter->setExtraFormats(block, std::move(ranges));
currentBlock = block.next();
}
- highlighter->clearExtraFormats(clearBlockNumberVector);
- highlighter->setExtraFormats(blockNumberMap);
}
-void SemanticHighlighter::setExtraAdditionalFormats(SyntaxHighlighterRunner *highlighter,
+void SemanticHighlighter::setExtraAdditionalFormats(SyntaxHighlighter *highlighter,
const QList<HighlightingResult> &results,
const QHash<int, QTextCharFormat> &kindToFormat)
{
@@ -139,19 +134,19 @@ void SemanticHighlighter::setExtraAdditionalFormats(SyntaxHighlighterRunner *hig
QTextDocument *doc = highlighter->document();
QTC_ASSERT(doc, return );
- QMap<int, QList<QTextLayout::FormatRange>> blockNumberMap;
+ std::map<QTextBlock, QVector<QTextLayout::FormatRange>> formatRanges;
- for (const HighlightingResult &result : results) {
- const Ranges ranges = rangesForResult(result, doc, kindToFormat);
- for (const Range &range : ranges)
- blockNumberMap[range.block.blockNumber()].append(range.formatRange);
+ for (auto result : results) {
+ for (const Range &range : rangesForResult(result, doc, kindToFormat))
+ formatRanges[range.block].append(range.formatRange);
}
- highlighter->setExtraFormats(blockNumberMap);
+ for (auto &[block, ranges] : formatRanges)
+ highlighter->setExtraFormats(block, std::move(ranges));
}
void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
- SyntaxHighlighterRunner *highlighter, const QFuture<HighlightingResult> &future)
+ SyntaxHighlighter *highlighter, const QFuture<HighlightingResult> &future)
{
const QTextDocument * const doc = highlighter->document();
QTextBlock firstBlockToClear = doc->begin();
@@ -168,7 +163,6 @@ void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
QList<int> clearBlockNumberVector;
for (QTextBlock b = firstBlockToClear; b.isValid(); b = b.next())
- clearBlockNumberVector.append(b.blockNumber());
+ highlighter->clearExtraFormats(b);
- highlighter->clearExtraFormats(clearBlockNumberVector);
}
diff --git a/src/plugins/texteditor/semantichighlighter.h b/src/plugins/texteditor/semantichighlighter.h
index ad1d854b834..f8ae30a0eda 100644
--- a/src/plugins/texteditor/semantichighlighter.h
+++ b/src/plugins/texteditor/semantichighlighter.h
@@ -21,7 +21,6 @@ QT_END_NAMESPACE
namespace TextEditor {
class SyntaxHighlighter;
-class SyntaxHighlighterRunner;
class TEXTEDITOR_EXPORT HighlightingResult
{
@@ -74,7 +73,7 @@ using Splitter = std::function<const QList<std::pair<HighlightingResult, QTextBl
// the (to-1).line result.
// Requires that results of the Future are ordered by line.
void TEXTEDITOR_EXPORT
-incrementalApplyExtraAdditionalFormats(SyntaxHighlighterRunner *highlighter,
+incrementalApplyExtraAdditionalFormats(SyntaxHighlighter *highlighter,
const QFuture<HighlightingResult> &future,
int from,
int to,
@@ -85,7 +84,7 @@ incrementalApplyExtraAdditionalFormats(SyntaxHighlighterRunner *highlighter,
// indicated by Result::kind and kindToFormat to the correct location using
// SyntaxHighlighter::setExtraFormats. In contrast to
// incrementalApplyExtraAdditionalFormats the results do not have to be ordered by line.
-void TEXTEDITOR_EXPORT setExtraAdditionalFormats(SyntaxHighlighterRunner *highlighter,
+void TEXTEDITOR_EXPORT setExtraAdditionalFormats(SyntaxHighlighter *highlighter,
const HighlightingResults &results,
const QHash<int, QTextCharFormat> &kindToFormat);
@@ -93,7 +92,7 @@ void TEXTEDITOR_EXPORT setExtraAdditionalFormats(SyntaxHighlighterRunner *highli
// until the end of the document.
// Requires that results of the Future are ordered by line.
void TEXTEDITOR_EXPORT clearExtraAdditionalFormatsUntilEnd(
- SyntaxHighlighterRunner *highlighter, const QFuture<HighlightingResult> &future);
+ SyntaxHighlighter *highlighter, const QFuture<HighlightingResult> &future);
} // namespace SemanticHighlighter
} // namespace TextEditor
diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp
index f7db190852d..0162cdeeff0 100644
--- a/src/plugins/texteditor/syntaxhighlighter.cpp
+++ b/src/plugins/texteditor/syntaxhighlighter.cpp
@@ -25,8 +25,6 @@ enum HighlighterTypeProperty
class SyntaxHighlighterPrivate
{
- SyntaxHighlighter *q_ptr = nullptr;
- Q_DECLARE_PUBLIC(SyntaxHighlighter)
public:
SyntaxHighlighterPrivate() = default;
@@ -37,8 +35,10 @@ public:
QPointer<QTextDocument> doc;
+ void updateFormats(int from, int charsRemoved, int charsAdded);
void reformatBlocks(int from, int charsRemoved, int charsAdded);
- void reformatBlock(const QTextBlock &block, int from, int charsRemoved, int charsAdded);
+ void reformatBlocks();
+ void reformatBlock(const QTextBlock &block);
inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) {
inReformatBlocks = true;
@@ -48,7 +48,7 @@ public:
inReformatBlocks = false;
}
- void applyFormatChanges(int from, int charsRemoved, int charsAdded);
+ void applyFormatChanges();
void updateFormats(const FontSettings &fontSettings);
FontSettings fontSettings;
@@ -61,6 +61,11 @@ public:
QList<std::pair<int,TextStyle>> formatCategories;
QTextCharFormat whitespaceFormat;
QString mimeType;
+ bool syntaxInfoUpToDate = false;
+ int highlightStartBlock = 0;
+ int highlightEndBlock = 0;
+ QSet<int> forceRehighlightBlocks;
+ SyntaxHighlighter *q;
};
static bool adjustRange(QTextLayout::FormatRange &range, int from, int charsDelta)
@@ -77,31 +82,30 @@ static bool adjustRange(QTextLayout::FormatRange &range, int from, int charsDelt
void SyntaxHighlighter::delayedRehighlight()
{
- Q_D(SyntaxHighlighter);
if (!d->rehighlightPending)
return;
d->rehighlightPending = false;
- if (document()->isEmpty())
- return;
-
rehighlight();
}
+void SyntaxHighlighter::continueRehighlight()
+{
+ d->reformatBlocks();
+}
+
#ifdef WITH_TESTS
SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent, const FontSettings &fontsettings)
- : QObject(parent), d_ptr(new SyntaxHighlighterPrivate(fontsettings))
+ : QObject(parent), d(new SyntaxHighlighterPrivate(fontsettings))
{
- d_ptr->q_ptr = this;
+ d->q = this;
if (parent)
setDocument(parent);
}
#endif
-void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, int charsAdded)
+void SyntaxHighlighterPrivate::applyFormatChanges()
{
- bool formatsChanged = false;
-
QTextLayout *layout = currentBlock.layout();
QList<QTextLayout::FormatRange> ranges;
@@ -111,12 +115,6 @@ void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, in
return range.format.property(SyntaxHighlight).toBool();
});
- if (currentBlock.contains(from)) {
- const int charsDelta = charsAdded - charsRemoved;
- for (QTextLayout::FormatRange &range : ranges)
- formatsChanged |= adjustRange(range, from - currentBlock.position(), charsDelta);
- }
-
QTextCharFormat emptyFormat;
QTextLayout::FormatRange r;
@@ -157,7 +155,7 @@ void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, in
newRanges << r;
}
- formatsChanged = formatsChanged || (newRanges.size() != oldRanges.size());
+ bool formatsChanged = (newRanges.size() != oldRanges.size());
for (int i = 0; !formatsChanged && i < newRanges.size(); ++i) {
const QTextLayout::FormatRange &o = oldRanges.at(i);
@@ -174,85 +172,103 @@ void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, in
void SyntaxHighlighter::reformatBlocks(int from, int charsRemoved, int charsAdded)
{
- Q_D(SyntaxHighlighter);
if (!d->inReformatBlocks)
d->reformatBlocks(from, charsRemoved, charsAdded);
}
-void SyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded)
+void SyntaxHighlighterPrivate::updateFormats(int from, int charsRemoved, int charsAdded)
{
- Q_Q(SyntaxHighlighter);
- foldValidator.reset();
+ bool formatsChanged = false;
- rehighlightPending = false;
+ const QTextBlock block = doc->findBlock(from);
+ QTextLayout *layout = block.layout();
- QTextBlock block = doc->findBlock(from);
- if (!block.isValid())
- return;
+ QList<QTextLayout::FormatRange> ranges = layout->formats();
- int endPosition;
- QTextBlock lastBlock = doc->findBlock(from + charsAdded + (charsRemoved > 0 ? 1 : 0));
- if (lastBlock.isValid())
- endPosition = lastBlock.position() + lastBlock.length();
- else
- endPosition = doc->lastBlock().position() + doc->lastBlock().length();
+ const int charsDelta = charsAdded - charsRemoved;
+ for (QTextLayout::FormatRange &range : ranges)
+ formatsChanged |= adjustRange(range, from - block.position(), charsDelta);
- bool forceHighlightOfNextBlock = false;
+ if (formatsChanged) {
+ layout->setFormats(ranges);
+ doc->markContentsDirty(block.position(), block.length());
+ }
+}
- QList<SyntaxHighlighter::Result> vecRes;
+void SyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded)
+{
+ updateFormats(from, charsRemoved, charsAdded);
- SyntaxHighlighter::Result resStart;
- resStart.m_state = SyntaxHighlighter::State::Start;
- vecRes << resStart;
+ QTextBlock block = doc->findBlock(from);
+ if (block.isValid() && block.blockNumber() < highlightStartBlock)
+ highlightStartBlock = block.blockNumber();
+ block = doc->findBlock(from + charsAdded + (charsRemoved > 0 ? 1 : 0));
+ if (!block.isValid())
+ highlightEndBlock = doc->blockCount() - 1;
+ else if (block.blockNumber() > highlightEndBlock)
+ highlightEndBlock = block.blockNumber();
- while (block.isValid() && (block.position() < endPosition || forceHighlightOfNextBlock)) {
- if (QThread::currentThread()->isInterruptionRequested() || q->isInterrupted()) {
- inReformatBlocks = false;
- emit q->resultsReady({});
- return;
- }
+ reformatBlocks();
+}
- const int stateBeforeHighlight = block.userState();
+void SyntaxHighlighterPrivate::reformatBlocks()
+{
+ QElapsedTimer et;
+ et.start();
- reformatBlock(block, from, charsRemoved, charsAdded);
+ syntaxInfoUpToDate = false;
+ rehighlightPending = false;
- forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight);
+ foldValidator.reset();
- SyntaxHighlighter::Result res;
- res.m_formatRanges = block.layout()->formats();
- res.fillByBlock(block);
- vecRes << res;
+ bool forceHighlightOfNextBlock = false;
+ QTextBlock block = doc->findBlockByNumber(highlightStartBlock);
+ QTC_ASSERT(block.isValid(), block = doc->firstBlock());
+ QTextBlock endBlock = doc->findBlockByNumber(highlightEndBlock);
+ QTC_ASSERT(endBlock.isValid(), endBlock = doc->lastBlock());
- // Sending data to the text editor in chunks of 200 blocks is a sensible approach.
- // This helps avoid UI slowdowns when applying formatting to the text.
- if (vecRes.size() >= 200) {
- emit q->resultsReady(vecRes);
- vecRes.clear();
+ while (block.isValid()) {
+ if (et.elapsed() > 20)
+ break;
+
+ const int stateBeforeHighlight = block.userState();
+
+ if (forceHighlightOfNextBlock || forceRehighlightBlocks.contains(block.blockNumber())
+ || block.blockNumber() <= highlightEndBlock) {
+ reformatBlock(block);
+ forceRehighlightBlocks.remove(block.blockNumber());
+ forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight);
}
+ highlightStartBlock = block.blockNumber();
+ if (block == endBlock && !forceHighlightOfNextBlock)
+ break;
block = block.next();
}
formatChanges.clear();
-
foldValidator.finalize();
- SyntaxHighlighter::Result res;
- res.m_state = SyntaxHighlighter::State::Done;
- vecRes << res;
- emit q->resultsReady(vecRes);
+
+ if (endBlock.isValid() && block.isValid() && block.blockNumber() < endBlock.blockNumber()) {
+ QMetaObject::invokeMethod(q, &SyntaxHighlighter::continueRehighlight, Qt::QueuedConnection);
+ if (forceHighlightOfNextBlock)
+ forceRehighlightBlocks << block.blockNumber();
+ } else {
+ highlightEndBlock = 0;
+ syntaxInfoUpToDate = true;
+ emit q->finished();
+ }
}
-void SyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block, int from, int charsRemoved, int charsAdded)
+void SyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
{
- Q_Q(SyntaxHighlighter);
-
- Q_ASSERT_X(!currentBlock.isValid(), "SyntaxHighlighter::reformatBlock()", "reFormatBlock() called recursively");
+ QTC_ASSERT(!currentBlock.isValid(), return);
currentBlock = block;
formatChanges.fill(QTextCharFormat(), block.length() - 1);
q->highlightBlock(block.text());
- applyFormatChanges(from, charsRemoved, charsAdded);
+ applyFormatChanges();
foldValidator.process(currentBlock);
@@ -293,9 +309,9 @@ void SyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block, int from,
Constructs a SyntaxHighlighter with the given \a parent.
*/
SyntaxHighlighter::SyntaxHighlighter(QObject *parent)
- : QObject(parent), d_ptr(new SyntaxHighlighterPrivate)
+ : QObject(parent), d(new SyntaxHighlighterPrivate)
{
- d_ptr->q_ptr = this;
+ d->q = this;
}
/*!
@@ -304,9 +320,9 @@ SyntaxHighlighter::SyntaxHighlighter(QObject *parent)
SyntaxHighlighter.
*/
SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent)
- : QObject(parent), d_ptr(new SyntaxHighlighterPrivate)
+ : QObject(parent), d(new SyntaxHighlighterPrivate)
{
- d_ptr->q_ptr = this;
+ d->q = this;
if (parent)
setDocument(parent);
}
@@ -317,9 +333,9 @@ SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent)
the SyntaxHighlighter.
*/
SyntaxHighlighter::SyntaxHighlighter(QTextEdit *parent)
- : QObject(parent), d_ptr(new SyntaxHighlighterPrivate)
+ : QObject(parent), d(new SyntaxHighlighterPrivate)
{
- d_ptr->q_ptr = this;
+ d->q = this;
if (parent)
setDocument(parent->document());
}
@@ -338,7 +354,6 @@ SyntaxHighlighter::~SyntaxHighlighter()
*/
void SyntaxHighlighter::setDocument(QTextDocument *doc)
{
- Q_D(SyntaxHighlighter);
if (d->doc == doc)
return;
@@ -356,10 +371,7 @@ void SyntaxHighlighter::setDocument(QTextDocument *doc)
documentChanged(oldDoc, d->doc);
if (d->doc) {
connect(d->doc, &QTextDocument::contentsChange, this, &SyntaxHighlighter::reformatBlocks);
- d->rehighlightPending = true;
- QMetaObject::invokeMethod(this,
- &SyntaxHighlighter::delayedRehighlight,
- Qt::QueuedConnection);
+ scheduleRehighlight();
d->foldValidator.setup(qobject_cast<TextDocumentLayout *>(doc->documentLayout()));
}
}
@@ -370,19 +382,16 @@ void SyntaxHighlighter::setDocument(QTextDocument *doc)
*/
QTextDocument *SyntaxHighlighter::document() const
{
- Q_D(const SyntaxHighlighter);
return d->doc;
}
void SyntaxHighlighter::setMimeType(const QString &mimeType)
{
- Q_D(SyntaxHighlighter);
d->mimeType = mimeType;
}
QString SyntaxHighlighter::mimeType() const
{
- Q_D(const SyntaxHighlighter);
return d->mimeType;
}
@@ -395,7 +404,6 @@ QString SyntaxHighlighter::mimeType() const
*/
void SyntaxHighlighter::rehighlight()
{
- Q_D(SyntaxHighlighter);
if (!d->doc)
return;
@@ -403,6 +411,17 @@ void SyntaxHighlighter::rehighlight()
d->rehighlight(cursor, QTextCursor::End);
}
+void SyntaxHighlighter::scheduleRehighlight()
+{
+ if (d->rehighlightPending)
+ return;
+ d->rehighlightPending = true;
+ d->syntaxInfoUpToDate = false;
+ QMetaObject::invokeMethod(this,
+ &SyntaxHighlighter::delayedRehighlight,
+ Qt::QueuedConnection);
+}
+
/*!
\since 4.6
@@ -412,7 +431,6 @@ void SyntaxHighlighter::rehighlight()
*/
void SyntaxHighlighter::rehighlightBlock(const QTextBlock &block)
{
- Q_D(SyntaxHighlighter);
if (!d->doc || !block.isValid() || block.document() != d->doc)
return;
@@ -486,7 +504,6 @@ void SyntaxHighlighter::rehighlightBlock(const QTextBlock &block)
*/
void SyntaxHighlighter::setFormat(int start, int count, const QTextCharFormat &format)
{
- Q_D(SyntaxHighlighter);
if (start < 0 || start >= d->formatChanges.count())
return;
@@ -533,7 +550,6 @@ void SyntaxHighlighter::setFormat(int start, int count, const QFont &font)
void SyntaxHighlighter::formatSpaces(const QString &text, int start, int count)
{
- Q_D(const SyntaxHighlighter);
int offset = start;
const int end = std::min(start + count, int(text.length()));
while (offset < end) {
@@ -585,10 +601,7 @@ void SyntaxHighlighter::setFormatWithSpaces(const QString &text, int start, int
*/
QTextCharFormat SyntaxHighlighter::format(int pos) const
{
- Q_D(const SyntaxHighlighter);
- if (pos < 0 || pos >= d->formatChanges.count())
- return QTextCharFormat();
- return d->formatChanges.at(pos);
+ return d->formatChanges.value(pos);
}
/*!
@@ -600,7 +613,6 @@ QTextCharFormat SyntaxHighlighter::format(int pos) const
*/
int SyntaxHighlighter::previousBlockState() const
{
- Q_D(const SyntaxHighlighter);
if (!d->currentBlock.isValid())
return -1;
@@ -617,7 +629,6 @@ int SyntaxHighlighter::previousBlockState() const
*/
int SyntaxHighlighter::currentBlockState() const
{
- Q_D(const SyntaxHighlighter);
if (!d->currentBlock.isValid())
return -1;
@@ -631,7 +642,6 @@ int SyntaxHighlighter::currentBlockState() const
*/
void SyntaxHighlighter::setCurrentBlockState(int newState)
{
- Q_D(SyntaxHighlighter);
if (!d->currentBlock.isValid())
return;
@@ -674,7 +684,6 @@ void SyntaxHighlighter::setCurrentBlockState(int newState)
*/
void SyntaxHighlighter::setCurrentBlockUserData(QTextBlockUserData *data)
{
- Q_D(SyntaxHighlighter);
if (!d->currentBlock.isValid())
return;
@@ -689,7 +698,6 @@ void SyntaxHighlighter::setCurrentBlockUserData(QTextBlockUserData *data)
*/
QTextBlockUserData *SyntaxHighlighter::currentBlockUserData() const
{
- Q_D(const SyntaxHighlighter);
if (!d->currentBlock.isValid())
return nullptr;
@@ -703,7 +711,6 @@ QTextBlockUserData *SyntaxHighlighter::currentBlockUserData() const
*/
QTextBlock SyntaxHighlighter::currentBlock() const
{
- Q_D(const SyntaxHighlighter);
return d->currentBlock;
}
@@ -715,8 +722,6 @@ static bool byStartOfRange(const QTextLayout::FormatRange &range, const QTextLay
void SyntaxHighlighter::setExtraFormats(const QTextBlock &block,
const QList<QTextLayout::FormatRange> &formats)
{
- Q_D(SyntaxHighlighter);
-
QList<QTextLayout::FormatRange> formatsCopy = formats;
const int blockLength = block.length();
@@ -766,20 +771,17 @@ void SyntaxHighlighter::setExtraFormats(const QTextBlock &block,
d->inReformatBlocks = true;
block.layout()->setFormats(formatsToApply);
- SyntaxHighlighter::Result res;
- res.m_formatRanges = block.layout()->formats();
- res.fillByBlock(block);
- res.m_state = SyntaxHighlighter::State::Extras;
- emit resultsReady({std::move(res)});
-
document()->markContentsDirty(block.position(), blockLength - 1);
d->inReformatBlocks = wasInReformatBlocks;
}
-void SyntaxHighlighter::clearExtraFormats(const QTextBlock &block)
+bool SyntaxHighlighter::syntaxHighlighterUpToDate() const
{
- Q_D(SyntaxHighlighter);
+ return d->syntaxInfoUpToDate;
+}
+void SyntaxHighlighter::clearExtraFormats(const QTextBlock &block)
+{
const int blockLength = block.length();
if (block.layout() == nullptr || blockLength == 0)
return;
@@ -793,12 +795,6 @@ void SyntaxHighlighter::clearExtraFormats(const QTextBlock &block)
d->inReformatBlocks = true;
block.layout()->setFormats(formatsToApply);
- SyntaxHighlighter::Result res;
- res.m_formatRanges = block.layout()->formats();
- res.fillByBlock(block);
- res.m_state = SyntaxHighlighter::State::Extras;
- emit resultsReady({std::move(res)});
-
document()->markContentsDirty(block.position(), blockLength - 1);
d->inReformatBlocks = wasInReformatBlocks;
}
@@ -848,13 +844,11 @@ QList<QColor> SyntaxHighlighter::generateColors(int n, const QColor &background)
void SyntaxHighlighter::setFontSettings(const FontSettings &fontSettings)
{
- Q_D(SyntaxHighlighter);
d->updateFormats(fontSettings);
}
FontSettings SyntaxHighlighter::fontSettings() const
{
- Q_D(const SyntaxHighlighter);
return d->fontSettings;
}
@@ -897,7 +891,6 @@ void SyntaxHighlighter::setTextFormatCategories(int count,
*/
void SyntaxHighlighter::setTextFormatCategories(const QList<std::pair<int, TextStyle>> &categories)
{
- Q_D(SyntaxHighlighter);
d->formatCategories = categories;
const int maxCategory = Utils::maxElementOr(categories, {-1, C_TEXT}).first;
d->formats = QList<QTextCharFormat>(maxCategory + 1);
@@ -906,7 +899,6 @@ void SyntaxHighlighter::setTextFormatCategories(const QList<std::pair<int, TextS
QTextCharFormat SyntaxHighlighter::formatForCategory(int category) const
{
- Q_D(const SyntaxHighlighter);
QTC_ASSERT(d->formats.size() > category, return QTextCharFormat());
return d->formats.at(category);
@@ -914,7 +906,6 @@ QTextCharFormat SyntaxHighlighter::formatForCategory(int category) const
QTextCharFormat SyntaxHighlighter::whitespacified(const QTextCharFormat &fmt)
{
- Q_D(SyntaxHighlighter);
QTextCharFormat format = d->whitespaceFormat;
format.setBackground(fmt.background());
return format;
diff --git a/src/plugins/texteditor/syntaxhighlighter.h b/src/plugins/texteditor/syntaxhighlighter.h
index 6b07d333f33..f5506374267 100644
--- a/src/plugins/texteditor/syntaxhighlighter.h
+++ b/src/plugins/texteditor/syntaxhighlighter.h
@@ -34,7 +34,6 @@ class SyntaxHighlighterPrivate;
class TEXTEDITOR_EXPORT SyntaxHighlighter : public QObject
{
Q_OBJECT
- Q_DECLARE_PRIVATE(SyntaxHighlighter)
public:
SyntaxHighlighter(QObject *parent = nullptr);
SyntaxHighlighter(QTextDocument *parent);
@@ -53,79 +52,16 @@ public:
virtual void setFontSettings(const TextEditor::FontSettings &fontSettings);
TextEditor::FontSettings fontSettings() const;
- enum State {
- Start,
- InProgress,
- Done,
- Extras
- };
-
- struct Result
- {
- void fillByBlock(const QTextBlock &block)
- {
- m_blockNumber = block.blockNumber();
- m_userState = block.userState();
-
- TextBlockUserData *userDate = TextDocumentLayout::textUserData(block);
- if (!userDate)
- return;
-
- m_hasBlockUserData = true;
- m_foldingIndent = userDate->foldingIndent();
- m_ifdefedOut = userDate->ifdefedOut();
- m_foldingStartIncluded = userDate->foldingStartIncluded();
- m_foldingEndIncluded = userDate->foldingEndIncluded();
- m_parentheses = userDate->parentheses();
- m_expectedRawStringSuffix = userDate->expectedRawStringSuffix();
- }
-
- void copyToBlock(QTextBlock &block) const
- {
- block.setUserState(m_userState);
-
- if (!m_hasBlockUserData)
- return;
-
- TextBlockUserData *data = TextDocumentLayout::userData(block);
- data->setExpectedRawStringSuffix(m_expectedRawStringSuffix);
- data->setFoldingIndent(m_foldingIndent);
- data->setFoldingStartIncluded(m_foldingStartIncluded);
- data->setFoldingEndIncluded(m_foldingEndIncluded);
-
- if (m_ifdefedOut)
- data->setIfdefedOut();
- else
- data->clearIfdefedOut();
-
- data->setParentheses(m_parentheses);
- }
-
- int m_blockNumber;
- bool m_hasBlockUserData = false;
-
- int m_foldingIndent : 16;
- uint m_ifdefedOut : 1;
- uint m_foldingStartIncluded : 1;
- uint m_foldingEndIncluded : 1;
-
- Parentheses m_parentheses;
- QByteArray m_expectedRawStringSuffix;
- int m_userState = -1;
- QList<QTextLayout::FormatRange> m_formatRanges;
-
- State m_state = InProgress;
- };
-
- void setInterrupted(bool interrupted) { m_interrupted = interrupted; }
- bool isInterrupted() { return m_interrupted; }
void setExtraFormats(const QTextBlock &block, const QList<QTextLayout::FormatRange> &formats);
virtual void setLanguageFeaturesFlags(unsigned int /*flags*/) {}; // needed for CppHighlighting
virtual void setEnabled(bool /*enabled*/) {}; // needed for DiffAndLogHighlighter
virtual void setDefinitionName(const QString & /*definitionName*/) {} // needed for Highlighter
+ bool syntaxHighlighterUpToDate() const;
+
public slots:
virtual void rehighlight();
+ virtual void scheduleRehighlight();
void rehighlightBlock(const QTextBlock &block);
void clearExtraFormats(const QTextBlock &block);
void reformatBlocks(int from, int charsRemoved, int charsAdded);
@@ -160,18 +96,18 @@ protected:
QTextBlock currentBlock() const;
-protected:
virtual void documentChanged(QTextDocument * /*oldDoc*/, QTextDocument * /*newDoc*/) {};
signals:
- void resultsReady(const QList<Result> &result);
+ void finished();
private:
void setTextFormatCategories(const QList<std::pair<int, TextStyle>> &categories);
void delayedRehighlight();
+ void continueRehighlight();
- QScopedPointer<SyntaxHighlighterPrivate> d_ptr;
- std::atomic<bool> m_interrupted = false;
+ friend class SyntaxHighlighterPrivate;
+ std::unique_ptr<SyntaxHighlighterPrivate> d;
#ifdef WITH_TESTS
friend class tst_highlighter;
diff --git a/src/plugins/texteditor/syntaxhighlighterrunner.cpp b/src/plugins/texteditor/syntaxhighlighterrunner.cpp
deleted file mode 100644
index 874f8254abf..00000000000
--- a/src/plugins/texteditor/syntaxhighlighterrunner.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "syntaxhighlighterrunner.h"
-
-#include "fontsettings.h"
-#include "textdocumentlayout.h"
-#include "texteditorsettings.h"
-#include "highlighter.h"
-
-#include <utils/algorithm.h>
-#include <utils/textutils.h>
-
-#include <QMetaObject>
-#include <QTextCursor>
-#include <QTextDocument>
-#include <QThread>
-
-namespace TextEditor {
-
-struct BlockPreeditData {
- int position;
- QString text;
-};
-
-class SyntaxHighlighterRunnerPrivate : public QObject
-{
- Q_OBJECT
-public:
- SyntaxHighlighterRunnerPrivate(SyntaxHighlighter *highlighter,
- QTextDocument *document,
- bool async)
- : m_highlighter(highlighter)
- {
- if (async) {
- m_document = new QTextDocument(this);
- m_document->setDocumentLayout(new TextDocumentLayout(m_document));
- } else {
- m_document = document;
- }
-
- m_highlighter->setParent(m_document);
- m_highlighter->setDocument(m_document);
-
- connect(m_highlighter,
- &SyntaxHighlighter::resultsReady,
- this,
- &SyntaxHighlighterRunnerPrivate::resultsReady);
- }
-
- void changeDocument(int from,
- int charsRemoved,
- const QString textAdded,
- const QMap<int, BlockPreeditData> &blocksPreedit)
- {
- QTextCursor cursor(m_document);
- cursor.setPosition(qMin(m_document->characterCount() - 1, from + charsRemoved));
- cursor.setPosition(from, QTextCursor::KeepAnchor);
- cursor.insertText(textAdded);
-
- for (auto it = blocksPreedit.cbegin(); it != blocksPreedit.cend(); ++it) {
- const QTextBlock block = m_document->findBlockByNumber(it.key());
- block.layout()->setPreeditArea(it.value().position, it.value().text);
- }
- }
-
- void setExtraFormats(const QMap<int, QList<QTextLayout::FormatRange>> &formatMap)
- {
- QTC_ASSERT(m_highlighter, return);
- for (auto it = formatMap.cbegin(); it != formatMap.cend(); ++it)
- m_highlighter->setExtraFormats(m_document->findBlockByNumber(it.key()), it.value());
- }
-
- void clearExtraFormats(const QList<int> &blockNumbers)
- {
- QTC_ASSERT(m_highlighter, return);
- for (auto it = blockNumbers.cbegin(); it != blockNumbers.cend(); ++it)
- m_highlighter->clearExtraFormats(m_document->findBlockByNumber(*it));
- }
-
- void clearAllExtraFormats()
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->clearAllExtraFormats();
- }
-
- void setFontSettings(const TextEditor::FontSettings &fontSettings)
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->setFontSettings(fontSettings);
- }
-
- void setDefinitionName(const QString &name)
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->setDefinitionName(name);
- }
-
- void setLanguageFeaturesFlags(unsigned int flags)
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->setLanguageFeaturesFlags(flags);
- }
-
- void setEnabled(bool enabled)
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->setEnabled(enabled);
- }
-
- void rehighlight()
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->rehighlight();
- }
-
- void reformatBlocks(int from, int charsRemoved, int charsAdded)
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->reformatBlocks(from, charsRemoved, charsAdded);
- }
-
- void setInterrupted(bool interrupted)
- {
- QTC_ASSERT(m_highlighter, return);
- m_highlighter->setInterrupted(interrupted);
- }
-
- QPointer<SyntaxHighlighter> m_highlighter = nullptr;
- QTextDocument *m_document = nullptr;
-
-signals:
- void resultsReady(const QList<SyntaxHighlighter::Result> &result);
-
-};
-
-void SyntaxHighlighterRunner::HighlightingStatus::notInterrupted(int from,
- int charsRemoved,
- int charsAdded)
-{
- m_from = from;
- m_addedChars = charsAdded;
- m_removedChars = charsRemoved;
- m_current = from;
- m_newFrom = from + m_addedChars;
- m_interruptionRequested = false;
-}
-
-void SyntaxHighlighterRunner::HighlightingStatus::interrupted(int from,
- int charsRemoved,
- int charsAdded)
-{
- m_newFrom = std::min(m_newFrom, from);
- m_newFrom = std::min(m_current, m_newFrom);
- m_removedChars += charsRemoved;
- m_addedChars += charsAdded;
- m_interruptionRequested = true;
-}
-
-void SyntaxHighlighterRunner::HighlightingStatus::applyNewFrom()
-{
- m_from = m_newFrom;
- m_current = m_newFrom;
- m_interruptionRequested = false;
-}
-
-SyntaxHighlighterRunner::SyntaxHighlighterRunner(SyntaxHighlighter *highlighter,
- QTextDocument *document,
- bool async)
- : d(new SyntaxHighlighterRunnerPrivate(highlighter, document, async))
- , m_document(document)
-{
- m_useGenericHighlighter = qobject_cast<Highlighter *>(d->m_highlighter);
-
- if (async) {
- m_thread.emplace();
- d->moveToThread(&*m_thread);
- connect(&*m_thread, &QThread::finished, d, &QObject::deleteLater);
- m_thread->start();
-
- connect(d,
- &SyntaxHighlighterRunnerPrivate::resultsReady,
- this,
- &SyntaxHighlighterRunner::applyFormatRanges);
-
- changeDocument(0, 0, m_document->characterCount());
- connect(m_document,
- &QTextDocument::contentsChange,
- this,
- &SyntaxHighlighterRunner::changeDocument);
-
- m_foldValidator.setup(qobject_cast<TextDocumentLayout *>(document->documentLayout()));
- } else {
- connect(d,
- &SyntaxHighlighterRunnerPrivate::resultsReady,
- this,
- [this](const QList<SyntaxHighlighter::Result> &result) {
- if (result.size() == 1
- && result.at(0).m_state == SyntaxHighlighter::State::Extras)
- return;
-
- auto done = std::find_if(result.cbegin(),
- result.cend(),
- [](const SyntaxHighlighter::Result &res) {
- return res.m_state
- == SyntaxHighlighter::State::Done;
- });
- if (done != result.cend()) {
- m_syntaxInfoUpdated = SyntaxHighlighter::State::Done;
- emit highlightingFinished();
- return;
- }
- m_syntaxInfoUpdated = SyntaxHighlighter::State::InProgress;
- });
- }
-}
-
-SyntaxHighlighterRunner::~SyntaxHighlighterRunner()
-{
- if (m_thread) {
- m_thread->requestInterruption();
- m_thread->quit();
- m_thread->wait();
- } else {
- delete d;
- }
-}
-
-void SyntaxHighlighterRunner::applyFormatRanges(const QList<SyntaxHighlighter::Result> &results)
-{
- if (m_document == nullptr)
- return;
-
- if (m_highlightingStatus.m_interruptionRequested) {
- d->setInterrupted(false);
- m_highlightingStatus.applyNewFrom();
- reformatBlocks(m_highlightingStatus.m_newFrom,
- m_highlightingStatus.m_removedChars,
- m_highlightingStatus.m_addedChars);
- return;
- }
-
- auto processResult = [this](SyntaxHighlighter::Result result, QTextBlock docBlock) {
- if (!docBlock.isValid())
- return;
-
- result.copyToBlock(docBlock);
- m_highlightingStatus.m_current = docBlock.position() + docBlock.length() - 1;
-
- if (result.m_formatRanges != docBlock.layout()->formats()) {
- docBlock.layout()->setFormats(result.m_formatRanges);
- m_document->markContentsDirty(docBlock.position(), docBlock.length());
- }
- };
-
- if (results.size() == 1 && results.at(0).m_state == SyntaxHighlighter::State::Extras) {
- QTextBlock docBlock = m_document->findBlockByNumber(results.at(0).m_blockNumber);
- processResult(results.at(0), docBlock);
- return;
- }
-
- for (const SyntaxHighlighter::Result &result : results) {
- m_syntaxInfoUpdated = result.m_state;
- if (m_syntaxInfoUpdated == SyntaxHighlighter::State::Start) {
- m_foldValidator.reset();
- continue;
- }
- if (m_syntaxInfoUpdated == SyntaxHighlighter::State::Done) {
- m_foldValidator.finalize();
- emit highlightingFinished();
- return;
- }
-
- QTextBlock docBlock = m_document->findBlockByNumber(result.m_blockNumber);
- processResult(result, docBlock);
- m_foldValidator.process(docBlock);
- }
-}
-
-void SyntaxHighlighterRunner::changeDocument(int from, int charsRemoved, int charsAdded)
-{
- QTC_ASSERT(m_document, return);
- SyntaxHighlighter::State prevSyntaxInfoUpdated = m_syntaxInfoUpdated;
- m_syntaxInfoUpdated = SyntaxHighlighter::State::InProgress;
-
- QMap<int, BlockPreeditData> blocksPreedit;
- QTextBlock block = m_document->findBlock(from);
- const QTextBlock endBlock = m_document->findBlock(from + charsAdded);
- while (block.isValid() && block != endBlock) {
- if (QTextLayout *layout = block.layout()) {
- if (const int pos = layout->preeditAreaPosition(); pos != -1)
- blocksPreedit[block.blockNumber()] = {pos, layout->preeditAreaText()};
- }
- block = block.next();
- }
- const QString text = Utils::Text::textAt(QTextCursor(m_document), from, charsAdded);
- QMetaObject::invokeMethod(d, [this, from, charsRemoved, text, blocksPreedit] {
- d->changeDocument(from, charsRemoved, text, blocksPreedit);
- });
-
- if (prevSyntaxInfoUpdated == SyntaxHighlighter::State::InProgress) {
- m_highlightingStatus.interrupted(from, charsRemoved, charsAdded);
- d->setInterrupted(true);
- } else {
- m_highlightingStatus.notInterrupted(from, charsRemoved, charsAdded);
- d->setInterrupted(false);
- }
-}
-
-bool SyntaxHighlighterRunner::useGenericHighlighter() const
-{
- return m_useGenericHighlighter;
-}
-
-void SyntaxHighlighterRunner::setExtraFormats(
- const QMap<int, QList<QTextLayout::FormatRange>> &formatMap)
-{
- QMetaObject::invokeMethod(d, [this, formatMap] { d->setExtraFormats(formatMap); });
-}
-
-void SyntaxHighlighterRunner::clearExtraFormats(const QList<int> &blockNumbers)
-{
- QMetaObject::invokeMethod(d, [this, blockNumbers] { d->clearExtraFormats(blockNumbers); });
-}
-
-void SyntaxHighlighterRunner::clearAllExtraFormats()
-{
- QMetaObject::invokeMethod(d, [this] { d->clearAllExtraFormats(); });
-}
-
-void SyntaxHighlighterRunner::setFontSettings(const TextEditor::FontSettings &fontSettings)
-{
- QMetaObject::invokeMethod(d, [this, fontSettings] { d->setFontSettings(fontSettings); });
- rehighlight();
-}
-
-void SyntaxHighlighterRunner::setLanguageFeaturesFlags(unsigned int flags)
-{
- QMetaObject::invokeMethod(d, [this, flags] { d->setLanguageFeaturesFlags(flags); });
-}
-
-void SyntaxHighlighterRunner::setEnabled(bool enabled)
-{
- QMetaObject::invokeMethod(d, [this, enabled] { d->setEnabled(enabled); });
-}
-
-void SyntaxHighlighterRunner::rehighlight()
-{
- if (m_syntaxInfoUpdated == SyntaxHighlighter::State::InProgress) {
- m_highlightingStatus.interrupted(0, 0, m_document->characterCount());
- d->setInterrupted(true);
- } else {
- m_highlightingStatus.notInterrupted(0, 0, m_document->characterCount());
- d->setInterrupted(false);
- QMetaObject::invokeMethod(d, [this] { d->rehighlight(); });
- }
-}
-
-
-void SyntaxHighlighterRunner::reformatBlocks(int from, int charsRemoved, int charsAdded)
-{
- QMetaObject::invokeMethod(
- d,
- [this, from, charsRemoved, charsAdded] {
- d->reformatBlocks(from, charsRemoved, charsAdded);
- });
-}
-
-QString SyntaxHighlighterRunner::definitionName()
-{
- return m_definitionName;
-}
-
-void SyntaxHighlighterRunner::setDefinitionName(const QString &name)
-{
- if (name.isEmpty())
- return;
-
- m_definitionName = name;
- QMetaObject::invokeMethod(d, [this, name] { d->setDefinitionName(name); });
-}
-
-} // namespace TextEditor
-
-#include "syntaxhighlighterrunner.moc"
diff --git a/src/plugins/texteditor/syntaxhighlighterrunner.h b/src/plugins/texteditor/syntaxhighlighterrunner.h
deleted file mode 100644
index 16b7c1535c8..00000000000
--- a/src/plugins/texteditor/syntaxhighlighterrunner.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include <texteditor/fontsettings.h>
-#include <texteditor/syntaxhighlighter.h>
-#include <texteditor/texteditorsettings.h>
-
-#include <QObject>
-#include <QPointer>
-
-QT_BEGIN_NAMESPACE
-class QTextDocument;
-QT_END_NAMESPACE
-
-namespace TextEditor {
-
-class SyntaxHighlighterRunnerPrivate;
-
-class TEXTEDITOR_EXPORT SyntaxHighlighterRunner : public QObject
-{
- Q_OBJECT
-public:
- using SyntaxHighlighterCreator = std::function<SyntaxHighlighter *()>;
-
- SyntaxHighlighterRunner(SyntaxHighlighter *highlighter, QTextDocument *document, bool async);
- virtual ~SyntaxHighlighterRunner();
-
- void setExtraFormats(const QMap<int, QList<QTextLayout::FormatRange>> &formats);
- void clearExtraFormats(const QList<int> &blockNumbers);
- void clearAllExtraFormats();
- void setFontSettings(const TextEditor::FontSettings &fontSettings);
- void setLanguageFeaturesFlags(unsigned int flags);
- void setEnabled(bool enabled);
- void rehighlight();
- void reformatBlocks(int from, int charsRemoved, int charsAdded);
-
- QString definitionName();
- void setDefinitionName(const QString &name);
-
- QTextDocument *document() const { return m_document; }
- bool useGenericHighlighter() const;
-
- bool syntaxInfoUpdated() const { return m_syntaxInfoUpdated == SyntaxHighlighter::State::Done; }
-
-signals:
- void highlightingFinished();
-
-private:
- void applyFormatRanges(const QList<SyntaxHighlighter::Result> &results);
- void changeDocument(int from, int charsRemoved, int charsAdded);
-
- SyntaxHighlighterRunnerPrivate *d;
- QPointer<QTextDocument> m_document = nullptr;
- SyntaxHighlighter::State m_syntaxInfoUpdated = SyntaxHighlighter::State::Done;
-
- struct HighlightingStatus
- {
- int m_from = 0;
- int m_addedChars = 0;
- int m_current = 0;
- int m_removedChars = 0;
- int m_newFrom = 0;
- bool m_interruptionRequested = false;
-
- void notInterrupted(int from, int charsRemoved, int charsAdded);
- void interrupted(int from, int charsRemoved, int charsAdded);
- void applyNewFrom();
- } m_highlightingStatus;
-
- bool m_useGenericHighlighter = false;
- QString m_definitionName;
- std::optional<QThread> m_thread;
- TextDocumentLayout::FoldValidator m_foldValidator;
-};
-
-} // namespace TextEditor
-
diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp
index 2636ad46e23..9d8133912c8 100644
--- a/src/plugins/texteditor/textdocument.cpp
+++ b/src/plugins/texteditor/textdocument.cpp
@@ -10,10 +10,10 @@
#include "tabsettings.h"
#include "textdocumentlayout.h"
#include "texteditor.h"
+#include "texteditorsettings.h"
#include "texteditortr.h"
#include "textindenter.h"
#include "typingsettings.h"
-#include "syntaxhighlighterrunner.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/diffservice.h>
@@ -64,8 +64,6 @@ public:
~TextDocumentPrivate()
{
- if (m_highlighterRunner)
- m_highlighterRunner->deleteLater();
}
MultiTextCursor indentOrUnindent(const MultiTextCursor &cursor, bool doIndent, const TabSettings &tabSettings);
@@ -101,7 +99,7 @@ public:
TextMarks m_marksCache; // Marks not owned
Utils::Guard m_modificationChangedGuard;
- SyntaxHighlighterRunner *m_highlighterRunner = nullptr;
+ SyntaxHighlighter *m_highlighter = nullptr;
};
MultiTextCursor TextDocumentPrivate::indentOrUnindent(const MultiTextCursor &cursors,
@@ -462,8 +460,8 @@ void TextDocument::applyFontSettings()
block = block.next();
}
updateLayout();
- if (d->m_highlighterRunner)
- d->m_highlighterRunner->setFontSettings(d->m_fontSettings);
+ if (d->m_highlighter)
+ d->m_highlighter->setFontSettings(d->m_fontSettings);
}
const FontSettings &TextDocument::fontSettings() const
@@ -533,6 +531,15 @@ bool TextDocument::applyChangeSet(const ChangeSet &changeSet)
// the blocks list must be sorted
void TextDocument::setIfdefedOutBlocks(const QList<BlockRange> &blocks)
{
+ if (syntaxHighlighter() && !syntaxHighlighter()->syntaxHighlighterUpToDate()) {
+ connect(syntaxHighlighter(),
+ &SyntaxHighlighter::finished,
+ this,
+ [this, blocks] { setIfdefedOutBlocks(blocks); },
+ Qt::SingleShotConnection);
+ return;
+ }
+
QTextDocument *doc = document();
auto documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout());
QTC_ASSERT(documentLayout, return);
@@ -635,11 +642,6 @@ QTextDocument *TextDocument::document() const
return &d->m_document;
}
-SyntaxHighlighterRunner *TextDocument::syntaxHighlighterRunner() const
-{
- return d->m_highlighterRunner;
-}
-
/*!
* Saves the document to the file specified by \a fileName. If errors occur,
* \a errorString contains their cause.
@@ -911,26 +913,19 @@ bool TextDocument::reload(QString *errorString, ReloadFlag flag, ChangeType type
return reload(errorString);
}
-void TextDocument::resetSyntaxHighlighter(const std::function<SyntaxHighlighter *()> &creator,
- bool threaded)
+void TextDocument::resetSyntaxHighlighter(const std::function<SyntaxHighlighter *()> &creator)
{
- delete d->m_highlighterRunner;
-
- static const std::optional<bool> envValue = []() -> std::optional<bool> {
- const QString key("QTC_USE_THREADED_HIGHLIGHTER");
- if (qtcEnvironmentVariableIsSet(key)) {
- const QString value = qtcEnvironmentVariable(key).toUpper();
- return value != "FALSE" && value != "0";
- }
- return {};
- }();
-
SyntaxHighlighter *highlighter = creator();
+ highlighter->setParent(this);
+ highlighter->setDocument(this->document());
highlighter->setFontSettings(TextEditorSettings::fontSettings());
highlighter->setMimeType(mimeType());
- d->m_highlighterRunner = new SyntaxHighlighterRunner(highlighter,
- document(),
- envValue.value_or(threaded));
+ d->m_highlighter = highlighter;
+}
+
+SyntaxHighlighter *TextDocument::syntaxHighlighter() const
+{
+ return d->m_highlighter;
}
void TextDocument::cleanWhitespace(const QTextCursor &cursor)
diff --git a/src/plugins/texteditor/textdocument.h b/src/plugins/texteditor/textdocument.h
index 5879d9e9ec2..b3bf77e5442 100644
--- a/src/plugins/texteditor/textdocument.h
+++ b/src/plugins/texteditor/textdocument.h
@@ -34,7 +34,6 @@ class FontSettings;
class IAssistProvider;
class StorageSettings;
class SyntaxHighlighter;
-class SyntaxHighlighterRunner;
class TabSettings;
class TextDocumentPrivate;
class TextMark;
@@ -127,8 +126,8 @@ public:
QTextDocument *document() const;
using SyntaxHighLighterCreator = std::function<SyntaxHighlighter *()>;
- void resetSyntaxHighlighter(const SyntaxHighLighterCreator &creator, bool threaded = false);
- SyntaxHighlighterRunner *syntaxHighlighterRunner() const;
+ void resetSyntaxHighlighter(const SyntaxHighLighterCreator &creator);
+ SyntaxHighlighter *syntaxHighlighter() const;
bool reload(QString *errorString, QTextCodec *codec);
void cleanWhitespace(const QTextCursor &cursor);
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index 42daeeff6d3..85bd4732baa 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -34,7 +34,6 @@
#include "texteditorsettings.h"
#include "texteditortr.h"
#include "typingsettings.h"
-#include "syntaxhighlighterrunner.h"
#include <aggregation/aggregate.h>
@@ -1935,8 +1934,8 @@ void TextEditorWidgetPrivate::foldLicenseHeader()
QStringList commentMarker;
QStringList docMarker;
HighlighterHelper::Definition def;
- if (SyntaxHighlighterRunner *highlighter = q->textDocument()->syntaxHighlighterRunner())
- def = HighlighterHelper::definitionForName(highlighter->definitionName());
+ if (auto highlighter = qobject_cast<Highlighter *>(q->textDocument()->syntaxHighlighter()))
+ def = highlighter->definition();
if (def.isValid()) {
for (const QString &marker :
@@ -3494,10 +3493,10 @@ QByteArray TextEditorWidget::saveState() const
bool TextEditorWidget::singleShotAfterHighlightingDone(std::function<void()> &&f)
{
- if (d->m_document->syntaxHighlighterRunner()
- && !d->m_document->syntaxHighlighterRunner()->syntaxInfoUpdated()) {
- connect(d->m_document->syntaxHighlighterRunner(),
- &SyntaxHighlighterRunner::highlightingFinished,
+ if (d->m_document->syntaxHighlighter()
+ && !d->m_document->syntaxHighlighter()->syntaxHighlighterUpToDate()) {
+ connect(d->m_document->syntaxHighlighter(),
+ &SyntaxHighlighter::finished,
this,
[f = std::move(f)] { f(); }, Qt::SingleShotConnection);
return true;
@@ -3741,10 +3740,11 @@ void TextEditorWidgetPrivate::configureGenericHighlighter(
const QString definitionFilesPath
= TextEditorSettings::highlighterSettings().definitionFilesPath().toString();
- m_document->resetSyntaxHighlighter([definitionFilesPath] {
- return new Highlighter(definitionFilesPath);
+ m_document->resetSyntaxHighlighter([definitionFilesPath, definition] {
+ auto highlighter = new Highlighter(definitionFilesPath);
+ highlighter->setDefinition(definition);
+ return highlighter;
});
- m_document->syntaxHighlighterRunner()->setDefinitionName(definition.name());
m_document->setFontSettings(TextEditorSettings::fontSettings());
}
@@ -3769,8 +3769,8 @@ void TextEditorWidgetPrivate::setupFromDefinition(const KSyntaxHighlighting::Def
KSyntaxHighlighting::Definition TextEditorWidgetPrivate::currentDefinition()
{
- if (SyntaxHighlighterRunner *highlighter = m_document->syntaxHighlighterRunner())
- return HighlighterHelper::definitionForName(highlighter->definitionName());
+ if (auto *highlighter = qobject_cast<Highlighter *>(m_document->syntaxHighlighter()))
+ return highlighter->definition();
return {};
}
@@ -5127,7 +5127,8 @@ void TextEditorWidgetPrivate::setupBlockLayout(const PaintEventData &data,
blockData.layout = data.block.layout();
QTextOption option = blockData.layout->textOption();
- if (data.suppressSyntaxInIfdefedOutBlock && TextDocumentLayout::ifdefedOut(data.block)) {
+ if (data.suppressSyntaxInIfdefedOutBlock
+ && TextDocumentLayout::ifdefedOut(data.block)) {
option.setFlags(option.flags() | QTextOption::SuppressColors);
painter.setPen(data.ifdefedOutFormat.foreground().color());
} else {
@@ -5746,8 +5747,8 @@ void TextEditorWidgetPrivate::paintCodeFolding(QPainter &painter,
TextBlockUserData *nextBlockUserData = TextDocumentLayout::textUserData(nextBlock);
bool drawBox = nextBlockUserData
- && TextDocumentLayout::foldingIndent(data.block) < nextBlockUserData->foldingIndent();
-
+ && TextDocumentLayout::foldingIndent(data.block)
+ < nextBlockUserData->foldingIndent();
const int blockNumber = data.block.blockNumber();
bool active = blockNumber == extraAreaHighlightFoldBlockNumber;
@@ -8183,7 +8184,7 @@ void TextEditorWidget::setDisplaySettings(const DisplaySettings &ds)
optionFlags.setFlag(QTextOption::AddSpaceForLineAndParagraphSeparators);
optionFlags.setFlag(QTextOption::ShowTabsAndSpaces, ds.m_visualizeWhitespace);
if (optionFlags != currentOptionFlags) {
- if (SyntaxHighlighterRunner *highlighter = textDocument()->syntaxHighlighterRunner())
+ if (SyntaxHighlighter *highlighter = textDocument()->syntaxHighlighter())
highlighter->rehighlight();
QTextOption option = document()->defaultTextOption();
option.setFlags(optionFlags);
diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs
index 41fe08d51b5..30a4712b731 100644
--- a/src/plugins/texteditor/texteditor.qbs
+++ b/src/plugins/texteditor/texteditor.qbs
@@ -124,8 +124,6 @@ QtcPlugin {
"storagesettings.h",
"syntaxhighlighter.cpp",
"syntaxhighlighter.h",
- "syntaxhighlighterrunner.cpp",
- "syntaxhighlighterrunner.h",
"tabsettings.cpp",
"tabsettings.h",
"tabsettingswidget.cpp",
diff --git a/src/plugins/vcsbase/baseannotationhighlighter.cpp b/src/plugins/vcsbase/baseannotationhighlighter.cpp
index e3dce5ba266..0809d2c5237 100644
--- a/src/plugins/vcsbase/baseannotationhighlighter.cpp
+++ b/src/plugins/vcsbase/baseannotationhighlighter.cpp
@@ -4,6 +4,7 @@
#include "baseannotationhighlighter.h"
#include <texteditor/fontsettings.h>
+#include <texteditor/syntaxhighlighter.h>
#include <texteditor/texteditorsettings.h>
#include <utils/algorithm.h>
@@ -163,7 +164,7 @@ void BaseAnnotationHighlighter::rehighlight()
return;
setChangeNumbers(changes);
- TextEditor::SyntaxHighlighter::rehighlight();
+ SyntaxHighlighter::rehighlight();
}
} // namespace VcsBase
diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp
index 38bb004a2d6..13338584bf1 100644
--- a/src/plugins/vcsbase/vcsbaseeditor.cpp
+++ b/src/plugins/vcsbase/vcsbaseeditor.cpp
@@ -30,7 +30,7 @@
#include <texteditor/texteditoractionhandler.h>
#include <texteditor/textdocument.h>
#include <texteditor/textdocumentlayout.h>
-#include <texteditor/syntaxhighlighterrunner.h>
+#include <texteditor/syntaxhighlighter.h>
#include <utils/algorithm.h>
#include <utils/progressindicator.h>
@@ -821,7 +821,7 @@ void VcsBaseEditorWidget::setFileLogAnnotateEnabled(bool e)
void VcsBaseEditorWidget::setHighlightingEnabled(bool e)
{
- textDocument()->syntaxHighlighterRunner()->setEnabled(e);
+ textDocument()->syntaxHighlighter()->setEnabled(e);
}
FilePath VcsBaseEditorWidget::workingDirectory() const
@@ -1102,7 +1102,7 @@ void VcsBaseEditorWidget::slotActivateAnnotation()
disconnect(this, &QPlainTextEdit::textChanged, this, &VcsBaseEditorWidget::slotActivateAnnotation);
- if (SyntaxHighlighterRunner *ah = textDocument()->syntaxHighlighterRunner()) {
+ if (SyntaxHighlighter *ah = textDocument()->syntaxHighlighter()) {
ah->rehighlight();
} else {
BaseAnnotationHighlighterCreator creator = annotationHighlighterCreator();