summary refs log tree commit diff
path: root/src/CompletionProxyModel.h
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-09-18 00:22:33 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2021-09-18 00:45:50 +0200
commitcfca7157b98c9dc8e0852fe6484bc3f75008af7d (patch)
tree32b92340908a9374214ec7b84c1fac7ea338f56d /src/CompletionProxyModel.h
parentMerge pull request #728 from Thulinma/goto (diff)
downloadnheko-cfca7157b98c9dc8e0852fe6484bc3f75008af7d.tar.xz
Change indentation to 4 spaces
Diffstat (limited to 'src/CompletionProxyModel.h')
-rw-r--r--src/CompletionProxyModel.h283
1 files changed, 140 insertions, 143 deletions
diff --git a/src/CompletionProxyModel.h b/src/CompletionProxyModel.h

index d85d9343..c6331a2d 100644 --- a/src/CompletionProxyModel.h +++ b/src/CompletionProxyModel.h
@@ -11,179 +11,176 @@ template<typename Key, typename Value> struct trie { - std::vector<Value> values; - std::map<Key, trie> next; - - void insert(const QVector<Key> &keys, const Value &v) - { - auto t = this; - for (const auto k : keys) { - t = &t->next[k]; - } - - t->values.push_back(v); + std::vector<Value> values; + std::map<Key, trie> next; + + void insert(const QVector<Key> &keys, const Value &v) + { + auto t = this; + for (const auto k : keys) { + t = &t->next[k]; } - std::vector<Value> valuesAndSubvalues(size_t limit = -1) const - { - std::vector<Value> ret; - if (limit < 200) - ret.reserve(limit); - - for (const auto &v : values) { - if (ret.size() >= limit) - return ret; - else - ret.push_back(v); - } + t->values.push_back(v); + } - for (const auto &[k, t] : next) { - (void)k; - if (ret.size() >= limit) - return ret; - else { - auto temp = t.valuesAndSubvalues(limit - ret.size()); - 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)); - } - } - } - } + std::vector<Value> valuesAndSubvalues(size_t limit = -1) const + { + std::vector<Value> ret; + if (limit < 200) + ret.reserve(limit); + for (const auto &v : values) { + if (ret.size() >= limit) return ret; + else + ret.push_back(v); } - std::vector<Value> search(const QVector<Key> &keys, //< TODO(Nico): replace this with a span - size_t result_count_limit, - size_t max_edit_distance_ = 2) const - { - std::vector<Value> ret; - if (!result_count_limit) + for (const auto &[k, t] : next) { + (void)k; + if (ret.size() >= limit) + return ret; + else { + auto temp = t.valuesAndSubvalues(limit - ret.size()); + for (auto &&v : temp) { + if (ret.size() >= limit) return ret; - if (keys.isEmpty()) - return valuesAndSubvalues(result_count_limit); + if (std::find(ret.begin(), ret.end(), v) == ret.end()) { + ret.push_back(std::move(v)); + } + } + } + } - auto append = [&ret, result_count_limit](std::vector<Value> &&in) { - for (auto &&v : in) { - if (ret.size() >= result_count_limit) - return; + return ret; + } - if (std::find(ret.begin(), ret.end(), v) == ret.end()) { - ret.push_back(std::move(v)); - } - } - }; - - auto limit = [&ret, result_count_limit] { - return std::min(result_count_limit, (result_count_limit - ret.size()) * 2); - }; - - // Try first exact matches, then with maximum errors - for (size_t max_edit_distance = 0; - max_edit_distance <= max_edit_distance_ && ret.size() < result_count_limit; - max_edit_distance += 1) { - if (max_edit_distance && ret.size() < result_count_limit) { - max_edit_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(), max_edit_distance)); - } - } - - // insert case - for (const auto &[k, t] : this->next) { - if (k == keys[0]) - continue; - if (ret.size() >= limit()) - break; - - // insert - append(t.search(keys, limit(), max_edit_distance)); - } - - // delete character case - append(this->search(keys.mid(1), limit(), max_edit_distance)); - - // substitute case - for (const auto &[k, t] : this->next) { - if (k == keys[0]) - continue; - if (ret.size() >= limit()) - break; - - // substitute - append(t.search(keys.mid(1), limit(), max_edit_distance)); - } - - max_edit_distance += 1; - } + std::vector<Value> search(const QVector<Key> &keys, //< TODO(Nico): replace this with a span + size_t result_count_limit, + size_t max_edit_distance_ = 2) const + { + std::vector<Value> ret; + if (!result_count_limit) + return ret; + + if (keys.isEmpty()) + return valuesAndSubvalues(result_count_limit); + + auto append = [&ret, result_count_limit](std::vector<Value> &&in) { + for (auto &&v : in) { + if (ret.size() >= result_count_limit) + return; - if (auto e = this->next.find(keys[0]); e != this->next.end()) { - append(e->second.search(keys.mid(1), limit(), max_edit_distance)); + if (std::find(ret.begin(), ret.end(), v) == ret.end()) { + ret.push_back(std::move(v)); + } + } + }; + + auto limit = [&ret, result_count_limit] { + return std::min(result_count_limit, (result_count_limit - ret.size()) * 2); + }; + + // Try first exact matches, then with maximum errors + for (size_t max_edit_distance = 0; + max_edit_distance <= max_edit_distance_ && ret.size() < result_count_limit; + max_edit_distance += 1) { + if (max_edit_distance && ret.size() < result_count_limit) { + max_edit_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(), max_edit_distance)); + } } - return ret; + // insert case + for (const auto &[k, t] : this->next) { + if (k == keys[0]) + continue; + if (ret.size() >= limit()) + break; + + // insert + append(t.search(keys, limit(), max_edit_distance)); + } + + // delete character case + append(this->search(keys.mid(1), limit(), max_edit_distance)); + + // substitute case + for (const auto &[k, t] : this->next) { + if (k == keys[0]) + continue; + if (ret.size() >= limit()) + break; + + // substitute + append(t.search(keys.mid(1), limit(), max_edit_distance)); + } + + max_edit_distance += 1; + } + + if (auto e = this->next.find(keys[0]); e != this->next.end()) { + append(e->second.search(keys.mid(1), limit(), max_edit_distance)); + } } + + return ret; + } }; class CompletionProxyModel : public QAbstractProxyModel { - Q_OBJECT - Q_PROPERTY( - QString searchString READ searchString WRITE setSearchString NOTIFY newSearchString) + Q_OBJECT + Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY newSearchString) public: - CompletionProxyModel(QAbstractItemModel *model, - int max_mistakes = 2, - size_t max_completions = 7, - QObject *parent = nullptr); + CompletionProxyModel(QAbstractItemModel *model, + int max_mistakes = 2, + size_t max_completions = 7, + QObject *parent = nullptr); - void invalidate(); + void invalidate(); - QHash<int, QByteArray> roleNames() const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &) const override; + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &) const override; - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; + QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; + QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; - QModelIndex index(int row, - int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &) const override; + QModelIndex index(int row, + int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &) const override; public slots: - QVariant completionAt(int i) const; + QVariant completionAt(int i) const; - void setSearchString(QString s); - QString searchString() const { return searchString_; } + void setSearchString(QString s); + QString searchString() const { return searchString_; } signals: - void newSearchString(QString); + void newSearchString(QString); private: - QString searchString_; - trie<uint, int> trie_; - std::vector<int> mapping; - int maxMistakes_; - size_t max_completions_; + QString searchString_; + trie<uint, int> trie_; + std::vector<int> mapping; + int maxMistakes_; + size_t max_completions_; };