Refactor how InsetCompletionHide hook parameter is computed
Keep track of inserted ranges instead of trying to re-derive them. Fixes #3556
This commit is contained in:
parent
099b83d922
commit
fc3e5ea419
|
@ -32,7 +32,7 @@ public:
|
||||||
|
|
||||||
template<typename Container,
|
template<typename Container,
|
||||||
typename = std::enable_if_t<sizeof(decltype(*std::declval<Container>().data())) == sizeof(T)>>
|
typename = std::enable_if_t<sizeof(decltype(*std::declval<Container>().data())) == sizeof(T)>>
|
||||||
constexpr ArrayView(const Container& c)
|
constexpr ArrayView(Container&& c)
|
||||||
: m_pointer(c.data()), m_size(c.size()) {}
|
: m_pointer(c.data()), m_size(c.size()) {}
|
||||||
|
|
||||||
constexpr ArrayView(const std::initializer_list<T>& v)
|
constexpr ArrayView(const std::initializer_list<T>& v)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "event_manager.hh"
|
#include "event_manager.hh"
|
||||||
#include "file.hh"
|
#include "file.hh"
|
||||||
#include "selection.hh"
|
#include "selection.hh"
|
||||||
|
#include "changes.hh"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -15,6 +16,25 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void replace(Buffer& buffer, ArrayView<BufferRange> ranges, ConstArrayView<String> strings)
|
||||||
|
{
|
||||||
|
ForwardChangesTracker changes_tracker;
|
||||||
|
size_t timestamp = buffer.timestamp();
|
||||||
|
for (size_t index = 0; index < ranges.size(); ++index)
|
||||||
|
{
|
||||||
|
auto& range = ranges[index];
|
||||||
|
range.begin = changes_tracker.get_new_coord_tolerant(range.begin);
|
||||||
|
range.end = changes_tracker.get_new_coord_tolerant(range.end);
|
||||||
|
kak_assert(buffer.is_valid(range.begin) and buffer.is_valid(range.end));
|
||||||
|
|
||||||
|
range = buffer.replace(range.begin, range.end, strings.empty() ? StringView{} : strings[std::min(index, strings.size()-1)]);
|
||||||
|
kak_assert(buffer.is_valid(range.begin) and buffer.is_valid(range.end));
|
||||||
|
changes_tracker.update(buffer, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.check_invariant();
|
||||||
|
}
|
||||||
|
|
||||||
ColumnCount get_column(const Buffer& buffer,
|
ColumnCount get_column(const Buffer& buffer,
|
||||||
ColumnCount tabstop, BufferCoord coord)
|
ColumnCount tabstop, BufferCoord coord)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,8 @@ inline BufferRange replace(Buffer& buffer, const Selection& range, StringView co
|
||||||
return buffer.replace(range.min(), buffer.char_next(range.max()), content);
|
return buffer.replace(range.min(), buffer.char_next(range.max()), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void replace(Buffer& buffer, ArrayView<BufferRange> ranges, ConstArrayView<String> strings);
|
||||||
|
|
||||||
inline CharCount char_length(const Buffer& buffer, const Selection& range)
|
inline CharCount char_length(const Buffer& buffer, const Selection& range)
|
||||||
{
|
{
|
||||||
return utf8::distance(buffer.iterator_at(range.min()),
|
return utf8::distance(buffer.iterator_at(range.min()),
|
||||||
|
|
|
@ -413,31 +413,21 @@ void InsertCompleter::select(int index, bool relative, Vector<Key>& keystrokes)
|
||||||
|
|
||||||
auto ref = buffer.string(m_completions.begin, m_completions.end);
|
auto ref = buffer.string(m_completions.begin, m_completions.end);
|
||||||
ForwardChangesTracker changes_tracker;
|
ForwardChangesTracker changes_tracker;
|
||||||
size_t timestamp = buffer.timestamp();
|
Vector<BufferRange> ranges;
|
||||||
Vector<BufferCoord> positions;
|
|
||||||
for (auto& sel : selections)
|
for (auto& sel : selections)
|
||||||
{
|
{
|
||||||
auto pos = buffer.iterator_at(changes_tracker.get_new_coord_tolerant(sel.cursor()));
|
auto pos = buffer.iterator_at(sel.cursor());
|
||||||
if (pos.coord().column >= prefix_len and (pos + suffix_len) != buffer.end() and
|
if (pos.coord().column >= prefix_len and (pos + suffix_len) != buffer.end() and std::equal(ref.begin(), ref.end(), pos - prefix_len))
|
||||||
std::equal(ref.begin(), ref.end(), pos - prefix_len))
|
ranges.push_back({(pos - prefix_len).coord(), (pos + suffix_len).coord()});
|
||||||
{
|
|
||||||
positions.push_back(buffer.erase((pos - prefix_len).coord(),
|
|
||||||
(pos + suffix_len).coord()));
|
|
||||||
changes_tracker.update(buffer, timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
changes_tracker = ForwardChangesTracker{};
|
|
||||||
for (auto pos : positions)
|
|
||||||
{
|
|
||||||
buffer.insert(changes_tracker.get_new_coord_tolerant(pos), candidate.completion);
|
|
||||||
changes_tracker.update(buffer, timestamp);
|
|
||||||
}
|
}
|
||||||
|
replace(buffer, ranges, candidate.completion);
|
||||||
|
|
||||||
selections.update();
|
selections.update();
|
||||||
m_completions.end = cursor_pos;
|
m_completions.end = cursor_pos;
|
||||||
m_completions.begin = buffer.advance(cursor_pos, -candidate.completion.length());
|
m_completions.begin = buffer.advance(cursor_pos, -candidate.completion.length());
|
||||||
m_completions.timestamp = buffer.timestamp();
|
m_completions.timestamp = buffer.timestamp();
|
||||||
|
m_inserted_ranges = std::move(ranges);
|
||||||
|
|
||||||
if (m_context.has_client())
|
if (m_context.has_client())
|
||||||
{
|
{
|
||||||
m_context.client().menu_select(m_current_candidate);
|
m_context.client().menu_select(m_current_candidate);
|
||||||
|
@ -464,8 +454,8 @@ void InsertCompleter::update(bool allow_implicit)
|
||||||
setup_ifn();
|
setup_ifn();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& get_first(InsertCompletion& completions) { return completions.begin; }
|
auto& get_first(BufferRange& range) { return range.begin; }
|
||||||
auto& get_last(InsertCompletion& completions) { return completions.end; }
|
auto& get_last(BufferRange& range) { return range.end; }
|
||||||
|
|
||||||
void InsertCompleter::reset()
|
void InsertCompleter::reset()
|
||||||
{
|
{
|
||||||
|
@ -475,20 +465,9 @@ void InsertCompleter::reset()
|
||||||
if (m_context.has_client() and m_current_candidate >= 0 and m_current_candidate < m_completions.candidates.size() - 1)
|
if (m_context.has_client() and m_current_candidate >= 0 and m_current_candidate < m_completions.candidates.size() - 1)
|
||||||
{
|
{
|
||||||
auto& buffer = m_context.buffer();
|
auto& buffer = m_context.buffer();
|
||||||
update_ranges(buffer, m_completions.timestamp,
|
update_ranges(buffer, m_completions.timestamp, m_inserted_ranges);
|
||||||
ArrayView<InsertCompletion>(m_completions));
|
hook_param = join(m_inserted_ranges | filter([](auto&& r) { return not r.empty(); }) | transform([&](auto&& r) {
|
||||||
auto ref = buffer.string(m_completions.begin, m_completions.end);
|
return selection_to_string(ColumnType::Byte, buffer, {r.begin, buffer.char_prev(r.end)});
|
||||||
const auto& cursor_pos = m_context.selections().main().cursor();
|
|
||||||
const auto prefix_len = buffer.distance(m_completions.begin, cursor_pos);
|
|
||||||
const auto suffix_len = std::max(0_byte, buffer.distance(cursor_pos, m_completions.end));
|
|
||||||
hook_param = join(m_context.selections() |
|
|
||||||
transform([&](const auto& sel) { return buffer.iterator_at(sel.cursor()); }) |
|
|
||||||
filter([&](const auto& pos) {
|
|
||||||
return pos.coord().column >= prefix_len and (pos + suffix_len) != buffer.end() and
|
|
||||||
std::equal(ref.begin(), ref.end(), pos - prefix_len);
|
|
||||||
}) |
|
|
||||||
transform([&](const auto& pos) {
|
|
||||||
return selection_to_string(ColumnType::Byte, buffer, {(pos - prefix_len).coord(), buffer.char_prev((pos + suffix_len).coord())});
|
|
||||||
}), ' ');
|
}), ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ private:
|
||||||
OptionManager& m_options;
|
OptionManager& m_options;
|
||||||
const FaceRegistry& m_faces;
|
const FaceRegistry& m_faces;
|
||||||
InsertCompletion m_completions;
|
InsertCompletion m_completions;
|
||||||
|
Vector<BufferRange> m_inserted_ranges;
|
||||||
int m_current_candidate = -1;
|
int m_current_candidate = -1;
|
||||||
|
|
||||||
using CompleteFunc = InsertCompletion (const SelectionList& sels,
|
using CompleteFunc = InsertCompletion (const SelectionList& sels,
|
||||||
|
|
|
@ -24,6 +24,8 @@ struct Range
|
||||||
{
|
{
|
||||||
return hash_values(range.begin, range.end);
|
return hash_values(range.begin, range.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool empty() const { return begin == end; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user