chore: add tests for input highlighting (#6779)
Reviewed-by: Arne <78976058+4rneee@users.noreply.github.com> Reviewed-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
@@ -69,12 +69,24 @@ bool isIgnoredWord(TwitchChannel *twitch, const QString &word)
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
namespace inputhighlight::detail {
|
||||
|
||||
// FIXME: this also matches URLs - this probably needs to be some function like Firefox' mozEnglishWordUtils::FindNextWord
|
||||
QRegularExpression wordRegex()
|
||||
{
|
||||
static QRegularExpression regex{
|
||||
R"(\p{L}(?:\P{Z}+\p{L}+)*)",
|
||||
QRegularExpression::PatternOption::UseUnicodePropertiesOption,
|
||||
};
|
||||
return regex;
|
||||
}
|
||||
|
||||
} // namespace inputhighlight::detail
|
||||
|
||||
InputHighlighter::InputHighlighter(SpellChecker &spellChecker, QObject *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
, spellChecker(spellChecker)
|
||||
// FIXME: this also matches URLs - this probably needs to be some function like Firefox' mozEnglishWordUtils::FindNextWord
|
||||
, wordRegex(R"(\p{L}(?:\P{Z}+\p{L}+)*)",
|
||||
QRegularExpression::PatternOption::UseUnicodePropertiesOption)
|
||||
, wordRegex(inputhighlight::detail::wordRegex())
|
||||
{
|
||||
this->spellFmt.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
|
||||
this->spellFmt.setUnderlineColor(Qt::red);
|
||||
@@ -88,12 +100,36 @@ void InputHighlighter::setChannel(const std::shared_ptr<Channel> &channel)
|
||||
this->rehighlight();
|
||||
}
|
||||
|
||||
std::vector<QString> InputHighlighter::getSpellCheckedWords(const QString &text)
|
||||
{
|
||||
std::vector<QString> words;
|
||||
this->visitWords(text, [&](const QString &word, qsizetype /*start*/,
|
||||
qsizetype /*count*/) {
|
||||
words.emplace_back(word);
|
||||
});
|
||||
return words;
|
||||
}
|
||||
|
||||
void InputHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
if (!this->spellChecker.isLoaded())
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->visitWords(
|
||||
text, [&](const QString &word, qsizetype start, qsizetype count) {
|
||||
if (!this->spellChecker.check(word))
|
||||
{
|
||||
this->setFormat(static_cast<int>(start),
|
||||
static_cast<int>(count), this->spellFmt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void InputHighlighter::visitWords(
|
||||
const QString &text,
|
||||
std::invocable<const QString &, qsizetype, qsizetype> auto &&cb)
|
||||
{
|
||||
auto *channel = this->channel.lock().get();
|
||||
|
||||
QStringView textView = text;
|
||||
@@ -112,11 +148,10 @@ void InputHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
auto match = it.next();
|
||||
auto text = match.captured();
|
||||
if (!isIgnoredWord(channel, text) && !this->spellChecker.check(text))
|
||||
if (!isIgnoredWord(channel, text))
|
||||
{
|
||||
this->setFormat(
|
||||
static_cast<int>(match.capturedStart() + cmdTriggerLen),
|
||||
static_cast<int>(text.size()), this->spellFmt);
|
||||
cb(text, static_cast<int>(match.capturedStart() + cmdTriggerLen),
|
||||
static_cast<int>(text.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <QString>
|
||||
#include <QSyntaxHighlighter>
|
||||
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
|
||||
class QTextDocument;
|
||||
@@ -18,6 +19,12 @@ class Channel;
|
||||
class TwitchChannel;
|
||||
class SpellChecker;
|
||||
|
||||
namespace inputhighlight::detail {
|
||||
|
||||
QRegularExpression wordRegex();
|
||||
|
||||
} // namespace inputhighlight::detail
|
||||
|
||||
/// This highlights the text in the split input.
|
||||
/// Currently, it only does spell checking.
|
||||
class InputHighlighter : public QSyntaxHighlighter
|
||||
@@ -32,10 +39,20 @@ public:
|
||||
|
||||
void setChannel(const std::shared_ptr<Channel> &channel);
|
||||
|
||||
/// Do a pass over the whole text and filter out all words that will be
|
||||
/// checked by the spell checker.
|
||||
std::vector<QString> getSpellCheckedWords(const QString &text);
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString &text) override;
|
||||
|
||||
private:
|
||||
/// Visit all words that are not ignored
|
||||
void visitWords(
|
||||
const QString &text,
|
||||
std::invocable</*word=*/const QString &, /*start=*/qsizetype,
|
||||
/*count=*/qsizetype> auto &&cb);
|
||||
|
||||
SpellChecker &spellChecker;
|
||||
QTextCharFormat spellFmt;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user