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:
Rasmus Karlsson
2017-08-01 00:10:02 +02:00
parent 62a1148c02
commit ba092aa29b
6 changed files with 69 additions and 11 deletions
+16 -5
View File
@@ -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 + ":");
} }
} }
+2
View File
@@ -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;
}; };
+1
View File
@@ -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);
+2
View File
@@ -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);
+44 -5
View File
@@ -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);
} }
+4 -1
View File
@@ -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: