diff --git a/src/channel.cpp b/src/channel.cpp
index da7643d62..75afbd0f6 100644
--- a/src/channel.cpp
+++ b/src/channel.cpp
@@ -38,11 +38,11 @@ void Channel::addMessage(std::shared_ptr<Message> message)
 {
     std::shared_ptr<Message> deleted;
 
-    const QString &username = message->username;
+    const QString &username = message->loginName;
 
     if (!username.isEmpty()) {
         // TODO: Add recent chatters display name. This should maybe be a setting
-        this->addRecentChatter(username);
+        this->addRecentChatter(message);
     }
 
     //    if (_loggingChannel.get() != nullptr) {
@@ -56,22 +56,27 @@ void Channel::addMessage(std::shared_ptr<Message> message)
     this->messageAppended(message);
 }
 
-void Channel::addRecentChatter(const QString &username)
+void Channel::addRecentChatter(const std::shared_ptr<messages::Message> &message)
 {
+    assert(!message->loginName.isEmpty());
+
     std::lock_guard<std::mutex> lock(this->recentChattersMutex);
 
-    this->recentChatters.insert(username);
+    this->recentChatters[message->loginName] = {message->displayName, message->localizedName};
 }
 
-std::set<QString> Channel::getUsernamesForCompletions()
+std::vector<Channel::NameOptions> Channel::getUsernamesForCompletions()
 {
-    std::set<QString> usernames;
+    std::vector<NameOptions> names;
 
     this->recentChattersMutex.lock();
-    usernames.insert(this->recentChatters.begin(), this->recentChatters.end());
+    for (const auto &p : this->recentChatters) {
+        names.push_back(p.second);
+    }
+    // usernames.insert(this->recentChatters.begin(), this->recentChatters.end());
     this->recentChattersMutex.unlock();
 
-    return usernames;
+    return names;
 }
 
 bool Channel::canSendMessage() const
diff --git a/src/channel.hpp b/src/channel.hpp
index 685503dbf..193e95ff2 100644
--- a/src/channel.hpp
+++ b/src/channel.hpp
@@ -32,15 +32,21 @@ public:
     messages::LimitedQueueSnapshot<messages::SharedMessage> getMessageSnapshot();
 
     void addMessage(messages::SharedMessage message);
-    void addRecentChatter(const QString &username);
+    void addRecentChatter(const std::shared_ptr<messages::Message> &message);
 
-    std::set<QString> getUsernamesForCompletions();
+    struct NameOptions {
+        QString displayName;
+        QString localizedName;
+    };
+
+    std::vector<NameOptions> getUsernamesForCompletions();
 
     QString name;
     QStringList modList;
 
+    // Key = login name
+    std::map<QString, NameOptions> recentChatters;
     std::mutex recentChattersMutex;
-    std::set<QString> recentChatters;
 
     virtual bool canSendMessage() const;
     virtual void sendMessage(const QString &message);
diff --git a/src/completionmanager.cpp b/src/completionmanager.cpp
index 520cf1d6e..00d1b57d5 100644
--- a/src/completionmanager.cpp
+++ b/src/completionmanager.cpp
@@ -65,9 +65,15 @@ void CompletionModel::refresh()
         return;
     }
     auto usernames = c->getUsernamesForCompletions();
-    for (const auto &username : usernames) {
-        this->addString(username);
-        this->addString('@' + username);
+    for (const auto &name : usernames) {
+        assert(!name.displayName.isEmpty());
+        this->addString(name.displayName);
+        this->addString('@' + name.displayName);
+
+        if (!name.localizedName.isEmpty()) {
+            this->addString(name.localizedName);
+            this->addString('@' + name.localizedName);
+        }
     }
 }
 
diff --git a/src/completionmanager.hpp b/src/completionmanager.hpp
index e35c027be..d2f8eb0bf 100644
--- a/src/completionmanager.hpp
+++ b/src/completionmanager.hpp
@@ -13,18 +13,18 @@ class CompletionModel : public QAbstractListModel
 public:
     CompletionModel(const QString &_channelName);
 
-    virtual int columnCount(const QModelIndex & /*parent*/) const override
+    virtual int columnCount(const QModelIndex &) const override
     {
         return 1;
     }
 
