Make word insert completion work better with unicode char
This commit is contained in:
parent
92c3aa4d31
commit
2bf44b6b49
|
@ -10,6 +10,7 @@
|
||||||
#include "user_interface.hh"
|
#include "user_interface.hh"
|
||||||
#include "window.hh"
|
#include "window.hh"
|
||||||
#include "word_db.hh"
|
#include "word_db.hh"
|
||||||
|
#include "utf8_iterator.hh"
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
|
@ -75,23 +76,24 @@ WordDB& get_word_db(const Buffer& buffer)
|
||||||
template<bool other_buffers>
|
template<bool other_buffers>
|
||||||
InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
|
InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
|
||||||
{
|
{
|
||||||
auto pos = buffer.iterator_at(cursor_pos);
|
using Utf8It = utf8::iterator<BufferIterator>;
|
||||||
if (pos == buffer.begin() or not is_word(*utf8::previous(pos, buffer.begin())))
|
Utf8It pos{buffer.iterator_at(cursor_pos), buffer};
|
||||||
|
if (pos == buffer.begin() or not is_word(*(pos-1)))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
auto end = buffer.iterator_at(cursor_pos);
|
auto end = Utf8It{buffer.iterator_at(cursor_pos), buffer};
|
||||||
auto begin = end-1;
|
auto begin = end-1;
|
||||||
while (begin != buffer.begin() and is_word(*begin))
|
while (begin != buffer.begin() and is_word(*begin))
|
||||||
--begin;
|
--begin;
|
||||||
if (not is_word(*begin))
|
if (not is_word(*begin))
|
||||||
++begin;
|
++begin;
|
||||||
|
|
||||||
String prefix{begin, end};
|
String prefix{begin.base(), end.base()};
|
||||||
|
|
||||||
while (end != buffer.end() and is_word(*end))
|
while (end != buffer.end() and is_word(*end))
|
||||||
++end;
|
++end;
|
||||||
|
|
||||||
String current_word{begin, end};
|
String current_word{begin.base(), end.base()};
|
||||||
|
|
||||||
struct RankedMatchAndBuffer : RankedMatch
|
struct RankedMatchAndBuffer : RankedMatch
|
||||||
{
|
{
|
||||||
|
@ -153,7 +155,7 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
|
||||||
candidates.push_back({m.candidate().str(), "", std::move(menu_entry)});
|
candidates.push_back({m.candidate().str(), "", std::move(menu_entry)});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { begin.coord(), cursor_pos, std::move(candidates), buffer.timestamp() };
|
return { begin.base().coord(), cursor_pos, std::move(candidates), buffer.timestamp() };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool require_slash>
|
template<bool require_slash>
|
||||||
|
|
|
@ -1,55 +1,59 @@
|
||||||
#include "ranked_match.hh"
|
#include "ranked_match.hh"
|
||||||
|
|
||||||
|
#include "utf8_iterator.hh"
|
||||||
#include "unit_tests.hh"
|
#include "unit_tests.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using Utf8It = utf8::iterator<const char*>;
|
||||||
|
|
||||||
static int count_word_boundaries_match(StringView candidate, StringView query)
|
static int count_word_boundaries_match(StringView candidate, StringView query)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
auto it = query.begin();
|
Utf8It qit{query.begin(), query};
|
||||||
char prev = 0;
|
Codepoint prev = 0;
|
||||||
for (auto c : candidate)
|
for (Utf8It it{candidate.begin(), candidate}; it != candidate.end(); ++it)
|
||||||
{
|
{
|
||||||
|
const Codepoint c = *it;
|
||||||
const bool is_word_boundary = prev == 0 or
|
const bool is_word_boundary = prev == 0 or
|
||||||
(ispunct(prev) and is_word(c)) or
|
(!iswalnum(prev) and iswalnum(c)) or
|
||||||
(islower(prev) and isupper(c));
|
(islower(prev) and isupper(c));
|
||||||
prev = c;
|
prev = c;
|
||||||
|
|
||||||
if (not is_word_boundary)
|
if (not is_word_boundary)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char lc = tolower(c);
|
const Codepoint lc = tolower(c);
|
||||||
for (; it != query.end(); ++it)
|
for (; qit != query.end(); ++qit)
|
||||||
{
|
{
|
||||||
const char qc = *it;
|
const Codepoint qc = *qit;
|
||||||
if (qc == (islower(qc) ? lc : c))
|
if (qc == (islower(qc) ? lc : c))
|
||||||
{
|
{
|
||||||
++count;
|
++count;
|
||||||
++it;
|
++qit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (it == query.end())
|
if (qit == query.end())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool smartcase_eq(char query, char candidate)
|
static bool smartcase_eq(Codepoint query, Codepoint candidate)
|
||||||
{
|
{
|
||||||
return query == (islower(query) ? tolower(candidate) : candidate);
|
return query == (islower(query) ? tolower(candidate) : candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool subsequence_match_smart_case(StringView str, StringView subseq)
|
static bool subsequence_match_smart_case(StringView str, StringView subseq)
|
||||||
{
|
{
|
||||||
auto it = str.begin();
|
Utf8It it{str.begin(), str};
|
||||||
for (auto& c : subseq)
|
for (Utf8It subseq_it{subseq.begin(), subseq}; subseq_it != subseq.end(); ++subseq_it)
|
||||||
{
|
{
|
||||||
if (it == str.end())
|
if (it == str.end())
|
||||||
return false;
|
return false;
|
||||||
while (not smartcase_eq(c, *it))
|
while (not smartcase_eq(*subseq_it, *it))
|
||||||
{
|
{
|
||||||
if (++it == str.end())
|
if (++it == str.end())
|
||||||
return false;
|
return false;
|
||||||
|
@ -98,9 +102,9 @@ bool RankedMatch::operator<(const RankedMatch& other) const
|
||||||
return m_first_char_match;
|
return m_first_char_match;
|
||||||
|
|
||||||
return std::lexicographical_compare(
|
return std::lexicographical_compare(
|
||||||
m_candidate.begin(), m_candidate.end(),
|
Utf8It{m_candidate.begin(), m_candidate}, Utf8It{m_candidate.end(), m_candidate},
|
||||||
other.m_candidate.begin(), other.m_candidate.end(),
|
Utf8It{other.m_candidate.begin(), other.m_candidate}, Utf8It{other.m_candidate.end(), other.m_candidate},
|
||||||
[](char a, char b) {
|
[](Codepoint a, Codepoint b) {
|
||||||
const bool low_a = islower(a), low_b = islower(b);
|
const bool low_a = islower(a), low_b = islower(b);
|
||||||
return low_a == low_b ? a < b : low_a;
|
return low_a == low_b ? a < b : low_a;
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
|
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
iterator(Iterator it, const Container& c)
|
iterator(Iterator it, const Container& c)
|
||||||
: m_it{std::move(it)}, m_begin{begin(c)}, m_end{end(c)}
|
: m_it{std::move(it)}, m_begin{std::begin(c)}, m_end{std::end(c)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
iterator& operator++()
|
iterator& operator++()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user