diff --git a/autotests/src/searchbar_test.h b/autotests/src/searchbar_test.h --- a/autotests/src/searchbar_test.h +++ b/autotests/src/searchbar_test.h @@ -73,6 +73,9 @@ void testReplaceInBlockMode(); void testReplaceManyCapturesBug365124(); + + void testReplaceEscapeSequence_data(); + void testReplaceEscapeSequence(); }; #endif diff --git a/autotests/src/searchbar_test.cpp b/autotests/src/searchbar_test.cpp --- a/autotests/src/searchbar_test.cpp +++ b/autotests/src/searchbar_test.cpp @@ -639,5 +639,44 @@ QCOMPARE(doc.text(), QString("one::two::three::four::five::six::seven::eight::nine::ten::eleven::twelve::thirteen\n")); } -#include "moc_searchbar_test.cpp" +void SearchBarTest::testReplaceEscapeSequence_data() +{ + QTest::addColumn("textBefore"); + QTest::addColumn("textAfter"); + QTest::addColumn("cursorBefore"); + QTest::addColumn("cursorAfter"); + + testNewRow() << QStringLiteral("a\n") << QStringLiteral("a ") << Cursor(1, 0) << Cursor(0, 2); + testNewRow() << QStringLiteral("a\nb\n") << QStringLiteral("a b ") << Cursor(2, 0) << Cursor(0, 4); + testNewRow() << QStringLiteral("\n\n\n") << QStringLiteral(" ") << Cursor(3, 0) << Cursor(0, 3); +} + +void SearchBarTest::testReplaceEscapeSequence() +{ + QFETCH(QString, textBefore); + QFETCH(QString, textAfter); + QFETCH(Cursor, cursorBefore); + QFETCH(Cursor, cursorAfter); + + // testcase for https://bugs.kde.org/show_bug.cgi?id=381080 + KTextEditor::DocumentPrivate doc; + KTextEditor::ViewPrivate view(&doc, nullptr); + KateViewConfig config(&view); + doc.setText(textBefore); + view.setCursorPosition(cursorBefore); + QCOMPARE(view.cursorPosition(), cursorBefore); + + KateSearchBar bar(true, &view, &config); + + bar.setSearchMode(KateSearchBar::MODE_ESCAPE_SEQUENCES); + bar.setSearchPattern(QStringLiteral("\\n")); + bar.setReplacementPattern(QStringLiteral(" ")); + + bar.replaceAll(); + + QCOMPARE(doc.text(), textAfter); + QCOMPARE(view.cursorPosition(), cursorAfter); +} + +#include "moc_searchbar_test.cpp" diff --git a/src/search/kateplaintextsearch.cpp b/src/search/kateplaintextsearch.cpp --- a/src/search/kateplaintextsearch.cpp +++ b/src/search/kateplaintextsearch.cpp @@ -86,14 +86,19 @@ if (forMin == j && startCol < inputRange.start().column()) { break; } - if (!hayLine.endsWith(needleLine, m_caseSensitivity)) { + + // NOTE: QString("")::endsWith("") is false in Qt, therefore we need the additional checks. + const bool endsWith = hayLine.endsWith(needleLine, m_caseSensitivity) || (hayLine.isEmpty() && needleLine.isEmpty()); + if (!endsWith) { break; } } else if (k == needleLines.count() - 1) { // last line const int maxRight = (j + k == inputRange.end().line()) ? inputRange.end().column() : hayLine.length(); - if (hayLine.startsWith(needleLine, m_caseSensitivity) && needleLine.length() <= maxRight) { + // NOTE: QString("")::startsWith("") is false in Qt, therefore we need the additional checks. + const bool startsWith = hayLine.startsWith(needleLine, m_caseSensitivity) || (hayLine.isEmpty() && needleLine.isEmpty()); + if (startsWith && needleLine.length() <= maxRight) { return KTextEditor::Range(j, startCol, j + k, needleLine.length()); } } else {