-    virtual QVariant data(const QModelIndex &index, int role) const override
+    virtual QVariant data(const QModelIndex &index, int) const override
     {
         // TODO: Implement more safely
         return QVariant(this->emotes.at(index.row()));
     }
 
-    virtual int rowCount(const QModelIndex &parent) const override
+    virtual int rowCount(const QModelIndex &) const override
     {
         return this->emotes.size();
     }
diff --git a/src/logging/loggingchannel.cpp b/src/logging/loggingchannel.cpp
index d3fe1dd17..4f2e7420c 100644
--- a/src/logging/loggingchannel.cpp
+++ b/src/logging/loggingchannel.cpp
@@ -37,7 +37,7 @@ void Channel::append(std::shared_ptr<messages::Message> message)
     str.append('[');
     str.append(now.toString("HH:mm:ss"));
     str.append("] ");
-    str.append(message->username);
+    str.append(message->loginName);
     str.append(": ");
     str.append(message->getContent());
     str.append('\n');
diff --git a/src/messages/message.cpp b/src/messages/message.cpp
index d0b84f174..bdd136a23 100644
--- a/src/messages/message.cpp
+++ b/src/messages/message.cpp
@@ -36,11 +36,6 @@ int Message::getTimeoutCount() const
     return this->timeoutCount;
 }
 
-const QString &Message::getDisplayName() const
-{
-    return this->displayName;
-}
-
 const QString &Message::getContent() const
 {
     return this->content;
diff --git a/src/messages/message.hpp b/src/messages/message.hpp
index 670ea744a..b6600549d 100644
--- a/src/messages/message.hpp
+++ b/src/messages/message.hpp
@@ -22,14 +22,15 @@ public:
     void setHighlight(bool value);
     const QString &getTimeoutUser() const;
     int getTimeoutCount() const;
-    const QString &getDisplayName() const;
     const QString &getContent() const;
     const std::chrono::time_point<std::chrono::system_clock> &getParseTime() const;
     std::vector<Word> &getWords();
     bool isDisabled() const;
     const QString &getId() const;
 
-    QString username;
+    QString loginName;
+    QString displayName;
+    QString localizedName;
 
     const QString text;
     bool centered = false;
@@ -58,7 +59,6 @@ private:
     bool disabled = false;
     std::chrono::time_point<std::chrono::system_clock> parseTime;
 
-    QString displayName = "";
     QString content;
     QString id = "";
 
diff --git a/src/twitch/twitchmessagebuilder.cpp b/src/twitch/twitchmessagebuilder.cpp
index e028a8713..002d485a4 100644
--- a/src/twitch/twitchmessagebuilder.cpp
+++ b/src/twitch/twitchmessagebuilder.cpp
@@ -288,7 +288,7 @@ void TwitchMessageBuilder::parseUsername()
         this->userName = this->tags.value(QLatin1String("login")).toString();
     }
 
-    this->message->username = this->userName;
+    this->message->loginName = this->userName;
 }
 
 void TwitchMessageBuilder::appendUsername()
@@ -302,8 +302,13 @@ void TwitchMessageBuilder::appendUsername()
 
         if (QString::compare(displayName, this->userName, Qt::CaseInsensitive) == 0) {
             username = displayName;
+
+            this->message->displayName = displayName;
         } else {
             localizedName = displayName;
+
+            this->message->displayName = username;
+            this->message->localizedName = displayName;
         }
     }
 
diff --git a/src/widgets/helper/resizingtextedit.cpp b/src/widgets/helper/resizingtextedit.cpp
index 10a286735..3eaef4082 100644
--- a/src/widgets/helper/resizingtextedit.cpp
+++ b/src/widgets/helper/resizingtextedit.cpp
@@ -89,9 +89,9 @@ void ResizingTextEdit::keyPressEvent(QKeyEvent *event)
 
         auto *completionModel =
             static_cast<chatterino::CompletionModel *>(this->completer->model());
-        completionModel->refresh();
 
         if (!this->nextCompletion) {
+            completionModel->refresh();
             // first selection
             this->completer->setCompletionPrefix(currentCompletionPrefix);
             this->nextCompletion = true;