diff options
author | David Schulz <david.schulz@qt.io> | 2023-06-06 07:31:33 +0200 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2023-06-14 10:05:12 +0000 |
commit | 9091c994298f75ca76a9e1244236925320f60e15 (patch) | |
tree | e8d4a0a8a805573d87a8a287a47370965d7408d9 /src/plugins/texteditor/syntaxhighlighter.cpp | |
parent | 196245c8f63d75eb10d3af3e7e7721d1575deaa8 (diff) |
TextEditor: correctly highlight preedit text
Fixes: QTCREATORBUG-29134
Change-Id: I8c5cdab8c5b2e5a2380c9e4aeadaf1bd72e60e09
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
Diffstat (limited to 'src/plugins/texteditor/syntaxhighlighter.cpp')
-rw-r--r-- | src/plugins/texteditor/syntaxhighlighter.cpp | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp index 6d2616193e..21db8c0cd3 100644 --- a/src/plugins/texteditor/syntaxhighlighter.cpp +++ b/src/plugins/texteditor/syntaxhighlighter.cpp @@ -17,6 +17,12 @@ namespace TextEditor { +enum HighlighterTypeProperty +{ + SyntaxHighlight = QTextFormat::UserProperty + 1, + SemanticHighlight = QTextFormat::UserProperty + 2 +}; + class SyntaxHighlighterPrivate { SyntaxHighlighter *q_ptr = nullptr; @@ -98,9 +104,9 @@ void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, in QVector<QTextLayout::FormatRange> ranges; QVector<QTextLayout::FormatRange> oldRanges; - std::tie(ranges, oldRanges) + std::tie(oldRanges, ranges) = Utils::partition(layout->formats(), [](const QTextLayout::FormatRange &range) { - return range.format.property(QTextFormat::UserProperty).toBool(); + return range.format.property(SyntaxHighlight).toBool(); }); if (currentBlock.contains(from)) { @@ -129,8 +135,23 @@ void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, in while (i < formatChanges.count() && formatChanges.at(i) == r.format) ++i; + r.format.setProperty(SyntaxHighlight, true); r.length = i - r.start; + const QString preeditText = currentBlock.layout()->preeditAreaText(); + if (!preeditText.isEmpty()) { + const int preeditPosition = currentBlock.layout()->preeditAreaPosition(); + if (r.start >= preeditPosition) { + r.start += preeditText.length(); + } else if (r.start + r.length > preeditPosition) { + QTextLayout::FormatRange beforePreeditRange = r; + r.start = preeditPosition + preeditText.length(); + r.length = r.length - (r.start - preeditPosition); + beforePreeditRange.length = preeditPosition - beforePreeditRange.start; + newRanges << beforePreeditRange; + } + } + newRanges << r; } @@ -656,6 +677,24 @@ void SyntaxHighlighter::setExtraFormats(const QTextBlock &block, if (block.layout() == nullptr || blockLength == 0) return; + const QString preeditText = block.layout()->preeditAreaText(); + if (!preeditText.isEmpty()) { + QVector<QTextLayout::FormatRange> additionalRanges; + const int preeditPosition = block.layout()->preeditAreaPosition(); + for (QTextLayout::FormatRange &r : formats) { + if (r.start >= preeditPosition) { + r.start += preeditText.length(); + } else if (r.start + r.length > preeditPosition) { + QTextLayout::FormatRange afterPreeditRange = r; + afterPreeditRange.start = preeditPosition + preeditText.length(); + afterPreeditRange.length = r.length - (preeditPosition - r.start); + additionalRanges << afterPreeditRange; + r.length = preeditPosition - r.start; + } + } + formats << additionalRanges; + } + Utils::sort(formats, byStartOfRange); const QVector<QTextLayout::FormatRange> all = block.layout()->formats(); @@ -663,11 +702,11 @@ void SyntaxHighlighter::setExtraFormats(const QTextBlock &block, QVector<QTextLayout::FormatRange> formatsToApply; std::tie(previousSemanticFormats, formatsToApply) = Utils::partition(all, [](const QTextLayout::FormatRange &r) { - return r.format.hasProperty(QTextFormat::UserProperty); + return r.format.property(SemanticHighlight).toBool(); }); for (auto &format : formats) - format.format.setProperty(QTextFormat::UserProperty, true); + format.format.setProperty(SemanticHighlight, true); if (formats.size() == previousSemanticFormats.size()) { Utils::sort(previousSemanticFormats, byStartOfRange); @@ -694,7 +733,7 @@ void SyntaxHighlighter::clearExtraFormats(const QTextBlock &block) const QVector<QTextLayout::FormatRange> formatsToApply = Utils::filtered(block.layout()->formats(), [](const QTextLayout::FormatRange &r) { - return !r.format.hasProperty(QTextFormat::UserProperty); + return !r.format.property(SemanticHighlight).toBool(); }); bool wasInReformatBlocks = d->inReformatBlocks; |