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,
|
||||
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()) {}
|
||||
|
||||
constexpr ArrayView(const std::initializer_list<T>& v)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "event_manager.hh"
|
||||
#include "file.hh"
|
||||
#include "selection.hh"
|
||||
#include "changes.hh"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -15,6 +16,25 @@
|
|||
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 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);
|
||||
}
|
||||
|
||||
void replace(Buffer& buffer, ArrayView<BufferRange> ranges, ConstArrayView<String> strings);
|
||||
|
||||
inline CharCount char_length(const Buffer& buffer, const Selection& range)
|
||||
{
|
||||
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);
|
||||
ForwardChangesTracker changes_tracker;
|
||||
size_t timestamp = buffer.timestamp();
|
||||
Vector<BufferCoord> positions;
|
||||
Vector<BufferRange> ranges;
|
||||
for (auto& sel : selections)
|
||||
{
|
||||
auto pos = buffer.iterator_at(changes_tracker.get_new_coord_tolerant(sel.cursor()));
|
||||
if (pos.coord().column >= prefix_len and (pos + suffix_len) != buffer.end() and
|
||||
std::equal(ref.begin(), ref.end(), pos - prefix_len))
|
||||
{
|
||||
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);
|
||||
auto pos = buffer.iterator_at(sel.cursor());
|
||||
if (pos.coord().column >= prefix_len and (pos + suffix_len) != buffer.end() and std::equal(ref.begin(), ref.end(), pos - prefix_len))
|
||||
ranges.push_back({(pos - prefix_len).coord(), (pos + suffix_len).coord()});
|
||||
}
|
||||
replace(buffer, ranges, candidate.completion);
|
||||
|
||||
selections.update();
|
||||
m_completions.end = cursor_pos;
|
||||
m_completions.begin = buffer.advance(cursor_pos, -candidate.completion.length());
|
||||
m_completions.timestamp = buffer.timestamp();
|
||||
m_inserted_ranges = std::move(ranges);
|
||||
|
||||
if (m_context.has_client())
|
||||
{
|
||||
m_context.client().menu_select(m_current_candidate);
|
||||
|
@ -464,8 +454,8 @@ void InsertCompleter::update(bool allow_implicit)
|
|||
setup_ifn();
|
||||
}
|
||||
|
||||
auto& get_first(InsertCompletion& completions) { return completions.begin; }
|
||||
auto& get_last(InsertCompletion& completions) { return completions.end; }
|
||||
auto& get_first(BufferRange& range) { return range.begin; }
|
||||
auto& get_last(BufferRange& range) { return range.end; }
|
||||
|
||||
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)
|
||||
{
|
||||
auto& buffer = m_context.buffer();
|
||||
update_ranges(buffer, m_completions.timestamp,
|
||||
ArrayView<InsertCompletion>(m_completions));
|
||||
auto ref = buffer.string(m_completions.begin, m_completions.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())});
|
||||
update_ranges(buffer, m_completions.timestamp, m_inserted_ranges);
|
||||
hook_param = join(m_inserted_ranges | filter([](auto&& r) { return not r.empty(); }) | transform([&](auto&& r) {
|
||||
return selection_to_string(ColumnType::Byte, buffer, {r.begin, buffer.char_prev(r.end)});
|
||||
}), ' ');
|
||||
}
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ private:
|
|||
OptionManager& m_options;
|
||||
const FaceRegistry& m_faces;
|
||||
InsertCompletion m_completions;
|
||||
Vector<BufferRange> m_inserted_ranges;
|
||||
int m_current_candidate = -1;
|
||||
|
||||
using CompleteFunc = InsertCompletion (const SelectionList& sels,
|
||||
|
|
|
@ -24,6 +24,8 @@ struct Range
|
|||
{
|
||||
return hash_values(range.begin, range.end);
|
||||
}
|
||||
|
||||
bool empty() const { return begin == end; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user