aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/texteditor
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/texteditor')
-rw-r--r--src/plugins/texteditor/CMakeLists.txt1
-rw-r--r--src/plugins/texteditor/basehoverhandler.cpp2
-rw-r--r--src/plugins/texteditor/codeassist/codeassistant.cpp2
-rw-r--r--src/plugins/texteditor/colorpreviewhoverhandler.cpp2
-rw-r--r--src/plugins/texteditor/highlighter_test.cpp195
-rw-r--r--src/plugins/texteditor/highlighter_test.h26
-rw-r--r--src/plugins/texteditor/snippets/snippet.cpp4
-rw-r--r--src/plugins/texteditor/textdocumentlayout.cpp2
-rw-r--r--src/plugins/texteditor/texteditor.cpp8
-rw-r--r--src/plugins/texteditor/texteditor.qbs2
-rw-r--r--src/plugins/texteditor/texteditorplugin.cpp2
11 files changed, 237 insertions, 9 deletions
diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt
index 048cd40b1d5..2a99947b933 100644
--- a/src/plugins/texteditor/CMakeLists.txt
+++ b/src/plugins/texteditor/CMakeLists.txt
@@ -115,5 +115,6 @@ extend_qtc_plugin(TextEditor
CONDITION WITH_TESTS
SOURCES
codeassist/codeassist_test.cpp codeassist/codeassist_test.h
+ highlighter_test.cpp highlighter_test.h
texteditor_test.cpp
)
diff --git a/src/plugins/texteditor/basehoverhandler.cpp b/src/plugins/texteditor/basehoverhandler.cpp
index 203ecc36e20..45949fb8863 100644
--- a/src/plugins/texteditor/basehoverhandler.cpp
+++ b/src/plugins/texteditor/basehoverhandler.cpp
@@ -121,7 +121,7 @@ void BaseHoverHandler::process(TextEditorWidget *widget, int pos, ReportPriority
void BaseHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos, ReportPriority report)
{
- const auto cleanup = qScopeGuard([this, report] { report(priority()); });
+ const QScopeGuard cleanup([this, report] { report(priority()); });
QString tooltip = editorWidget->extraSelectionTooltip(pos);
if (!tooltip.isEmpty())
diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp
index 0da6571da8f..0bdf34efaba 100644
--- a/src/plugins/texteditor/codeassist/codeassistant.cpp
+++ b/src/plugins/texteditor/codeassist/codeassistant.cpp
@@ -158,7 +158,7 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
bool isUpdate)
{
// make sure to cleanup old proposals if we cannot find a new assistant
- auto cleanup = qScopeGuard([this] { destroyContext(); });
+ QScopeGuard cleanup([this] { destroyContext(); });
if (isWaitingForProposal())
cancelCurrentRequest();
diff --git a/src/plugins/texteditor/colorpreviewhoverhandler.cpp b/src/plugins/texteditor/colorpreviewhoverhandler.cpp
index 1a66392c550..7e3134e8c27 100644
--- a/src/plugins/texteditor/colorpreviewhoverhandler.cpp
+++ b/src/plugins/texteditor/colorpreviewhoverhandler.cpp
@@ -335,7 +335,7 @@ static QColor colorFromFuncAndArgs(const QString &func, const QStringList &args)
void ColorPreviewHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
int pos, ReportPriority report)
{
- const auto cleanup = qScopeGuard([this, report] { report(priority()); });
+ const QScopeGuard cleanup([this, report] { report(priority()); });
if (editorWidget->extraSelectionTooltip(pos).isEmpty()) {
const QTextBlock tb = editorWidget->document()->findBlock(pos);
diff --git a/src/plugins/texteditor/highlighter_test.cpp b/src/plugins/texteditor/highlighter_test.cpp
new file mode 100644
index 00000000000..f0652a780b3
--- /dev/null
+++ b/src/plugins/texteditor/highlighter_test.cpp
@@ -0,0 +1,195 @@
+// 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 "syntaxhighlighter.h"
+
+#include "highlighter_test.h"
+
+#include "fontsettings.h"
+#include "textdocument.h"
+#include "texteditor.h"
+#include "texteditorsettings.h"
+
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <utils/mimeutils.h>
+
+#include <QtTest/QtTest>
+
+namespace TextEditor::Internal {
+
+constexpr auto json = R"(
+{
+ "name": "Test",
+ "scope": "source.test",
+ "uuid": "test",
+ "patterns": [
+ {
+ "match": "a",
+ "name": "keyword.test"
+ }
+ ]
+}
+)";
+
+void GenerigHighlighterTests::initTestCase()
+{
+ QString title = "test.json";
+
+ Core::IEditor *editor = Core::EditorManager::openEditorWithContents(
+ Core::Constants::K_DEFAULT_TEXT_EDITOR_ID, &title, json);
+ QVERIFY(editor);
+ m_editor = qobject_cast<BaseTextEditor *>(editor);
+ m_editor->editorWidget()->configureGenericHighlighter(Utils::mimeTypeForName("application/json"));
+ QVERIFY(m_editor);
+ m_editor->textDocument()->syntaxHighlighter()->rehighlight();
+}
+
+using FormatRanges = QList<QTextLayout::FormatRange>;
+
+QTextCharFormat toFormat(const TextStyle &style)
+{
+ const static FontSettings fontSettings = TextEditorSettings::fontSettings();
+ auto format = fontSettings.toTextCharFormat(style);
+ if (style == C_FUNCTION)
+ format.setFontWeight(QFont::Bold); // is explicitly set by the ksyntax format definition
+ if (style == C_TEXT) {
+ format = QTextCharFormat();
+ format.setFontWeight(QFont::Bold); // is explicitly set by the ksyntax format definition
+ }
+ return format;
+};
+
+void GenerigHighlighterTests::testHighlight_data()
+{
+ QTest::addColumn<int>("blockNumber");
+ QTest::addColumn<QList<QTextLayout::FormatRange>>("formatRanges");
+
+ // clang-format off
+ QTest::addRow("0:<empty block>")
+ << 0
+ << FormatRanges();
+ QTest::addRow("1:{")
+ << 1
+ << FormatRanges{{0, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("2: \"name\": \"Test\",")
+ << 2
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 6, toFormat(C_TYPE)},
+ {10, 1, toFormat(C_FUNCTION)},
+ {11, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 6, toFormat(C_STRING)},
+ {18, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("3: \"scope\": \"source.test\",")
+ << 3
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 7, toFormat(C_TYPE)},
+ {11, 1, toFormat(C_FUNCTION)},
+ {12, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {13, 13, toFormat(C_STRING)},
+ {26, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("4: \"uuid\": \"test\",")
+ << 4
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 6, toFormat(C_TYPE)},
+ {10, 1, toFormat(C_FUNCTION)},
+ {11, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 6, toFormat(C_STRING)},
+ {18, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("5: \"patterns\": [")
+ << 5
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 10, toFormat(C_TYPE)},
+ {14, 1, toFormat(C_FUNCTION)},
+ {15, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {16, 1, toFormat(C_TEXT)}};
+ QTest::addRow("6: {")
+ << 6
+ << FormatRanges{{0, 8, toFormat(C_VISUAL_WHITESPACE)},
+ {8, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("7: \"match\": \"a\",")
+ << 7
+ << FormatRanges{{0, 12, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 7, toFormat(C_TYPE)},
+ {19, 1, toFormat(C_FUNCTION)},
+ {20, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {21, 3, toFormat(C_STRING)},
+ {24, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("8: \"name\": \"keyword.test\"")
+ << 8
+ << FormatRanges{{0, 12, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 6, toFormat(C_TYPE)},
+ {18, 1, toFormat(C_FUNCTION)},
+ {19, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {20, 14, toFormat(C_STRING)}};
+ QTest::addRow("9: }")
+ << 9
+ << FormatRanges{{0, 8, toFormat(C_VISUAL_WHITESPACE)},
+ {8, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("10: ]")
+ << 10
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 1, toFormat(C_TEXT)}};
+ QTest::addRow("11:}")
+ << 11
+ << FormatRanges{{0, 1, toFormat(C_FUNCTION)}};
+ // clang-format on
+}
+
+void compareFormats(const QTextLayout::FormatRange &actual, const QTextLayout::FormatRange &expected)
+{
+ QCOMPARE(actual.start, expected.start);
+ QCOMPARE(actual.length, expected.length);
+ QCOMPARE(actual.format.foreground(), expected.format.foreground());
+ QCOMPARE(actual.format.background(), expected.format.background());
+ QCOMPARE(actual.format.fontWeight(), expected.format.fontWeight());
+ QCOMPARE(actual.format.fontItalic(), expected.format.fontItalic());
+ QCOMPARE(actual.format.underlineStyle(), expected.format.underlineStyle());
+ QCOMPARE(actual.format.underlineColor(), expected.format.underlineColor());
+}
+
+void GenerigHighlighterTests::testHighlight()
+{
+ QFETCH(int, blockNumber);
+ QFETCH(FormatRanges, formatRanges);
+
+ QTextBlock block = m_editor->textDocument()->document()->findBlockByNumber(blockNumber);
+ QVERIFY(block.isValid());
+
+ const QList<QTextLayout::FormatRange> actualFormats = block.layout()->formats();
+ // full hash calculation for QTextCharFormat fails so just check the important entries of format
+ QCOMPARE(actualFormats.size(), formatRanges.size());
+ for (int i = 0; i < formatRanges.size(); ++i)
+ compareFormats(actualFormats.at(i), formatRanges.at(i));
+}
+
+void GenerigHighlighterTests::testChange()
+{
+ QTextBlock block = m_editor->textDocument()->document()->findBlockByNumber(10);
+ QVERIFY(block.isValid());
+
+ QTextCursor c(block);
+ c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
+ c.removeSelectedText();
+ m_editor->textDocument()->document()->undo();
+
+ block = m_editor->textDocument()->document()->findBlockByNumber(10);
+ QVERIFY(block.isValid());
+
+ const FormatRanges formatRanges = {{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 1, toFormat(C_TEXT)}};
+ const QList<QTextLayout::FormatRange> actualFormats = block.layout()->formats();
+ // full hash calculation for QTextCharFormat fails so just check the important entries of format
+ QCOMPARE(actualFormats.size(), formatRanges.size());
+ for (int i = 0; i < formatRanges.size(); ++i)
+ compareFormats(actualFormats.at(i), formatRanges.at(i));
+}
+
+void GenerigHighlighterTests::cleanupTestCase()
+{
+ if (m_editor)
+ Core::EditorManager::closeEditors({m_editor});
+ QVERIFY(Core::EditorManager::currentEditor() == nullptr);
+}
+
+} // namespace TextEditor::Internal
diff --git a/src/plugins/texteditor/highlighter_test.h b/src/plugins/texteditor/highlighter_test.h
new file mode 100644
index 00000000000..30c2848c5c1
--- /dev/null
+++ b/src/plugins/texteditor/highlighter_test.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include <QObject>
+
+namespace TextEditor { class BaseTextEditor; }
+
+namespace TextEditor::Internal {
+
+class GenerigHighlighterTests : public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase();
+ void testHighlight_data();
+ void testHighlight();
+ void testChange();
+ void cleanupTestCase();
+
+private:
+ TextEditor::BaseTextEditor *m_editor = nullptr;
+};
+
+} // namespace TextEditor::Internal
diff --git a/src/plugins/texteditor/snippets/snippet.cpp b/src/plugins/texteditor/snippets/snippet.cpp
index 74a4dc543c3..0b3bd080e7a 100644
--- a/src/plugins/texteditor/snippets/snippet.cpp
+++ b/src/plugins/texteditor/snippets/snippet.cpp
@@ -189,7 +189,7 @@ SnippetParseResult Snippet::parse(const QString &snippet)
if (!errorMessage.isEmpty())
return {SnippetParseError{errorMessage, {}, -1}};
- const int count = preprocessedSnippet.count();
+ const int count = preprocessedSnippet.size();
NameMangler *mangler = nullptr;
QMap<QString, int> variableIndexes;
@@ -404,7 +404,7 @@ void Internal::TextEditorPlugin::testSnippetParsing()
QCOMPARE(manglerId, expected.manglerId);
};
- for (int i = 0; i < parts.count(); ++i)
+ for (int i = 0; i < parts.size(); ++i)
rangesCompare(snippet.parts.at(i), parts.at(i));
}
#endif
diff --git a/src/plugins/texteditor/textdocumentlayout.cpp b/src/plugins/texteditor/textdocumentlayout.cpp
index 703f9563bf1..08c1e21117b 100644
--- a/src/plugins/texteditor/textdocumentlayout.cpp
+++ b/src/plugins/texteditor/textdocumentlayout.cpp
@@ -596,6 +596,8 @@ bool TextDocumentLayout::updateSuggestion(const QTextBlock &block,
{
if (TextSuggestion *suggestion = TextDocumentLayout::suggestion(block)) {
auto positionInBlock = position - block.position();
+ if (positionInBlock < suggestion->position())
+ return false;
const QString start = block.text().left(positionInBlock);
const QString end = block.text().mid(positionInBlock);
const QString replacement = suggestion->document()->firstBlock().text();
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index 97c878e4425..33323b3b76a 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -1426,7 +1426,7 @@ void TextEditorWidgetPrivate::print(QPrinter *printer)
return;
doc = doc->clone(doc);
- const auto cleanup = qScopeGuard([doc] { delete doc; });
+ const QScopeGuard cleanup([doc] { delete doc; });
QTextOption opt = doc->defaultTextOption();
opt.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
@@ -2546,7 +2546,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
{
ICore::restartTrimmer();
- auto clearBlockSelectionGuard = qScopeGuard([&]() { d->clearBlockSelection(); });
+ QScopeGuard cleanup([&] { d->clearBlockSelection(); });
if (!isModifier(e) && mouseHidingEnabled())
viewport()->setCursor(Qt::BlankCursor);
@@ -2825,7 +2825,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
}
if (blockSelectionOperation != QTextCursor::NoMove) {
- clearBlockSelectionGuard.dismiss();
+ cleanup.dismiss();
d->handleMoveBlockSelection(blockSelectionOperation);
} else if (!d->cursorMoveKeyEvent(e)) {
QTextCursor cursor = textCursor();
@@ -5275,7 +5275,7 @@ void TextEditorWidgetPrivate::paintTextMarks(QPainter &painter, const ExtraAreaP
int yoffset = blockBoundingRect.top();
painter.save();
- const auto cleanup = qScopeGuard([&painter, size, yoffset, xoffset, overrideIcon] {
+ const QScopeGuard cleanup([&painter, size, yoffset, xoffset, overrideIcon] {
if (!overrideIcon.isNull()) {
const QRect r(xoffset, yoffset, size, size);
overrideIcon.paint(&painter, r, Qt::AlignCenter);
diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs
index 071e0b5fc2a..fa8441f29ef 100644
--- a/src/plugins/texteditor/texteditor.qbs
+++ b/src/plugins/texteditor/texteditor.qbs
@@ -226,6 +226,8 @@ Project {
files: [
"codeassist/codeassist_test.cpp",
"codeassist/codeassist_test.h",
+ "highlighter_test.cpp",
+ "highlighter_test.h",
"texteditor_test.cpp",
]
}
diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp
index 4d5c2268d1e..f82155c0a54 100644
--- a/src/plugins/texteditor/texteditorplugin.cpp
+++ b/src/plugins/texteditor/texteditorplugin.cpp
@@ -22,6 +22,7 @@
#ifdef WITH_TESTS
#include "codeassist/codeassist_test.h"
+#include "highlighter_test.h"
#endif
#include <coreplugin/actionmanager/actioncontainer.h>
@@ -149,6 +150,7 @@ void TextEditorPlugin::initialize()
#ifdef WITH_TESTS
addTest<CodeAssistTests>();
+ addTest<GenerigHighlighterTests>();
#endif
}