Add emojis to autocomplete
Improve autocomplete: - Add space after autocompleted item - Emotes starting with `:` can now be autocompleted properly (i.e. emojis)
This commit is contained in:
@@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
void CompletionModel::addString(const std::string &str)
|
||||||
|
{
|
||||||
|
// Always add a space at the end of completions
|
||||||
|
this->emotes.push_back(qS(str) + " ");
|
||||||
|
}
|
||||||
|
|
||||||
CompletionManager::CompletionManager(EmoteManager &_emoteManager)
|
CompletionManager::CompletionManager(EmoteManager &_emoteManager)
|
||||||
: emoteManager(_emoteManager)
|
: emoteManager(_emoteManager)
|
||||||
{
|
{
|
||||||
@@ -40,30 +46,35 @@ void CompletionManager::updateModel(CompletionModel *model, const std::string &c
|
|||||||
|
|
||||||
for (const auto &m : this->emoteManager.twitchAccountEmotes) {
|
for (const auto &m : this->emoteManager.twitchAccountEmotes) {
|
||||||
for (const auto &emoteName : m.second.emoteCodes) {
|
for (const auto &emoteName : m.second.emoteCodes) {
|
||||||
model->emotes.push_back(qS(emoteName));
|
model->addString(emoteName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> &bttvGlobalEmoteCodes = this->emoteManager.bttvGlobalEmoteCodes;
|
std::vector<std::string> &bttvGlobalEmoteCodes = this->emoteManager.bttvGlobalEmoteCodes;
|
||||||
for (const auto &m : bttvGlobalEmoteCodes) {
|
for (const auto &m : bttvGlobalEmoteCodes) {
|
||||||
model->emotes.push_back(qS(m));
|
model->addString(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> &ffzGlobalEmoteCodes = this->emoteManager.ffzGlobalEmoteCodes;
|
std::vector<std::string> &ffzGlobalEmoteCodes = this->emoteManager.ffzGlobalEmoteCodes;
|
||||||
for (const auto &m : ffzGlobalEmoteCodes) {
|
for (const auto &m : ffzGlobalEmoteCodes) {
|
||||||
model->emotes.push_back(qS(m));
|
model->addString(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> &bttvChannelEmoteCodes =
|
std::vector<std::string> &bttvChannelEmoteCodes =
|
||||||
this->emoteManager.bttvChannelEmoteCodes[channelName];
|
this->emoteManager.bttvChannelEmoteCodes[channelName];
|
||||||
for (const auto &m : bttvChannelEmoteCodes) {
|
for (const auto &m : bttvChannelEmoteCodes) {
|
||||||
model->emotes.push_back(qS(m));
|
model->addString(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> &ffzChannelEmoteCodes =
|
std::vector<std::string> &ffzChannelEmoteCodes =
|
||||||
this->emoteManager.ffzChannelEmoteCodes[channelName];
|
this->emoteManager.ffzChannelEmoteCodes[channelName];
|
||||||
for (const auto &m : ffzChannelEmoteCodes) {
|
for (const auto &m : ffzChannelEmoteCodes) {
|
||||||
model->emotes.push_back(qS(m));
|
model->addString(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &emojiShortCodes = this->emoteManager.emojiShortCodes;
|
||||||
|
for (const auto &m : emojiShortCodes) {
|
||||||
|
model->addString(":" + m + ":");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public:
|
|||||||
return this->emotes.size();
|
return this->emotes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addString(const std::string &str);
|
||||||
|
|
||||||
QVector<QString> emotes;
|
QVector<QString> emotes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -199,6 +199,7 @@ void EmoteManager::loadEmojis()
|
|||||||
};
|
};
|
||||||
|
|
||||||
this->emojiShortCodeToEmoji.insert(shortCode, emojiData);
|
this->emojiShortCodeToEmoji.insert(shortCode, emojiData);
|
||||||
|
this->emojiShortCodes.push_back(shortCode.toStdString());
|
||||||
|
|
||||||
this->emojiFirstByte[emojiData.value.at(0)].append(emojiData);
|
this->emojiFirstByte[emojiData.value.at(0)].append(emojiData);
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ public:
|
|||||||
|
|
||||||
QString replaceShortCodes(const QString &text);
|
QString replaceShortCodes(const QString &text);
|
||||||
|
|
||||||
|
std::vector<std::string> emojiShortCodes;
|
||||||
|
|
||||||
/// Twitch emotes
|
/// Twitch emotes
|
||||||
void refreshTwitchEmotes(const std::string &roomID);
|
void refreshTwitchEmotes(const std::string &roomID);
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,41 @@ int ResizingTextEdit::heightForWidth(int) const
|
|||||||
return margins.top() + document()->size().height() + margins.bottom() + 5;
|
return margins.top() + document()->size().height() + margins.bottom() + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ResizingTextEdit::textUnderCursor() const
|
QString ResizingTextEdit::textUnderCursor(bool *hadSpace) const
|
||||||
{
|
{
|
||||||
QTextCursor tc = textCursor();
|
auto currentText = this->toPlainText();
|
||||||
tc.select(QTextCursor::WordUnderCursor);
|
|
||||||
return tc.selectedText();
|
QTextCursor tc = this->textCursor();
|
||||||
|
|
||||||
|
auto textUpToCursor = currentText.left(tc.selectionStart());
|
||||||
|
|
||||||
|
auto words = textUpToCursor.splitRef(' ');
|
||||||
|
if (words.size() == 0) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
QString lastWord;
|
||||||
|
for (auto it = words.crbegin(); it != words.crend(); ++it) {
|
||||||
|
auto word = *it;
|
||||||
|
|
||||||
|
if (first && word.isEmpty()) {
|
||||||
|
first = false;
|
||||||
|
if (hadSpace != nullptr) {
|
||||||
|
*hadSpace = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastWord = word.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastWord.isEmpty()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizingTextEdit::keyPressEvent(QKeyEvent *event)
|
void ResizingTextEdit::keyPressEvent(QKeyEvent *event)
|
||||||
@@ -105,8 +135,17 @@ void ResizingTextEdit::insertCompletion(const QString &completion)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hadSpace = false;
|
||||||
|
auto prefix = this->textUnderCursor(&hadSpace);
|
||||||
|
|
||||||
|
int prefixSize = prefix.size();
|
||||||
|
|
||||||
|
if (hadSpace) {
|
||||||
|
++prefixSize;
|
||||||
|
}
|
||||||
|
|
||||||
QTextCursor tc = this->textCursor();
|
QTextCursor tc = this->textCursor();
|
||||||
tc.select(QTextCursor::SelectionType::WordUnderCursor);
|
tc.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, prefixSize);
|
||||||
tc.insertText(completion);
|
tc.insertText(completion);
|
||||||
this->setTextCursor(tc);
|
this->setTextCursor(tc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QCompleter *completer = nullptr;
|
QCompleter *completer = nullptr;
|
||||||
QString textUnderCursor() const;
|
|
||||||
|
// hadSpace is set to true in case the "textUnderCursor" word was after a space
|
||||||
|
QString textUnderCursor(bool *hadSpace = nullptr) const;
|
||||||
|
|
||||||
bool nextCompletion = false;
|
bool nextCompletion = false;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|||||||
Reference in New Issue
Block a user