Text rules: auto-capitalization, double-space period, backspace repeat

- TextContext: field purpose/hints and text before the cursor, reported by
  the backend (KWin content_type + surrounding_text)
- TextRules: sentence-start and double-space heuristics, deletion helpers
- KeyRepeater: held backspace repeats, then deletes whole words (Ctrl+BS)
- Controller keeps a best-guess of the text before the cursor so rules work
  instantly and in fields that don't report surrounding text
- No auto-capitalization or smart punctuation in password/URL/email fields

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 14:59:21 +02:00
co-authored by Claude Opus 5.5
parent 2b5edeb365
commit 92c132c66f
22 changed files with 452 additions and 39 deletions
+53
View File
@@ -0,0 +1,53 @@
#include "input/TextRules.h"
#include <QTest>
using namespace Qt::StringLiterals;
class TestTextRules : public QObject
{
Q_OBJECT
private Q_SLOTS:
void startsSentence_data()
{
QTest::addColumn<QString>("text");
QTest::addColumn<bool>("expected");
QTest::newRow("empty") << QString() << true;
QTest::newRow("after period and space") << u"Hi. "_s << true;
QTest::newRow("after question, two spaces") << u"Why? "_s << true;
QTest::newRow("after newline") << u"Hi\n"_s << true;
QTest::newRow("only spaces") << u" "_s << true;
QTest::newRow("period without space") << u"Hi."_s << false;
QTest::newRow("mid sentence") << u"Hi there "_s << false;
QTest::newRow("after comma") << u"Hi, "_s << false;
QTest::newRow("mid word") << u"Hel"_s << false;
}
void startsSentence()
{
QFETCH(QString, text);
QFETCH(bool, expected);
QCOMPARE(TextRules::startsSentence(text), expected);
}
void doubleSpacePeriod()
{
QVERIFY(TextRules::wantsDoubleSpacePeriod(u"word "_s));
QVERIFY(TextRules::wantsDoubleSpacePeriod(u"42 "_s));
QVERIFY(!TextRules::wantsDoubleSpacePeriod(u"word. "_s));
QVERIFY(!TextRules::wantsDoubleSpacePeriod(u"word "_s));
QVERIFY(!TextRules::wantsDoubleSpacePeriod(u" "_s));
}
void deletion()
{
QCOMPARE(TextRules::withoutLastCharacter(u"ab"_s), u"a");
QCOMPARE(TextRules::withoutLastCharacter(u"a👍"_s), u"a");
QCOMPARE(TextRules::withoutLastWord(u"one two "_s), u"one ");
QCOMPARE(TextRules::withoutLastWord(u"one"_s), QString());
}
};
QTEST_GUILESS_MAIN(TestTextRules)
#include "tst_textrules.moc"