From 58d892a8c2507f624893adab32571257a56c455f Mon Sep 17 00:00:00 2001 From: Leon Richardt Date: Sat, 17 Aug 2019 17:17:38 +0200 Subject: [PATCH] Make Emote Tab Completion Search for Substrings (#1204) * Make emote tab completion search for substrings Previously, tab completion only searched for emotes that start with the current prefix under the cursor. This commit makes tab completion look for the current prefix as a substring in any position, not just the start. Examples: * In forsen's channel, tabbing on "pls" will cycle through "DonaldPls", "forsenPls", "GachiPls", "nyanPls" and "SourPls". * As a forsen subscriber, tabbing on "sen1" will complete to "forsen1". * As a pajlada subscriber, tabbing on "shrug" will cycle through "pajaShrugL" and "pajaShrugR". (Unless you are in a channel with more "shrug" emotes, of course.) * Add a setting for prefix and substring completion This commit adds a setting under the "Miscellaneous" section to allow user to choose whether they want prefix-only or substring emote completion. The QCompleter filter mode and `addString` function are now chosen according to the user's setting. * Improve description of emote completion setting Also reintroduce a blank line that went missing. --- src/common/CompletionModel.cpp | 22 +++++++++++++++++----- src/singletons/Settings.hpp | 1 + src/widgets/helper/ResizingTextEdit.cpp | 11 +++++++++++ src/widgets/settingspages/GeneralPage.cpp | 2 ++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/common/CompletionModel.cpp b/src/common/CompletionModel.cpp index 5f9dfff0..7d9251bc 100644 --- a/src/common/CompletionModel.cpp +++ b/src/common/CompletionModel.cpp @@ -10,6 +10,7 @@ #include "providers/twitch/TwitchChannel.hpp" #include "providers/twitch/TwitchServer.hpp" #include "singletons/Emotes.hpp" +#include "singletons/Settings.hpp" #include #include @@ -78,17 +79,28 @@ int CompletionModel::rowCount(const QModelIndex &) const void CompletionModel::refresh(const QString &prefix) { + std::function addString; + if (getSettings()->prefixOnlyEmoteCompletion) + { + addString = [&](const QString &str, TaggedString::Type type) { + if (str.startsWith(prefix, Qt::CaseInsensitive)) + this->items_.emplace(str + " ", type); + }; + } + else + { + addString = [&](const QString &str, TaggedString::Type type) { + if (str.contains(prefix, Qt::CaseInsensitive)) + this->items_.emplace(str + " ", type); + }; + } + std::lock_guard guard(this->itemsMutex_); this->items_.clear(); if (prefix.length() < 2) return; - auto addString = [&](const QString &str, TaggedString::Type type) { - if (str.startsWith(prefix, Qt::CaseInsensitive)) - this->items_.emplace(str + " ", type); - }; - if (auto channel = dynamic_cast(&this->channel_)) { // account emotes diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index 7dae9327..e771ee90 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -99,6 +99,7 @@ public: "/behaviour/autocompletion/onlyFetchChattersForSmallerStreamers", true}; IntSetting smallStreamerLimit = { "/behaviour/autocompletion/smallStreamerLimit", 1000}; + BoolSetting prefixOnlyEmoteCompletion = {"/behaviour/autocompletion/prefixOnlyCompletion", true}; BoolSetting pauseChatOnHover = {"/behaviour/pauseChatHover", false}; BoolSetting autorun = {"/behaviour/autorun", false}; diff --git a/src/widgets/helper/ResizingTextEdit.cpp b/src/widgets/helper/ResizingTextEdit.cpp index 2df772d0..92b5b8ef 100644 --- a/src/widgets/helper/ResizingTextEdit.cpp +++ b/src/widgets/helper/ResizingTextEdit.cpp @@ -1,6 +1,7 @@ #include "widgets/helper/ResizingTextEdit.hpp" #include "common/Common.hpp" #include "common/CompletionModel.hpp" +#include "singletons/Settings.hpp" namespace chatterino { @@ -198,6 +199,16 @@ void ResizingTextEdit::setCompleter(QCompleter *c) this->completer_->setWidget(this); this->completer_->setCompletionMode(QCompleter::InlineCompletion); this->completer_->setCaseSensitivity(Qt::CaseInsensitive); + + if (getSettings()->prefixOnlyEmoteCompletion) + { + this->completer_->setFilterMode(Qt::MatchStartsWith); + } + else + { + this->completer_->setFilterMode(Qt::MatchContains); + } + QObject::connect(completer_, static_cast( &QCompleter::highlighted), diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index 7b5f5e48..aec81113 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -283,6 +283,8 @@ void GeneralPage::initLayout(SettingsLayout &layout) {"Don't show", "Always show", "Hold shift"}, s.emotesTooltipPreview, [](int index) { return index; }, [](auto args) { return args.index; }, false); + layout.addCheckbox("Only search for emote autocompletion at the start of emote names", + s.prefixOnlyEmoteCompletion); layout.addSpacing(16); layout.addSeperator();