Commit 3b03ce93 authored by Waqar Ahmed's avatar Waqar Ahmed
Browse files

Tweak fuzzy matcher to score sequential matches a bit higher for kate command bar

Currently if you search for "Sort", the result for "sort" is 2nd or
third and not the first because Camel Case / separator matches have a
higher score. To fix this sequential score is raised a bit as a special
case for Kate command bar by introducing a new
`fuzzy_match_sequential()` function.
parent d78e7257
......@@ -56,7 +56,7 @@ protected:
int score = 0;
const auto idx = sourceModel()->index(sourceRow, 0, sourceParent);
const auto actionName = idx.data().toString().splitRef(QLatin1Char(':')).at(1);
const bool res = kfts::fuzzy_match(m_pattern, actionName, score);
const bool res = kfts::fuzzy_match_sequential(m_pattern, actionName, score);
sourceModel()->setData(idx, score, CommandModel::Score);
return res;
}
......
......@@ -32,6 +32,11 @@ Q_DECL_UNUSED static bool fuzzy_match_simple(const QStringView pattern, const QS
Q_DECL_UNUSED static bool fuzzy_match(const QStringView pattern, const QStringView str, int &outScore);
Q_DECL_UNUSED static bool fuzzy_match(const QStringView pattern, const QStringView str, int &outScore, uint8_t *matches, int maxMatches);
/**
* @brief This is a special case function which doesn't score separator matches higher than sequential matches.
* This is currently used in Kate's command bar where the string items are usually space separated names.
*/
Q_DECL_UNUSED static bool fuzzy_match_sequential(const QStringView pattern, const QStringView str, int &outScore);
/**
* @brief get string for display in treeview / listview. This should be used from style delegate.
* For example: with @a pattern = "kate", @a str = "kateapp" and @htmlTag = "<b>
......@@ -59,7 +64,8 @@ static bool fuzzy_match_recursive(QStringView::const_iterator pattern,
uint8_t *newMatches,
int maxMatches,
int nextMatch,
int &recursionCount);
int &recursionCount,
int seqBonus = 15);
}
// Public interface
......@@ -91,6 +97,19 @@ static bool fuzzy_match(const QStringView pattern, const QStringView str, int &o
return fuzzy_internal::fuzzy_match_recursive(patternIt, strIt, outScore, strIt, strEnd, patternEnd, nullptr, matches, maxMatches, 0, recursionCount);
}
static bool fuzzy_match_sequential(const QStringView pattern, const QStringView str, int &outScore)
{
int recursionCount = 0;
uint8_t matches[256];
auto maxMatches = sizeof(matches);
auto strIt = str.cbegin();
auto patternIt = pattern.cbegin();
const auto patternEnd = pattern.cend();
const auto strEnd = str.cend();
return fuzzy_internal::fuzzy_match_recursive(patternIt, strIt, outScore, strIt, strEnd, patternEnd, nullptr, matches, maxMatches, 0, recursionCount, 40);
}
// Private implementation
static bool fuzzy_internal::fuzzy_match_recursive(QStringView::const_iterator pattern,
QStringView::const_iterator str,
......@@ -102,7 +121,8 @@ static bool fuzzy_internal::fuzzy_match_recursive(QStringView::const_iterator pa
uint8_t *matches,
int maxMatches,
int nextMatch,
int &recursionCount)
int &recursionCount,
int seqBonus)
{
// Count recursions
static constexpr int recursionLimit = 10;
......@@ -159,7 +179,7 @@ static bool fuzzy_internal::fuzzy_match_recursive(QStringView::const_iterator pa
// Calculate score
if (matched) {
static constexpr int sequential_bonus = 15; // bonus for adjacent matches
int sequential_bonus = seqBonus; // bonus for adjacent matches
static constexpr int separator_bonus = 30; // bonus if match occurs after a separator
static constexpr int camel_bonus = 30; // bonus if match is uppercase and prev is lower
static constexpr int first_letter_bonus = 15; // bonus if the first letter is matched
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment