forked from qt-creator/qt-creator
CppEditor: Do not underline leading whitespace
... when visualizing the range of a code model warning. Otherwise, warnings covering multiple lines can get too noisy. Fixes: QTCREATORBUG-18659 Change-Id: Ieff7729d8069e791027f7bdde5fca13f4c7f7163 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -205,6 +205,9 @@ private slots:
|
||||
void test_useSelections_data();
|
||||
void test_useSelections();
|
||||
|
||||
void test_selectionFiltering_data();
|
||||
void test_selectionFiltering();
|
||||
|
||||
// tests for "Include Hierarchy"
|
||||
void test_includehierarchy_data();
|
||||
void test_includehierarchy();
|
||||
|
@@ -326,7 +326,8 @@ void CppEditorWidget::onCodeWarningsUpdated(unsigned revision,
|
||||
if (revision != documentRevision())
|
||||
return;
|
||||
|
||||
setExtraSelections(TextEditorWidget::CodeWarningsSelection, selections);
|
||||
setExtraSelections(TextEditorWidget::CodeWarningsSelection,
|
||||
unselectLeadingWhitespace(selections));
|
||||
setRefactorMarkers(refactorMarkers + RefactorMarker::filterOutType(
|
||||
this->refactorMarkers(), CppTools::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID));
|
||||
}
|
||||
@@ -1163,6 +1164,63 @@ void CppEditorWidget::invokeTextEditorWidgetAssist(TextEditor::AssistKind assist
|
||||
invokeAssist(assistKind, provider);
|
||||
}
|
||||
|
||||
const QList<QTextEdit::ExtraSelection> CppEditorWidget::unselectLeadingWhitespace(
|
||||
const QList<QTextEdit::ExtraSelection> &selections)
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> filtered;
|
||||
for (const QTextEdit::ExtraSelection &sel : selections) {
|
||||
QList<QTextEdit::ExtraSelection> splitSelections;
|
||||
int firstNonWhitespacePos = -1;
|
||||
int lastNonWhitespacePos = -1;
|
||||
bool split = false;
|
||||
const QTextBlock firstBlock = sel.cursor.document()->findBlock(sel.cursor.selectionStart());
|
||||
bool inIndentation = firstBlock.position() == sel.cursor.selectionStart();
|
||||
const auto createSplitSelection = [&] {
|
||||
QTextEdit::ExtraSelection newSelection;
|
||||
newSelection.cursor = QTextCursor(sel.cursor.document());
|
||||
newSelection.cursor.setPosition(firstNonWhitespacePos);
|
||||
newSelection.cursor.setPosition(lastNonWhitespacePos + 1, QTextCursor::KeepAnchor);
|
||||
newSelection.format = sel.format;
|
||||
splitSelections << newSelection;
|
||||
};
|
||||
for (int i = sel.cursor.selectionStart(); i < sel.cursor.selectionEnd(); ++i) {
|
||||
const QChar curChar = sel.cursor.document()->characterAt(i);
|
||||
if (!curChar.isSpace()) {
|
||||
if (firstNonWhitespacePos == -1)
|
||||
firstNonWhitespacePos = i;
|
||||
lastNonWhitespacePos = i;
|
||||
}
|
||||
if (!inIndentation) {
|
||||
if (curChar == QChar::ParagraphSeparator)
|
||||
inIndentation = true;
|
||||
continue;
|
||||
}
|
||||
if (curChar == QChar::ParagraphSeparator)
|
||||
continue;
|
||||
if (curChar.isSpace()) {
|
||||
if (firstNonWhitespacePos != -1) {
|
||||
createSplitSelection();
|
||||
firstNonWhitespacePos = -1;
|
||||
lastNonWhitespacePos = -1;
|
||||
}
|
||||
split = true;
|
||||
continue;
|
||||
}
|
||||
inIndentation = false;
|
||||
}
|
||||
|
||||
if (!split) {
|
||||
filtered << sel;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (firstNonWhitespacePos != -1)
|
||||
createSplitSelection();
|
||||
filtered << splitSelections;
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CppEditor
|
||||
|
||||
|
@@ -94,6 +94,9 @@ public:
|
||||
void invokeTextEditorWidgetAssist(TextEditor::AssistKind assistKind,
|
||||
TextEditor::IAssistProvider *provider) override;
|
||||
|
||||
static const QList<QTextEdit::ExtraSelection>
|
||||
unselectLeadingWhitespace(const QList<QTextEdit::ExtraSelection> &selections);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *) override;
|
||||
|
@@ -249,5 +249,70 @@ void CppEditorPlugin::test_useSelections()
|
||||
Tests::UseSelectionsTestCase(testDocument, expectedSelections);
|
||||
}
|
||||
|
||||
void CppEditorPlugin::test_selectionFiltering_data()
|
||||
{
|
||||
QTest::addColumn<QString>("source");
|
||||
QTest::addColumn<SelectionList>("original");
|
||||
QTest::addColumn<SelectionList>("filtered");
|
||||
|
||||
QTest::addRow("QTCREATORBUG-18659")
|
||||
<< QString("int main()\n"
|
||||
"{\n"
|
||||
" [](const Foo &foo) -> Foo {\n"
|
||||
" return foo;\n"
|
||||
" };\n"
|
||||
"}\n")
|
||||
<< SelectionList{{3, 4, 53}}
|
||||
<< SelectionList{{3, 4, 27}, {4, 8, 11}, {5, 4, 1}};
|
||||
QTest::addRow("indentation-selected-in-first-line")
|
||||
<< QString("int main()\n"
|
||||
"{\n"
|
||||
" [](const Foo &foo) -> Foo {\n"
|
||||
" return foo;\n"
|
||||
" };\n"
|
||||
"}\n")
|
||||
<< SelectionList{{3, 0, 57}}
|
||||
<< SelectionList{{3, 4, 27}, {4, 8, 11}, {5, 4, 1}};
|
||||
}
|
||||
|
||||
void CppEditorPlugin::test_selectionFiltering()
|
||||
{
|
||||
QFETCH(QString, source);
|
||||
QFETCH(SelectionList, original);
|
||||
QFETCH(SelectionList, filtered);
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setPlainText(source);
|
||||
|
||||
const auto convertList = [&doc](const SelectionList &in) {
|
||||
QList<QTextEdit::ExtraSelection> out;
|
||||
for (const Selection &selIn : in) {
|
||||
QTextEdit::ExtraSelection selOut;
|
||||
selOut.format.setFontItalic(true);
|
||||
const QTextBlock startBlock = doc.findBlockByLineNumber(selIn.line - 1);
|
||||
const int startPos = startBlock.position() + selIn.column;
|
||||
selOut.cursor = QTextCursor(&doc);
|
||||
selOut.cursor.setPosition(startPos);
|
||||
selOut.cursor.setPosition(startPos + selIn.length, QTextCursor::KeepAnchor);
|
||||
out << selOut;
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
const QList<QTextEdit::ExtraSelection> expected = convertList(filtered);
|
||||
const QList<QTextEdit::ExtraSelection> actual
|
||||
= CppEditorWidget::unselectLeadingWhitespace(convertList(original));
|
||||
|
||||
QCOMPARE(actual.length(), expected.length());
|
||||
for (int i = 0; i < expected.length(); ++i) {
|
||||
const QTextEdit::ExtraSelection &expectedSelection = expected.at(i);
|
||||
const QTextEdit::ExtraSelection &actualSelection = actual.at(i);
|
||||
QCOMPARE(actualSelection.format, expectedSelection.format);
|
||||
QCOMPARE(actualSelection.cursor.document(), expectedSelection.cursor.document());
|
||||
QCOMPARE(actualSelection.cursor.position(), expectedSelection.cursor.position());
|
||||
QCOMPARE(actualSelection.cursor.anchor(), expectedSelection.cursor.anchor());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CppEditor
|
||||
|
Reference in New Issue
Block a user