forked from qt-creator/qt-creator
TextEditor: Merge Base- and ThreadedSyntaxHighlighterRunner
Change-Id: I38ad01a895eabba99b2e554f3ae9bef85f32bb3b Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
This commit is contained in:
@@ -150,7 +150,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
return ::CppEditor::Tests::waitForSignalOrTimeout(
|
return ::CppEditor::Tests::waitForSignalOrTimeout(
|
||||||
cppEditor->textDocument()->syntaxHighlighterRunner(),
|
cppEditor->textDocument()->syntaxHighlighterRunner(),
|
||||||
&BaseSyntaxHighlighterRunner::highlightingFinished,
|
&SyntaxHighlighterRunner::highlightingFinished,
|
||||||
5000);
|
5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -164,7 +164,7 @@ QByteArray CppEditorDocument::contentsText() const
|
|||||||
|
|
||||||
void CppEditorDocument::applyFontSettings()
|
void CppEditorDocument::applyFontSettings()
|
||||||
{
|
{
|
||||||
if (TextEditor::BaseSyntaxHighlighterRunner *highlighter = syntaxHighlighterRunner())
|
if (TextEditor::SyntaxHighlighterRunner *highlighter = syntaxHighlighterRunner())
|
||||||
highlighter->clearAllExtraFormats(); // Clear all additional formats since they may have changed
|
highlighter->clearAllExtraFormats(); // Clear all additional formats since they may have changed
|
||||||
TextDocument::applyFontSettings(); // rehighlights and updates additional formats
|
TextDocument::applyFontSettings(); // rehighlights and updates additional formats
|
||||||
if (m_processor)
|
if (m_processor)
|
||||||
@@ -408,7 +408,7 @@ BaseEditorDocumentProcessor *CppEditorDocument::processor()
|
|||||||
connect(m_processor.data(), &BaseEditorDocumentProcessor::cppDocumentUpdated, this,
|
connect(m_processor.data(), &BaseEditorDocumentProcessor::cppDocumentUpdated, this,
|
||||||
[this](const CPlusPlus::Document::Ptr document) {
|
[this](const CPlusPlus::Document::Ptr document) {
|
||||||
// Update syntax highlighter
|
// Update syntax highlighter
|
||||||
if (BaseSyntaxHighlighterRunner *highlighter = syntaxHighlighterRunner())
|
if (SyntaxHighlighterRunner *highlighter = syntaxHighlighterRunner())
|
||||||
highlighter->setLanguageFeaturesFlags(document->languageFeatures().flags);
|
highlighter->setLanguageFeaturesFlags(document->languageFeatures().flags);
|
||||||
|
|
||||||
m_overviewModel.update(usesClangd() ? nullptr : document);
|
m_overviewModel.update(usesClangd() ? nullptr : document);
|
||||||
|
@@ -112,7 +112,7 @@ void SemanticHighlighter::handleHighlighterResults()
|
|||||||
QElapsedTimer t;
|
QElapsedTimer t;
|
||||||
t.start();
|
t.start();
|
||||||
|
|
||||||
BaseSyntaxHighlighterRunner *highlighter = m_baseTextDocument->syntaxHighlighterRunner();
|
SyntaxHighlighterRunner *highlighter = m_baseTextDocument->syntaxHighlighterRunner();
|
||||||
QTC_ASSERT(highlighter, return);
|
QTC_ASSERT(highlighter, return);
|
||||||
incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap);
|
incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap);
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ void SemanticHighlighter::onHighlighterFinished()
|
|||||||
t.start();
|
t.start();
|
||||||
|
|
||||||
if (!m_watcher->isCanceled() && documentRevision() == m_revision) {
|
if (!m_watcher->isCanceled() && documentRevision() == m_revision) {
|
||||||
BaseSyntaxHighlighterRunner *highlighter = m_baseTextDocument->syntaxHighlighterRunner();
|
SyntaxHighlighterRunner *highlighter = m_baseTextDocument->syntaxHighlighterRunner();
|
||||||
if (QTC_GUARD(highlighter)) {
|
if (QTC_GUARD(highlighter)) {
|
||||||
qCDebug(log) << "onHighlighterFinished() - clearing formats";
|
qCDebug(log) << "onHighlighterFinished() - clearing formats";
|
||||||
clearExtraAdditionalFormatsUntilEnd(highlighter, m_watcher->future());
|
clearExtraAdditionalFormatsUntilEnd(highlighter, m_watcher->future());
|
||||||
|
@@ -183,7 +183,7 @@ void SemanticTokenSupport::queueDocumentReload(TextEditor::TextDocument *doc)
|
|||||||
void SemanticTokenSupport::clearHighlight(TextEditor::TextDocument *doc)
|
void SemanticTokenSupport::clearHighlight(TextEditor::TextDocument *doc)
|
||||||
{
|
{
|
||||||
if (m_tokens.contains(doc->filePath())){
|
if (m_tokens.contains(doc->filePath())){
|
||||||
if (TextEditor::BaseSyntaxHighlighterRunner *highlighter = doc->syntaxHighlighterRunner())
|
if (TextEditor::SyntaxHighlighterRunner *highlighter = doc->syntaxHighlighterRunner())
|
||||||
highlighter->clearAllExtraFormats();
|
highlighter->clearAllExtraFormats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,7 +413,7 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath, bool force
|
|||||||
TextDocument *doc = TextDocument::textDocumentForFilePath(filePath);
|
TextDocument *doc = TextDocument::textDocumentForFilePath(filePath);
|
||||||
if (!doc || LanguageClientManager::clientForDocument(doc) != m_client)
|
if (!doc || LanguageClientManager::clientForDocument(doc) != m_client)
|
||||||
return;
|
return;
|
||||||
BaseSyntaxHighlighterRunner *highlighter = doc->syntaxHighlighterRunner();
|
SyntaxHighlighterRunner *highlighter = doc->syntaxHighlighterRunner();
|
||||||
if (!highlighter)
|
if (!highlighter)
|
||||||
return;
|
return;
|
||||||
const VersionedTokens versionedTokens = m_tokens.value(filePath);
|
const VersionedTokens versionedTokens = m_tokens.value(filePath);
|
||||||
|
@@ -75,7 +75,7 @@ const Ranges rangesForResult(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
|
void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
|
||||||
BaseSyntaxHighlighterRunner *highlighter,
|
SyntaxHighlighterRunner *highlighter,
|
||||||
const QFuture<HighlightingResult> &future,
|
const QFuture<HighlightingResult> &future,
|
||||||
int from,
|
int from,
|
||||||
int to,
|
int to,
|
||||||
@@ -128,7 +128,7 @@ void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
|
|||||||
highlighter->setExtraFormats(blockNumberMap);
|
highlighter->setExtraFormats(blockNumberMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SemanticHighlighter::setExtraAdditionalFormats(BaseSyntaxHighlighterRunner *highlighter,
|
void SemanticHighlighter::setExtraAdditionalFormats(SyntaxHighlighterRunner *highlighter,
|
||||||
const QList<HighlightingResult> &results,
|
const QList<HighlightingResult> &results,
|
||||||
const QHash<int, QTextCharFormat> &kindToFormat)
|
const QHash<int, QTextCharFormat> &kindToFormat)
|
||||||
{
|
{
|
||||||
@@ -151,7 +151,7 @@ void SemanticHighlighter::setExtraAdditionalFormats(BaseSyntaxHighlighterRunner
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
|
void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
|
||||||
BaseSyntaxHighlighterRunner *highlighter, const QFuture<HighlightingResult> &future)
|
SyntaxHighlighterRunner *highlighter, const QFuture<HighlightingResult> &future)
|
||||||
{
|
{
|
||||||
const QTextDocument * const doc = highlighter->document();
|
const QTextDocument * const doc = highlighter->document();
|
||||||
QTextBlock firstBlockToClear = doc->begin();
|
QTextBlock firstBlockToClear = doc->begin();
|
||||||
|
@@ -21,7 +21,7 @@ QT_END_NAMESPACE
|
|||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
|
|
||||||
class SyntaxHighlighter;
|
class SyntaxHighlighter;
|
||||||
class BaseSyntaxHighlighterRunner;
|
class SyntaxHighlighterRunner;
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT HighlightingResult
|
class TEXTEDITOR_EXPORT HighlightingResult
|
||||||
{
|
{
|
||||||
@@ -74,7 +74,7 @@ using Splitter = std::function<const QList<std::pair<HighlightingResult, QTextBl
|
|||||||
// the (to-1).line result.
|
// the (to-1).line result.
|
||||||
// Requires that results of the Future are ordered by line.
|
// Requires that results of the Future are ordered by line.
|
||||||
void TEXTEDITOR_EXPORT
|
void TEXTEDITOR_EXPORT
|
||||||
incrementalApplyExtraAdditionalFormats(BaseSyntaxHighlighterRunner *highlighter,
|
incrementalApplyExtraAdditionalFormats(SyntaxHighlighterRunner *highlighter,
|
||||||
const QFuture<HighlightingResult> &future,
|
const QFuture<HighlightingResult> &future,
|
||||||
int from,
|
int from,
|
||||||
int to,
|
int to,
|
||||||
@@ -85,7 +85,7 @@ incrementalApplyExtraAdditionalFormats(BaseSyntaxHighlighterRunner *highlighter,
|
|||||||
// indicated by Result::kind and kindToFormat to the correct location using
|
// indicated by Result::kind and kindToFormat to the correct location using
|
||||||
// SyntaxHighlighter::setExtraFormats. In contrast to
|
// SyntaxHighlighter::setExtraFormats. In contrast to
|
||||||
// incrementalApplyExtraAdditionalFormats the results do not have to be ordered by line.
|
// incrementalApplyExtraAdditionalFormats the results do not have to be ordered by line.
|
||||||
void TEXTEDITOR_EXPORT setExtraAdditionalFormats(BaseSyntaxHighlighterRunner *highlighter,
|
void TEXTEDITOR_EXPORT setExtraAdditionalFormats(SyntaxHighlighterRunner *highlighter,
|
||||||
const HighlightingResults &results,
|
const HighlightingResults &results,
|
||||||
const QHash<int, QTextCharFormat> &kindToFormat);
|
const QHash<int, QTextCharFormat> &kindToFormat);
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ void TEXTEDITOR_EXPORT setExtraAdditionalFormats(BaseSyntaxHighlighterRunner *hi
|
|||||||
// until the end of the document.
|
// until the end of the document.
|
||||||
// Requires that results of the Future are ordered by line.
|
// Requires that results of the Future are ordered by line.
|
||||||
void TEXTEDITOR_EXPORT clearExtraAdditionalFormatsUntilEnd(
|
void TEXTEDITOR_EXPORT clearExtraAdditionalFormatsUntilEnd(
|
||||||
BaseSyntaxHighlighterRunner *highlighter, const QFuture<HighlightingResult> &future);
|
SyntaxHighlighterRunner *highlighter, const QFuture<HighlightingResult> &future);
|
||||||
|
|
||||||
} // namespace SemanticHighlighter
|
} // namespace SemanticHighlighter
|
||||||
} // namespace TextEditor
|
} // namespace TextEditor
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "texteditorsettings.h"
|
#include "texteditorsettings.h"
|
||||||
#include "highlighter.h"
|
#include "highlighter.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/textutils.h>
|
#include <utils/textutils.h>
|
||||||
|
|
||||||
#include <QMetaObject>
|
#include <QMetaObject>
|
||||||
@@ -21,19 +22,20 @@ class SyntaxHighlighterRunnerPrivate : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SyntaxHighlighterRunnerPrivate(BaseSyntaxHighlighterRunner::SyntaxHighLighterCreator creator,
|
SyntaxHighlighterRunnerPrivate(SyntaxHighlighterRunner::SyntaxHighlighterCreator creator,
|
||||||
QTextDocument *document,
|
QTextDocument *document,
|
||||||
|
bool async,
|
||||||
FontSettings fontSettings)
|
FontSettings fontSettings)
|
||||||
: m_document(document)
|
|
||||||
, m_fontSettings(fontSettings)
|
|
||||||
{
|
{
|
||||||
if (!m_document) {
|
if (async) {
|
||||||
m_document = new QTextDocument(this);
|
m_document = new QTextDocument(this);
|
||||||
m_document->setDocumentLayout(new TextDocumentLayout(m_document));
|
m_document->setDocumentLayout(new TextDocumentLayout(m_document));
|
||||||
|
} else {
|
||||||
|
m_document = document;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_highlighter.reset(creator());
|
m_highlighter.reset(creator());
|
||||||
m_highlighter->setFontSettings(m_fontSettings);
|
m_highlighter->setFontSettings(fontSettings);
|
||||||
m_highlighter->setDocument(m_document);
|
m_highlighter->setDocument(m_document);
|
||||||
m_highlighter->setParent(m_document);
|
m_highlighter->setParent(m_document);
|
||||||
|
|
||||||
@@ -46,7 +48,7 @@ public:
|
|||||||
void changeDocument(int from,
|
void changeDocument(int from,
|
||||||
int charsRemoved,
|
int charsRemoved,
|
||||||
const QString textAdded,
|
const QString textAdded,
|
||||||
const QMap<int, BaseSyntaxHighlighterRunner::BlockPreeditData> &blocksPreedit)
|
const QMap<int, SyntaxHighlighterRunner::BlockPreeditData> &blocksPreedit)
|
||||||
{
|
{
|
||||||
QTextCursor cursor(m_document);
|
QTextCursor cursor(m_document);
|
||||||
cursor.setPosition(qMin(m_document->characterCount() - 1, from + charsRemoved));
|
cursor.setPosition(qMin(m_document->characterCount() - 1, from + charsRemoved));
|
||||||
@@ -95,48 +97,69 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<SyntaxHighlighter> m_highlighter;
|
std::unique_ptr<SyntaxHighlighter> m_highlighter;
|
||||||
QTextDocument *m_document = nullptr;
|
QTextDocument *m_document = nullptr;
|
||||||
FontSettings m_fontSettings;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void resultsReady(const QList<SyntaxHighlighter::Result> &result);
|
void resultsReady(const QList<SyntaxHighlighter::Result> &result);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------- BaseSyntaxHighlighterRunner --------------------------------------
|
SyntaxHighlighterRunner::SyntaxHighlighterRunner(SyntaxHighlighterCreator creator,
|
||||||
|
QTextDocument *document,
|
||||||
BaseSyntaxHighlighterRunner::BaseSyntaxHighlighterRunner(
|
bool async,
|
||||||
BaseSyntaxHighlighterRunner::SyntaxHighLighterCreator creator,
|
const TextEditor::FontSettings &fontSettings)
|
||||||
QTextDocument *document,
|
: d(new SyntaxHighlighterRunnerPrivate(creator, document, async, fontSettings))
|
||||||
const TextEditor::FontSettings &fontSettings)
|
|
||||||
: d(new SyntaxHighlighterRunnerPrivate(creator, document, fontSettings))
|
|
||||||
, m_document(document)
|
, m_document(document)
|
||||||
{
|
{
|
||||||
m_useGenericHighlighter = qobject_cast<Highlighter *>(d->m_highlighter.get());
|
m_useGenericHighlighter = qobject_cast<Highlighter *>(d->m_highlighter.get());
|
||||||
|
|
||||||
if (document == nullptr)
|
if (async) {
|
||||||
return;
|
m_thread.emplace();
|
||||||
|
d->moveToThread(&*m_thread);
|
||||||
|
connect(&*m_thread, &QThread::finished, d, &QObject::deleteLater);
|
||||||
|
m_thread->start();
|
||||||
|
|
||||||
connect(d.get(),
|
connect(d,
|
||||||
&SyntaxHighlighterRunnerPrivate::resultsReady,
|
&SyntaxHighlighterRunnerPrivate::resultsReady,
|
||||||
this,
|
this,
|
||||||
[this](const QList<SyntaxHighlighter::Result> &result) {
|
&SyntaxHighlighterRunner::applyFormatRanges);
|
||||||
auto done = std::find_if(result.cbegin(),
|
|
||||||
result.cend(),
|
changeDocument(0, 0, document->characterCount());
|
||||||
[](const SyntaxHighlighter::Result &res) {
|
connect(document,
|
||||||
return res.m_state == SyntaxHighlighter::State::Done;
|
&QTextDocument::contentsChange,
|
||||||
});
|
this,
|
||||||
if (done != result.cend()) {
|
&SyntaxHighlighterRunner::changeDocument);
|
||||||
m_syntaxInfoUpdated = SyntaxHighlighter::State::Done;
|
} else {
|
||||||
emit highlightingFinished();
|
connect(d,
|
||||||
return;
|
&SyntaxHighlighterRunnerPrivate::resultsReady,
|
||||||
}
|
this,
|
||||||
m_syntaxInfoUpdated = SyntaxHighlighter::State::InProgress;
|
[this](const QList<SyntaxHighlighter::Result> &result) {
|
||||||
});
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseSyntaxHighlighterRunner::~BaseSyntaxHighlighterRunner() = default;
|
SyntaxHighlighterRunner::~SyntaxHighlighterRunner()
|
||||||
|
{
|
||||||
|
if (m_thread) {
|
||||||
|
m_thread->requestInterruption();
|
||||||
|
m_thread->quit();
|
||||||
|
m_thread->wait();
|
||||||
|
} else {
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::applyFormatRanges(const QList<SyntaxHighlighter::Result> &results)
|
void SyntaxHighlighterRunner::applyFormatRanges(const QList<SyntaxHighlighter::Result> &results)
|
||||||
{
|
{
|
||||||
if (m_document == nullptr)
|
if (m_document == nullptr)
|
||||||
return;
|
return;
|
||||||
@@ -164,11 +187,11 @@ void BaseSyntaxHighlighterRunner::applyFormatRanges(const QList<SyntaxHighlighte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::changeDocument(int from, int charsRemoved, int charsAdded)
|
void SyntaxHighlighterRunner::changeDocument(int from, int charsRemoved, int charsAdded)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_document, return);
|
QTC_ASSERT(m_document, return);
|
||||||
m_syntaxInfoUpdated = SyntaxHighlighter::State::InProgress;
|
m_syntaxInfoUpdated = SyntaxHighlighter::State::InProgress;
|
||||||
QMap<int, BaseSyntaxHighlighterRunner::BlockPreeditData> blocksPreedit;
|
QMap<int, SyntaxHighlighterRunner::BlockPreeditData> blocksPreedit;
|
||||||
QTextBlock block = m_document->findBlock(from);
|
QTextBlock block = m_document->findBlock(from);
|
||||||
const QTextBlock endBlock = m_document->findBlock(from + charsAdded);
|
const QTextBlock endBlock = m_document->findBlock(from + charsAdded);
|
||||||
while (block.isValid() && block != endBlock) {
|
while (block.isValid() && block != endBlock) {
|
||||||
@@ -179,97 +202,64 @@ void BaseSyntaxHighlighterRunner::changeDocument(int from, int charsRemoved, int
|
|||||||
block = block.next();
|
block = block.next();
|
||||||
}
|
}
|
||||||
const QString text = Utils::Text::textAt(QTextCursor(m_document), from, charsAdded);
|
const QString text = Utils::Text::textAt(QTextCursor(m_document), from, charsAdded);
|
||||||
QMetaObject::invokeMethod(d.get(), [this, from, charsRemoved, text, blocksPreedit] {
|
QMetaObject::invokeMethod(d, [this, from, charsRemoved, text, blocksPreedit] {
|
||||||
d->changeDocument(from, charsRemoved, text, blocksPreedit);
|
d->changeDocument(from, charsRemoved, text, blocksPreedit);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseSyntaxHighlighterRunner::useGenericHighlighter() const
|
bool SyntaxHighlighterRunner::useGenericHighlighter() const
|
||||||
{
|
{
|
||||||
return m_useGenericHighlighter;
|
return m_useGenericHighlighter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::setExtraFormats(
|
void SyntaxHighlighterRunner::setExtraFormats(
|
||||||
const QMap<int, QList<QTextLayout::FormatRange>> &formatMap)
|
const QMap<int, QList<QTextLayout::FormatRange>> &formatMap)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(d.get(), [this, formatMap] { d->setExtraFormats(formatMap); });
|
QMetaObject::invokeMethod(d, [this, formatMap] { d->setExtraFormats(formatMap); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::clearExtraFormats(const QList<int> &blockNumbers)
|
void SyntaxHighlighterRunner::clearExtraFormats(const QList<int> &blockNumbers)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(d.get(), [this, blockNumbers] { d->clearExtraFormats(blockNumbers); });
|
QMetaObject::invokeMethod(d, [this, blockNumbers] { d->clearExtraFormats(blockNumbers); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::clearAllExtraFormats()
|
void SyntaxHighlighterRunner::clearAllExtraFormats()
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(d.get(), [this] { d->clearAllExtraFormats(); });
|
QMetaObject::invokeMethod(d, [this] { d->clearAllExtraFormats(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::setFontSettings(const TextEditor::FontSettings &fontSettings)
|
void SyntaxHighlighterRunner::setFontSettings(const TextEditor::FontSettings &fontSettings)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(d.get(), [this, fontSettings] { d->setFontSettings(fontSettings); });
|
QMetaObject::invokeMethod(d, [this, fontSettings] { d->setFontSettings(fontSettings); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::setLanguageFeaturesFlags(unsigned int flags)
|
void SyntaxHighlighterRunner::setLanguageFeaturesFlags(unsigned int flags)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(d.get(), [this, flags] { d->setLanguageFeaturesFlags(flags); });
|
QMetaObject::invokeMethod(d, [this, flags] { d->setLanguageFeaturesFlags(flags); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::setEnabled(bool enabled)
|
void SyntaxHighlighterRunner::setEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(d.get(), [this, enabled] { d->setEnabled(enabled); });
|
QMetaObject::invokeMethod(d, [this, enabled] { d->setEnabled(enabled); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::rehighlight()
|
void SyntaxHighlighterRunner::rehighlight()
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(d.get(), [this] { d->rehighlight(); });
|
QMetaObject::invokeMethod(d, [this] { d->rehighlight(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BaseSyntaxHighlighterRunner::definitionName()
|
QString SyntaxHighlighterRunner::definitionName()
|
||||||
{
|
{
|
||||||
return m_definitionName;
|
return m_definitionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseSyntaxHighlighterRunner::setDefinitionName(const QString &name)
|
void SyntaxHighlighterRunner::setDefinitionName(const QString &name)
|
||||||
{
|
{
|
||||||
if (name.isEmpty())
|
if (name.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_definitionName = name;
|
m_definitionName = name;
|
||||||
QMetaObject::invokeMethod(d.get(), [this, name] { d->setDefinitionName(name); });
|
QMetaObject::invokeMethod(d, [this, name] { d->setDefinitionName(name); });
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------- ThreadedSyntaxHighlighterRunner ------------------------------------
|
|
||||||
|
|
||||||
ThreadedSyntaxHighlighterRunner::ThreadedSyntaxHighlighterRunner(SyntaxHighLighterCreator creator,
|
|
||||||
QTextDocument *document)
|
|
||||||
: BaseSyntaxHighlighterRunner(creator, nullptr)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(document, return);
|
|
||||||
|
|
||||||
d->moveToThread(&m_thread);
|
|
||||||
connect(&m_thread, &QThread::finished, d.get(), &QObject::deleteLater);
|
|
||||||
m_thread.start();
|
|
||||||
|
|
||||||
m_document = document;
|
|
||||||
connect(d.get(),
|
|
||||||
&SyntaxHighlighterRunnerPrivate::resultsReady,
|
|
||||||
this,
|
|
||||||
&ThreadedSyntaxHighlighterRunner::applyFormatRanges);
|
|
||||||
|
|
||||||
changeDocument(0, 0, document->characterCount());
|
|
||||||
connect(document,
|
|
||||||
&QTextDocument::contentsChange,
|
|
||||||
this,
|
|
||||||
&ThreadedSyntaxHighlighterRunner::changeDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadedSyntaxHighlighterRunner::~ThreadedSyntaxHighlighterRunner()
|
|
||||||
{
|
|
||||||
m_thread.requestInterruption();
|
|
||||||
m_thread.quit();
|
|
||||||
m_thread.wait();
|
|
||||||
d.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace TextEditor
|
} // namespace TextEditor
|
||||||
|
@@ -20,21 +20,22 @@ namespace TextEditor {
|
|||||||
|
|
||||||
class SyntaxHighlighterRunnerPrivate;
|
class SyntaxHighlighterRunnerPrivate;
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT BaseSyntaxHighlighterRunner : public QObject
|
class TEXTEDITOR_EXPORT SyntaxHighlighterRunner : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
using SyntaxHighLighterCreator = std::function<SyntaxHighlighter *()>;
|
using SyntaxHighlighterCreator = std::function<SyntaxHighlighter *()>;
|
||||||
struct BlockPreeditData {
|
struct BlockPreeditData {
|
||||||
int position;
|
int position;
|
||||||
QString text;
|
QString text;
|
||||||
};
|
};
|
||||||
|
|
||||||
BaseSyntaxHighlighterRunner(SyntaxHighLighterCreator creator,
|
SyntaxHighlighterRunner(SyntaxHighlighterCreator creator,
|
||||||
QTextDocument *document,
|
QTextDocument *document,
|
||||||
const TextEditor::FontSettings &fontSettings
|
bool async,
|
||||||
= TextEditorSettings::fontSettings());
|
const TextEditor::FontSettings &fontSettings
|
||||||
virtual ~BaseSyntaxHighlighterRunner();
|
= TextEditorSettings::fontSettings());
|
||||||
|
virtual ~SyntaxHighlighterRunner();
|
||||||
|
|
||||||
void setExtraFormats(const QMap<int, QList<QTextLayout::FormatRange>> &formats);
|
void setExtraFormats(const QMap<int, QList<QTextLayout::FormatRange>> &formats);
|
||||||
void clearExtraFormats(const QList<int> &blockNumbers);
|
void clearExtraFormats(const QList<int> &blockNumbers);
|
||||||
@@ -55,28 +56,16 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void highlightingFinished();
|
void highlightingFinished();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
std::unique_ptr<SyntaxHighlighterRunnerPrivate> d;
|
|
||||||
QPointer<QTextDocument> m_document = nullptr;
|
|
||||||
void applyFormatRanges(const QList<SyntaxHighlighter::Result> &results);
|
void applyFormatRanges(const QList<SyntaxHighlighter::Result> &results);
|
||||||
void changeDocument(int from, int charsRemoved, int charsAdded);
|
void changeDocument(int from, int charsRemoved, int charsAdded);
|
||||||
|
|
||||||
|
SyntaxHighlighterRunnerPrivate *d;
|
||||||
|
QPointer<QTextDocument> m_document = nullptr;
|
||||||
SyntaxHighlighter::State m_syntaxInfoUpdated = SyntaxHighlighter::State::Done;
|
SyntaxHighlighter::State m_syntaxInfoUpdated = SyntaxHighlighter::State::Done;
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_useGenericHighlighter = false;
|
bool m_useGenericHighlighter = false;
|
||||||
QString m_definitionName;
|
QString m_definitionName;
|
||||||
};
|
std::optional<QThread> m_thread;
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT ThreadedSyntaxHighlighterRunner : public BaseSyntaxHighlighterRunner
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ThreadedSyntaxHighlighterRunner(SyntaxHighLighterCreator SyntaxHighLighterCreator,
|
|
||||||
QTextDocument *document);
|
|
||||||
~ThreadedSyntaxHighlighterRunner();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QThread m_thread;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TextEditor
|
} // namespace TextEditor
|
||||||
|
@@ -101,7 +101,7 @@ public:
|
|||||||
TextMarks m_marksCache; // Marks not owned
|
TextMarks m_marksCache; // Marks not owned
|
||||||
Utils::Guard m_modificationChangedGuard;
|
Utils::Guard m_modificationChangedGuard;
|
||||||
|
|
||||||
BaseSyntaxHighlighterRunner *m_highlighterRunner = nullptr;
|
SyntaxHighlighterRunner *m_highlighterRunner = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
MultiTextCursor TextDocumentPrivate::indentOrUnindent(const MultiTextCursor &cursors,
|
MultiTextCursor TextDocumentPrivate::indentOrUnindent(const MultiTextCursor &cursors,
|
||||||
@@ -635,7 +635,7 @@ QTextDocument *TextDocument::document() const
|
|||||||
return &d->m_document;
|
return &d->m_document;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseSyntaxHighlighterRunner *TextDocument::syntaxHighlighterRunner() const
|
SyntaxHighlighterRunner *TextDocument::syntaxHighlighterRunner() const
|
||||||
{
|
{
|
||||||
return d->m_highlighterRunner;
|
return d->m_highlighterRunner;
|
||||||
}
|
}
|
||||||
@@ -917,14 +917,11 @@ void TextDocument::resetSyntaxHighlighter(const std::function<SyntaxHighlighter
|
|||||||
if (d->m_highlighterRunner)
|
if (d->m_highlighterRunner)
|
||||||
delete d->m_highlighterRunner;
|
delete d->m_highlighterRunner;
|
||||||
|
|
||||||
static const QString value
|
static const bool envValue
|
||||||
= qtcEnvironmentVariable("QTC_USE_THREADED_HIGHLIGHTER", "TRUE").toUpper();
|
= qtcEnvironmentVariable("QTC_USE_THREADED_HIGHLIGHTER", "TRUE").toUpper()
|
||||||
if (threaded && value == QLatin1String("TRUE")) {
|
== QLatin1String("TRUE");
|
||||||
d->m_highlighterRunner = new ThreadedSyntaxHighlighterRunner(creator, document());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->m_highlighterRunner = new BaseSyntaxHighlighterRunner(creator, document());
|
d->m_highlighterRunner = new SyntaxHighlighterRunner(creator, document(), threaded && envValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextDocument::cleanWhitespace(const QTextCursor &cursor)
|
void TextDocument::cleanWhitespace(const QTextCursor &cursor)
|
||||||
|
@@ -34,7 +34,7 @@ class FontSettings;
|
|||||||
class IAssistProvider;
|
class IAssistProvider;
|
||||||
class StorageSettings;
|
class StorageSettings;
|
||||||
class SyntaxHighlighter;
|
class SyntaxHighlighter;
|
||||||
class BaseSyntaxHighlighterRunner;
|
class SyntaxHighlighterRunner;
|
||||||
class TabSettings;
|
class TabSettings;
|
||||||
class TextDocumentPrivate;
|
class TextDocumentPrivate;
|
||||||
class TextMark;
|
class TextMark;
|
||||||
@@ -128,7 +128,7 @@ public:
|
|||||||
|
|
||||||
using SyntaxHighLighterCreator = std::function<SyntaxHighlighter *()>;
|
using SyntaxHighLighterCreator = std::function<SyntaxHighlighter *()>;
|
||||||
void resetSyntaxHighlighter(const SyntaxHighLighterCreator &creator, bool threaded = true);
|
void resetSyntaxHighlighter(const SyntaxHighLighterCreator &creator, bool threaded = true);
|
||||||
BaseSyntaxHighlighterRunner *syntaxHighlighterRunner() const;
|
SyntaxHighlighterRunner *syntaxHighlighterRunner() const;
|
||||||
|
|
||||||
bool reload(QString *errorString, QTextCodec *codec);
|
bool reload(QString *errorString, QTextCodec *codec);
|
||||||
void cleanWhitespace(const QTextCursor &cursor);
|
void cleanWhitespace(const QTextCursor &cursor);
|
||||||
|
@@ -1936,7 +1936,7 @@ void TextEditorWidgetPrivate::foldLicenseHeader()
|
|||||||
QStringList commentMarker;
|
QStringList commentMarker;
|
||||||
QStringList docMarker;
|
QStringList docMarker;
|
||||||
HighlighterHelper::Definition def;
|
HighlighterHelper::Definition def;
|
||||||
if (BaseSyntaxHighlighterRunner *highlighter = q->textDocument()->syntaxHighlighterRunner())
|
if (SyntaxHighlighterRunner *highlighter = q->textDocument()->syntaxHighlighterRunner())
|
||||||
def = HighlighterHelper::definitionForName(highlighter->definitionName());
|
def = HighlighterHelper::definitionForName(highlighter->definitionName());
|
||||||
|
|
||||||
if (def.isValid()) {
|
if (def.isValid()) {
|
||||||
@@ -3743,7 +3743,7 @@ void TextEditorWidgetPrivate::setupFromDefinition(const KSyntaxHighlighting::Def
|
|||||||
|
|
||||||
KSyntaxHighlighting::Definition TextEditorWidgetPrivate::currentDefinition()
|
KSyntaxHighlighting::Definition TextEditorWidgetPrivate::currentDefinition()
|
||||||
{
|
{
|
||||||
if (BaseSyntaxHighlighterRunner *highlighter = m_document->syntaxHighlighterRunner())
|
if (SyntaxHighlighterRunner *highlighter = m_document->syntaxHighlighterRunner())
|
||||||
return HighlighterHelper::definitionForName(highlighter->definitionName());
|
return HighlighterHelper::definitionForName(highlighter->definitionName());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -8132,7 +8132,7 @@ void TextEditorWidget::setDisplaySettings(const DisplaySettings &ds)
|
|||||||
optionFlags.setFlag(QTextOption::AddSpaceForLineAndParagraphSeparators);
|
optionFlags.setFlag(QTextOption::AddSpaceForLineAndParagraphSeparators);
|
||||||
optionFlags.setFlag(QTextOption::ShowTabsAndSpaces, ds.m_visualizeWhitespace);
|
optionFlags.setFlag(QTextOption::ShowTabsAndSpaces, ds.m_visualizeWhitespace);
|
||||||
if (optionFlags != currentOptionFlags) {
|
if (optionFlags != currentOptionFlags) {
|
||||||
if (BaseSyntaxHighlighterRunner *highlighter = textDocument()->syntaxHighlighterRunner())
|
if (SyntaxHighlighterRunner *highlighter = textDocument()->syntaxHighlighterRunner())
|
||||||
highlighter->rehighlight();
|
highlighter->rehighlight();
|
||||||
QTextOption option = document()->defaultTextOption();
|
QTextOption option = document()->defaultTextOption();
|
||||||
option.setFlags(optionFlags);
|
option.setFlags(optionFlags);
|
||||||
|
@@ -1100,7 +1100,7 @@ void VcsBaseEditorWidget::slotActivateAnnotation()
|
|||||||
|
|
||||||
disconnect(this, &QPlainTextEdit::textChanged, this, &VcsBaseEditorWidget::slotActivateAnnotation);
|
disconnect(this, &QPlainTextEdit::textChanged, this, &VcsBaseEditorWidget::slotActivateAnnotation);
|
||||||
|
|
||||||
if (BaseSyntaxHighlighterRunner *ah = textDocument()->syntaxHighlighterRunner()) {
|
if (SyntaxHighlighterRunner *ah = textDocument()->syntaxHighlighterRunner()) {
|
||||||
ah->rehighlight();
|
ah->rehighlight();
|
||||||
} else {
|
} else {
|
||||||
BaseAnnotationHighlighterCreator creator = annotationHighlighterCreator();
|
BaseAnnotationHighlighterCreator creator = annotationHighlighterCreator();
|
||||||
|
@@ -32,7 +32,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QTextDocument *doc = nullptr;
|
QTextDocument *doc = nullptr;
|
||||||
BaseSyntaxHighlighterRunner *highlighterRunner = nullptr;
|
SyntaxHighlighterRunner *highlighterRunner = nullptr;
|
||||||
FontSettings fontsettings;
|
FontSettings fontsettings;
|
||||||
QHash<int, QTextCharFormat> formatHash;
|
QHash<int, QTextCharFormat> formatHash;
|
||||||
QTextCharFormat whitespaceFormat;
|
QTextCharFormat whitespaceFormat;
|
||||||
@@ -59,8 +59,8 @@ Last)";
|
|||||||
doc = new QTextDocument();
|
doc = new QTextDocument();
|
||||||
doc->setPlainText(text);
|
doc->setPlainText(text);
|
||||||
|
|
||||||
highlighterRunner = new BaseSyntaxHighlighterRunner(
|
highlighterRunner = new SyntaxHighlighterRunner(
|
||||||
[this] { return new SyntaxHighlighter(doc, fontsettings); }, doc, fontsettings);
|
[this] { return new SyntaxHighlighter(doc, fontsettings); }, doc, false, fontsettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const HighlightingResults &highlightingResults()
|
static const HighlightingResults &highlightingResults()
|
||||||
|
Reference in New Issue
Block a user