2015-10-22 21:49:08 +03:00
|
|
|
#include "ranked_match.hh"
|
|
|
|
|
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2015-10-28 00:25:18 +03:00
|
|
|
static bool match_rank(StringView candidate, StringView query)
|
2015-10-22 21:49:08 +03:00
|
|
|
{
|
|
|
|
int rank = 0;
|
|
|
|
auto it = candidate.begin();
|
|
|
|
char prev = 0;
|
|
|
|
for (auto c : query)
|
|
|
|
{
|
|
|
|
if (it == candidate.end())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const bool islow = islower(c);
|
|
|
|
auto eq_c = [islow, c](char ch) { return islow ? tolower(ch) == c : ch == c; };
|
|
|
|
|
|
|
|
if (eq_c(*it)) // improve rank on contiguous
|
|
|
|
++rank;
|
|
|
|
|
|
|
|
while (!eq_c(*it))
|
|
|
|
{
|
|
|
|
prev = *it;
|
|
|
|
if (++it == candidate.end())
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// Improve rank on word boundaries
|
|
|
|
if (prev == 0 or prev == '_' or
|
|
|
|
(islower(prev) and isupper(*it)))
|
|
|
|
rank += 5;
|
|
|
|
|
|
|
|
prev = c;
|
|
|
|
++rank;
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
return rank;
|
|
|
|
}
|
|
|
|
|
2015-10-28 00:25:18 +03:00
|
|
|
RankedMatch::RankedMatch(StringView candidate, StringView query)
|
|
|
|
{
|
|
|
|
if (candidate.empty() or query.empty())
|
|
|
|
{
|
|
|
|
m_candidate = candidate;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_match_rank = match_rank(candidate, query);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RankedMatch::operator<(const RankedMatch& other) const
|
|
|
|
{
|
|
|
|
if (m_match_rank == other.m_match_rank)
|
|
|
|
return std::lexicographical_compare(
|
|
|
|
m_candidate.begin(), m_candidate.end(),
|
|
|
|
other.m_candidate.begin(), other.m_candidate.end(),
|
|
|
|
[](char a, char b) {
|
|
|
|
const bool low_a = islower(a), low_b = islower(b);
|
|
|
|
return low_a == low_b ? a < b : low_a;
|
|
|
|
});
|
|
|
|
|
|
|
|
return m_match_rank < other.m_match_rank;
|
|
|
|
}
|
|
|
|
|
2015-10-22 21:49:08 +03:00
|
|
|
}
|