feat: Allow negation of search predicates (#4207)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
closes https://github.com/Chatterino/chatterino2/issues/3998
This commit is contained in:
kornes
2022-12-04 11:34:13 +00:00
committed by GitHub
parent 4fa214a38a
commit b7888749fe
19 changed files with 139 additions and 111 deletions
+15 -33
View File
@@ -302,55 +302,57 @@ std::vector<std::unique_ptr<MessagePredicate>> SearchPopup::parsePredicates(
// It also ignores whitespaces in values when being surrounded by quotation
// marks, to enable inputs like this => regex:"kappa 123"
static QRegularExpression predicateRegex(
R"lit((?:(?<name>\w+):(?<value>".+?"|[^\s]+))|[^\s]+?(?=$|\s))lit");
R"lit((?<negation>[!\-])?(?:(?<name>\w+):(?<value>".+?"|[^\s]+))|[^\s]+?(?=$|\s))lit");
static QRegularExpression trimQuotationMarksRegex(R"(^"|"$)");
QRegularExpressionMatchIterator it = predicateRegex.globalMatch(input);
std::vector<std::unique_ptr<MessagePredicate>> predicates;
QStringList authors;
QStringList channels;
QStringList badges;
QStringList subtiers;
while (it.hasNext())
{
QRegularExpressionMatch match = it.next();
QString name = match.captured("name");
bool isNegated = !match.captured("negation").isEmpty();
QString value = match.captured("value");
value.remove(trimQuotationMarksRegex);
// match predicates
if (name == "from")
{
authors.append(value);
predicates.push_back(
std::make_unique<AuthorPredicate>(value, isNegated));
}
else if (name == "badge")
{
badges.append(value);
predicates.push_back(
std::make_unique<BadgePredicate>(value, isNegated));
}
else if (name == "subtier")
{
subtiers.append(value);
predicates.push_back(
std::make_unique<SubtierPredicate>(value, isNegated));
}
else if (name == "has" && value == "link")
{
predicates.push_back(std::make_unique<LinkPredicate>());
predicates.push_back(std::make_unique<LinkPredicate>(isNegated));
}
else if (name == "in")
{
channels.append(value);
predicates.push_back(
std::make_unique<ChannelPredicate>(value, isNegated));
}
else if (name == "is")
{
predicates.push_back(
std::make_unique<MessageFlagsPredicate>(value));
std::make_unique<MessageFlagsPredicate>(value, isNegated));
}
else if (name == "regex")
{
predicates.push_back(std::make_unique<RegexPredicate>(value));
predicates.push_back(
std::make_unique<RegexPredicate>(value, isNegated));
}
else
{
@@ -359,26 +361,6 @@ std::vector<std::unique_ptr<MessagePredicate>> SearchPopup::parsePredicates(
}
}
if (!authors.empty())
{
predicates.push_back(std::make_unique<AuthorPredicate>(authors));
}
if (!channels.empty())
{
predicates.push_back(std::make_unique<ChannelPredicate>(channels));
}
if (!badges.empty())
{
predicates.push_back(std::make_unique<BadgePredicate>(badges));
}
if (!subtiers.empty())
{
predicates.push_back(std::make_unique<SubtierPredicate>(subtiers));
}
return predicates;
}