-void TabCompleter::complete() {
- UiSettings uiSettings;
- nickSuffix = uiSettings.value("CompletionSuffix", QString(": ")).toString();
-
- if(!enabled) {
- buildCompletionList();
- enabled = true;
- }
-
- if (nextCompletion != completionMap.end()) {
- // clear previous completion
- for (int i = 0; i < lastCompletionLength; i++) {
- inputLine->backspace();
+
+void TabCompleter::buildCompletionList()
+{
+ // ensure a safe state in case we return early.
+ _completionMap.clear();
+ _nextCompletion = _completionMap.begin();
+
+ // this is the first time tab is pressed -> build up the completion list and it's iterator
+ QModelIndex currentIndex = Client::bufferModel()->currentIndex();
+ _currentBufferId = currentIndex.data(NetworkModel::BufferIdRole).value<BufferId>();
+ if (!_currentBufferId.isValid())
+ return;
+
+ NetworkId networkId = currentIndex.data(NetworkModel::NetworkIdRole).value<NetworkId>();
+ _currentBufferName = currentIndex.sibling(currentIndex.row(), 0).data().toString();
+
+ _currentNetwork = Client::network(networkId);
+ if (!_currentNetwork)
+ return;
+
+ QString tabAbbrev = _lineEdit->text().left(_lineEdit->cursorPosition()).section(QRegExp("[^#\\w\\d-_\\[\\]{}|`^.\\\\]"), -1, -1);
+ QRegExp regex(QString("^[-_\\[\\]{}|`^.\\\\]*").append(QRegExp::escape(tabAbbrev)), Qt::CaseInsensitive);
+
+ // channel completion - add all channels of the current network to the map
+ if (tabAbbrev.startsWith('#')) {
+ _completionType = ChannelTab;
+ foreach(IrcChannel *ircChannel, _currentNetwork->ircChannels()) {
+ if (regex.indexIn(ircChannel->name()) > -1)
+ _completionMap[ircChannel->name()] = ircChannel->name();
+ }
+ }
+ else {
+ // user completion
+ _completionType = UserTab;
+ switch (static_cast<BufferInfo::Type>(currentIndex.data(NetworkModel::BufferTypeRole).toInt())) {
+ case BufferInfo::ChannelBuffer:
+ { // scope is needed for local var declaration
+ IrcChannel *channel = _currentNetwork->ircChannel(_currentBufferName);
+ if (!channel)
+ return;
+ foreach(IrcUser *ircUser, channel->ircUsers()) {
+ if (regex.indexIn(ircUser->nick()) > -1)
+ _completionMap[ircUser->nick().toLower()] = ircUser->nick();
+ }
+ }
+ break;
+ case BufferInfo::QueryBuffer:
+ if (regex.indexIn(_currentBufferName) > -1)
+ _completionMap[_currentBufferName.toLower()] = _currentBufferName;
+ case BufferInfo::StatusBuffer:
+ if (!_currentNetwork->myNick().isEmpty() && regex.indexIn(_currentNetwork->myNick()) > -1)
+ _completionMap[_currentNetwork->myNick().toLower()] = _currentNetwork->myNick();
+ break;
+ default:
+ return;
+ }