diff --git a/kdevplatform/language/interfaces/abbreviations.h b/kdevplatform/language/interfaces/abbreviations.h --- a/kdevplatform/language/interfaces/abbreviations.h +++ b/kdevplatform/language/interfaces/abbreviations.h @@ -47,17 +47,11 @@ */ KDEVPLATFORMLANGUAGE_EXPORT bool matchesAbbreviationMulti(const QString& word, const QStringList& typedFragments); -enum class PathFilterMatchQuality -{ - NoMatch, - ExactMatch, - StartMatch, - OtherMatch -}; /** * @brief Matches a path against a list of search fragments. + * @return -1 when no match is found, otherwise a positive integer, higher values mean lower quality */ -KDEVPLATFORMLANGUAGE_EXPORT PathFilterMatchQuality matchPathFilter(const Path& toFilter, const QStringList& text); +KDEVPLATFORMLANGUAGE_EXPORT int matchPathFilter(const Path& toFilter, const QStringList& text); } #endif diff --git a/kdevplatform/language/interfaces/abbreviations.cpp b/kdevplatform/language/interfaces/abbreviations.cpp --- a/kdevplatform/language/interfaces/abbreviations.cpp +++ b/kdevplatform/language/interfaces/abbreviations.cpp @@ -158,13 +158,19 @@ return matchedFragments == typedFragments.size(); } -PathFilterMatchQuality matchPathFilter(const Path &toFilter, const QStringList &text) +int matchPathFilter(const Path &toFilter, const QStringList &text) { + enum PathFilterMatchQuality { + NoMatch = -1, + ExactMatch = 0, + StartMatch = 1, + OtherMatch = 2 // and anything higher than that + }; const QVector& segments = toFilter.segments(); if (text.count() > segments.count()) { // number of segments mismatches, thus item cannot match - return PathFilterMatchQuality::NoMatch; + return NoMatch; } { bool allMatched = true; @@ -178,7 +184,7 @@ } } if (allMatched) { - return PathFilterMatchQuality::ExactMatch; + return ExactMatch; } } @@ -211,14 +217,14 @@ } if (searchIndex != text.size()) { - return PathFilterMatchQuality::NoMatch; + return NoMatch; } // prefer matches whose last element starts with the filter if (pathIndex == segments.size() && lastMatchIndex == 0) { - return PathFilterMatchQuality::StartMatch; + return StartMatch; } else { - return PathFilterMatchQuality::OtherMatch; + return OtherMatch; } } diff --git a/kdevplatform/language/interfaces/quickopenfilter.h b/kdevplatform/language/interfaces/quickopenfilter.h --- a/kdevplatform/language/interfaces/quickopenfilter.h +++ b/kdevplatform/language/interfaces/quickopenfilter.h @@ -194,31 +194,25 @@ filterBase = m_items; } - // filterBase is correctly sorted, to keep it that way we add - // exact matches to this list in sorted way and then prepend the whole list in one go. - QVector exactMatches; - // similar for starting matches - QVector startMatches; - // all other matches are sorted by where they match, we prefer matches at the end - QVector otherMatches; - foreach( const Item& data, filterBase ) { + QVector> matches; + for (int i = 0, c = filterBase.size(); i < c; ++i) { + const auto& data = filterBase.at(i); const auto matchQuality = matchPathFilter(static_cast(this)->itemPath(data), text); - switch (matchQuality) { - case PathFilterMatchQuality::NoMatch: - break; - case PathFilterMatchQuality::ExactMatch: - exactMatches << data; - break; - case PathFilterMatchQuality::StartMatch: - startMatches << data; - break; - case PathFilterMatchQuality::OtherMatch: - otherMatches << data; - break; + if (matchQuality == -1) { + continue; } + matches.push_back({matchQuality, i}); } - - m_filtered = exactMatches + startMatches + otherMatches; + std::sort(matches.begin(), matches.end(), + [](const QPair& lhs, const QPair& rhs) + { + return lhs.first < rhs.first; + }); + m_filtered.resize(matches.size()); + std::transform(matches.begin(), matches.end(), m_filtered.begin(), + [&filterBase](const QPair& match) { + return filterBase.at(match.second); + }); m_oldFilterText = text; }