diff --git a/autotests/src/kateview_test.h b/autotests/src/kateview_test.h --- a/autotests/src/kateview_test.h +++ b/autotests/src/kateview_test.h @@ -33,18 +33,15 @@ private Q_SLOTS: void testReloadMultipleViews(); void testTabCursorOnReload(); - void testLowerCaseBlockSelection(); - void testCoordinatesToCursor(); void testCursorToCoordinates(); - void testSelection(); + void testDeselectByArrowKeys_data(); + void testDeselectByArrowKeys(); void testKillline(); void testScrollPastEndOfDocument(); - void testFoldFirstLine(); - void testDragAndDrop(); void testGotoMatchingBracket(); }; diff --git a/autotests/src/kateview_test.cpp b/autotests/src/kateview_test.cpp --- a/autotests/src/kateview_test.cpp +++ b/autotests/src/kateview_test.cpp @@ -31,6 +31,8 @@ #include #include +#define testNewRow() (QTest::newRow(QString("line %1").arg(__LINE__).toLatin1().data())) + using namespace KTextEditor; QTEST_MAIN(KateViewTest) @@ -267,6 +269,65 @@ QCOMPARE(view->selectionRange(), Range(1, 1, 2, 1)); } +void KateViewTest::testDeselectByArrowKeys_data() +{ + QTest::addColumn("text"); + + testNewRow() << "foobarhaz"; + testNewRow() << "كلسشمن يتبكسب"; // We all win, translates Google +} + +void KateViewTest::testDeselectByArrowKeys() +{ + QFETCH(QString, text); + + KTextEditor::DocumentPrivate doc; + doc.setText(text); + KTextEditor::ViewPrivate *view = new KTextEditor::ViewPrivate(&doc, nullptr); + KTextEditor::Cursor cur1(0, 3); // Start of bar: foo|barhaz + KTextEditor::Cursor cur2(0, 6); // End of bar: foobar|haz + KTextEditor::Cursor curDelta(0, 1); + Range range(cur1, cur2); // Select "bar" + + // RTL drives me nuts! + KTextEditor::Cursor help; + if (text.isRightToLeft()) { + help = cur1; + cur1 = cur2; + cur2 = help; + } + + view->setSelection(range); + view->setCursorPositionInternal(cur1); + view->cursorLeft(); + QCOMPARE(view->cursorPosition(), cur1); // Be at begin: foo|barhaz + QCOMPARE(view->selection(), false); + + view->setSelection(range); + view->setCursorPositionInternal(cur1); + view->cursorRight(); + QCOMPARE(view->cursorPosition(), cur2); // Be at end: foobar|haz + QCOMPARE(view->selection(), false); + + view->config()->setPersistentSelection(true); + + view->setSelection(range); + view->setCursorPositionInternal(cur1); + view->cursorLeft(); + // RTL drives me nuts! + help = text.isRightToLeft() ? (cur1 + curDelta): (cur1 - curDelta); + QCOMPARE(view->cursorPosition(), help); // Be one left: fo|obarhaz + QCOMPARE(view->selection(), true); + + view->setSelection(range); + view->setCursorPositionInternal(cur1); + view->cursorRight(); + // RTL drives me nuts! + help = text.isRightToLeft() ? (cur1 - curDelta): (cur1 + curDelta); + QCOMPARE(view->cursorPosition(), help); // Be one right: foob|arhaz + QCOMPARE(view->selection(), true); +} + void KateViewTest::testKillline() { KTextEditor::DocumentPrivate doc; diff --git a/src/view/kateview.cpp b/src/view/kateview.cpp --- a/src/view/kateview.cpp +++ b/src/view/kateview.cpp @@ -2795,70 +2795,92 @@ void KTextEditor::ViewPrivate::cursorLeft() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { - m_viewInternal->cursorNextChar(); + if (selection() && !config()->persistentSelection()) { + if (currentTextLine().isRightToLeft()) { + m_viewInternal->updateCursor(selectionRange().end()); + setSelection(KTextEditor::Range::invalid()); + } else { + m_viewInternal->updateCursor(selectionRange().start()); + setSelection(KTextEditor::Range::invalid()); + } + } else { - m_viewInternal->cursorPrevChar(); + if (currentTextLine().isRightToLeft()) { + m_viewInternal->cursorNextChar(); + } else { + m_viewInternal->cursorPrevChar(); + } } } void KTextEditor::ViewPrivate::shiftCursorLeft() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { + if (currentTextLine().isRightToLeft()) { m_viewInternal->cursorNextChar(true); } else { m_viewInternal->cursorPrevChar(true); } } void KTextEditor::ViewPrivate::cursorRight() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { - m_viewInternal->cursorPrevChar(); + if (selection() && !config()->persistentSelection()) { + if (currentTextLine().isRightToLeft()) { + m_viewInternal->updateCursor(selectionRange().start()); + setSelection(KTextEditor::Range::invalid()); + } else { + m_viewInternal->updateCursor(selectionRange().end()); + setSelection(KTextEditor::Range::invalid()); + } + } else { - m_viewInternal->cursorNextChar(); + if (currentTextLine().isRightToLeft()) { + m_viewInternal->cursorPrevChar(); + } else { + m_viewInternal->cursorNextChar(); + } } } void KTextEditor::ViewPrivate::shiftCursorRight() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { + if (currentTextLine().isRightToLeft()) { m_viewInternal->cursorPrevChar(true); } else { m_viewInternal->cursorNextChar(true); } } void KTextEditor::ViewPrivate::wordLeft() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { + if (currentTextLine().isRightToLeft()) { m_viewInternal->wordNext(); } else { m_viewInternal->wordPrev(); } } void KTextEditor::ViewPrivate::shiftWordLeft() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { + if (currentTextLine().isRightToLeft()) { m_viewInternal->wordNext(true); } else { m_viewInternal->wordPrev(true); } } void KTextEditor::ViewPrivate::wordRight() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { + if (currentTextLine().isRightToLeft()) { m_viewInternal->wordPrev(); } else { m_viewInternal->wordNext(); } } void KTextEditor::ViewPrivate::shiftWordRight() { - if (m_viewInternal->m_view->currentTextLine().isRightToLeft()) { + if (currentTextLine().isRightToLeft()) { m_viewInternal->wordPrev(true); } else { m_viewInternal->wordNext(true);