Fix performance of word completion with many different selections
Fixes #1228
This commit is contained in:
parent
5eef2b9105
commit
fe2d0fab71
|
@ -143,6 +143,7 @@ public:
|
|||
size_t current_history_id() const noexcept;
|
||||
|
||||
String string(BufferCoord begin, BufferCoord end) const;
|
||||
StringView substr(BufferCoord begin, BufferCoord end) const;
|
||||
|
||||
const char& byte_at(BufferCoord c) const;
|
||||
ByteCount distance(BufferCoord begin, BufferCoord end) const;
|
||||
|
|
|
@ -89,6 +89,12 @@ inline size_t Buffer::timestamp() const
|
|||
return m_changes.size();
|
||||
}
|
||||
|
||||
inline StringView Buffer::substr(BufferCoord begin, BufferCoord end) const
|
||||
{
|
||||
kak_assert(begin.line == end.line);
|
||||
return m_lines[begin.line].substr(begin.column, end.column - begin.column);
|
||||
}
|
||||
|
||||
inline ConstArrayView<Buffer::Change> Buffer::changes_since(size_t timestamp) const
|
||||
{
|
||||
if (timestamp < m_changes.size())
|
||||
|
|
|
@ -90,25 +90,24 @@ InsertCompletion complete_word(const SelectionList& sels, const OptionManager& o
|
|||
return {};
|
||||
|
||||
BufferCoord word_begin;
|
||||
String prefix;
|
||||
IdMap<int> sel_word_counts;
|
||||
StringView prefix;
|
||||
UnorderedMap<StringView, int> sel_word_counts;
|
||||
for (int i = 0; i < sels.size(); ++i)
|
||||
{
|
||||
Utf8It end{buffer.iterator_at(sels[i].cursor()), buffer};
|
||||
Utf8It begin = end-1;
|
||||
if (not skip_while_reverse(begin, buffer.begin(),
|
||||
[&](Codepoint c) { return is_word_pred(c); }))
|
||||
if (not skip_while_reverse(begin, buffer.begin(), is_word_pred))
|
||||
++begin;
|
||||
|
||||
if (i == sels.main_index())
|
||||
{
|
||||
word_begin = begin.base().coord();
|
||||
prefix = buffer.string(word_begin, end.base().coord());
|
||||
prefix = buffer.substr(word_begin, end.base().coord());
|
||||
}
|
||||
|
||||
skip_while(end, buffer.end(), [&](Codepoint c) { return is_word_pred(c); });
|
||||
skip_while(end, buffer.end(), is_word_pred);
|
||||
|
||||
auto word = buffer.string(begin.base().coord(), end.base().coord());
|
||||
StringView word = buffer.substr(begin.base().coord(), end.base().coord());
|
||||
++sel_word_counts[word];
|
||||
}
|
||||
|
||||
|
@ -137,8 +136,8 @@ InsertCompletion complete_word(const SelectionList& sels, const OptionManager& o
|
|||
// Remove words that are being edited
|
||||
for (auto& word_count : sel_word_counts)
|
||||
{
|
||||
if (get_word_db(buffer).get_word_occurences(word_count.key) <= word_count.value)
|
||||
unordered_erase(matches, StringView{word_count.key});
|
||||
if (get_word_db(buffer).get_word_occurences(word_count.first) <= word_count.second)
|
||||
unordered_erase(matches, word_count.first);
|
||||
}
|
||||
|
||||
if (other_buffers)
|
||||
|
@ -156,7 +155,7 @@ InsertCompletion complete_word(const SelectionList& sels, const OptionManager& o
|
|||
if (RankedMatch match{word, prefix})
|
||||
matches.emplace_back(match, nullptr);
|
||||
|
||||
unordered_erase(matches, StringView{prefix});
|
||||
unordered_erase(matches, prefix);
|
||||
std::sort(matches.begin(), matches.end());
|
||||
matches.erase(std::unique(matches.begin(), matches.end()), matches.end());
|
||||
|
||||
|
@ -206,7 +205,7 @@ InsertCompletion complete_filename(const SelectionList& sels,
|
|||
if (begin == pos)
|
||||
return {};
|
||||
|
||||
auto prefix = buffer.string(begin.coord(), pos.coord());
|
||||
StringView prefix = buffer.substr(begin.coord(), pos.coord());
|
||||
if (require_slash and not contains(prefix, '/'))
|
||||
return {};
|
||||
|
||||
|
@ -273,8 +272,7 @@ InsertCompletion complete_option(const SelectionList& sels,
|
|||
|
||||
if (cursor_pos.line == coord.line and cursor_pos.column >= coord.column)
|
||||
{
|
||||
StringView query = buffer[coord.line].substr(
|
||||
coord.column, cursor_pos.column - coord.column);
|
||||
StringView query = buffer.substr(coord, cursor_pos);
|
||||
|
||||
const ColumnCount tabstop = options["tabstop"].get<int>();
|
||||
const ColumnCount column = get_column(buffer, tabstop, cursor_pos);
|
||||
|
|
13
src/main.cc
13
src/main.cc
|
@ -237,6 +237,12 @@ static void check_timeout(const int& timeout)
|
|||
throw runtime_error{"the minimum acceptable timeout is 50 milliseconds"};
|
||||
}
|
||||
|
||||
static void check_extra_word_char(const String& extra_chars)
|
||||
{
|
||||
if (contains_that(extra_chars, is_blank))
|
||||
throw runtime_error{"blanks are not accepted for extra completion characters"};
|
||||
}
|
||||
|
||||
void register_options()
|
||||
{
|
||||
OptionsRegistry& reg = GlobalScope::instance().option_registry();
|
||||
|
@ -303,9 +309,10 @@ void register_options()
|
|||
"%val{bufname} %val{cursor_line}:%val{cursor_char_column} "_str);
|
||||
reg.declare_option("debug", "various debug flags", DebugFlags::None);
|
||||
reg.declare_option("readonly", "prevent buffers from being modified", false);
|
||||
reg.declare_option("completion_extra_word_char",
|
||||
"Additional characters to be considered as words for insert completion",
|
||||
""_str);
|
||||
reg.declare_option<String, check_extra_word_char>(
|
||||
"completion_extra_word_char",
|
||||
"Additional characters to be considered as words for insert completion",
|
||||
""_str);
|
||||
}
|
||||
|
||||
static Client* local_client = nullptr;
|
||||
|
|
Loading…
Reference in New Issue
Block a user