diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-11-24 02:35:38 +0100 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-11-25 19:05:12 +0100 |
commit | 29625ae25307aa6746df90cdecc208adc2c36ccb (patch) | |
tree | 41da3ba69577ab9b8a83acb4da66ef235dd2c562 /src/CompletionProxyModel.h | |
parent | Fix mimetype of media messages (diff) | |
download | nheko-29625ae25307aa6746df90cdecc208adc2c36ccb.tar.xz |
Fix some issues with completer
Diffstat (limited to '')
-rw-r--r-- | src/CompletionProxyModel.h | 89 |
1 files changed, 77 insertions, 12 deletions
diff --git a/src/CompletionProxyModel.h b/src/CompletionProxyModel.h index fa22c61e..ba28e84c 100644 --- a/src/CompletionProxyModel.h +++ b/src/CompletionProxyModel.h @@ -43,29 +43,94 @@ struct trie return ret; else { auto temp = t.valuesAndSubvalues(limit - ret.size()); - ret.insert(ret.end(), temp.begin(), temp.end()); + for (auto &&v : temp) { + if (ret.size() >= limit) + return ret; + + if (std::find(ret.begin(), ret.end(), v) == ret.end()) { + ret.push_back(std::move(v)); + } + } } } return ret; } - std::vector<Value> search(const QVector<Key> &keys, size_t limit) const + std::vector<Value> search(const QVector<Key> &keys, + size_t limit, + size_t max_distance = 2) const { std::vector<Value> ret; - auto t = this; - int i = 0; - for (; i < (int)keys.size(); i++) { - if (auto e = t->next.find(keys[i]); e != t->next.end()) { - t = &e->second; - } else { - t = nullptr; - break; + if (!limit) + return ret; + + auto append = [&ret, limit](std::vector<Value> &&in) { + for (auto &&v : in) { + if (ret.size() >= limit) + return; + + if (std::find(ret.begin(), ret.end(), v) == ret.end()) { + ret.push_back(std::move(v)); + } + } + }; + + { + auto t = this; + int i = 0; + for (; i < (int)keys.size(); i++) { + if (auto e = t->next.find(keys[i]); e != t->next.end()) { + t = &e->second; + } else { + t = nullptr; + break; + } + } + + if (t) { + ret = t->valuesAndSubvalues(limit); } } - if (t) { - ret = t->valuesAndSubvalues(limit); + if (max_distance && keys.size() < static_cast<int>(limit) && keys.size() > 1) { + max_distance -= 1; + + // swap chars case + if (keys.size() >= 2) { + auto t = this; + for (int i = 1; i >= 0; i--) { + if (auto e = t->next.find(keys[i]); e != t->next.end()) { + t = &e->second; + } else { + t = nullptr; + break; + } + } + + if (t) { + append(t->search( + keys.mid(2), (limit - ret.size()) * 2, max_distance)); + } + } + + // delete character case + append(this->search(keys.mid(1), (limit - ret.size()) * 2, max_distance)); + + // substitute and insert cases + for (const auto &[k, t] : this->next) { + if (k == keys[0] || ret.size() >= limit) + break; + + // substitute + append(this->search(keys.mid(1), limit - ret.size(), max_distance)); + + if (ret.size() >= limit) + break; + + // insert + append(this->search(keys, limit - ret.size(), max_distance)); + } } return ret; |