Extract merge_overlapping as a free function template
This commit is contained in:
parent
5bcb55b6dd
commit
1b30c0f4fb
|
@ -1155,7 +1155,7 @@ void spaces_to_tabs(Context& context, int ts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::optional<SelectionList> compute_modified_ranges(Buffer& buffer, size_t timestamp)
|
static std::vector<Selection> compute_modified_ranges(Buffer& buffer, size_t timestamp)
|
||||||
{
|
{
|
||||||
std::vector<Selection> ranges;
|
std::vector<Selection> ranges;
|
||||||
for (auto& change : buffer.changes_since(timestamp))
|
for (auto& change : buffer.changes_since(timestamp))
|
||||||
|
@ -1183,29 +1183,25 @@ static boost::optional<SelectionList> compute_modified_ranges(Buffer& buffer, si
|
||||||
ranges.insert(it, Selection{pos, pos});
|
ranges.insert(it, Selection{pos, pos});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ranges.empty())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
for (auto& sel : ranges)
|
for (auto& sel : ranges)
|
||||||
{
|
{
|
||||||
sel.anchor() = buffer.clamp(sel.anchor());
|
sel.anchor() = buffer.clamp(sel.anchor());
|
||||||
sel.cursor() = buffer.clamp(sel.cursor());
|
sel.cursor() = buffer.clamp(sel.cursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionList result{buffer, std::move(ranges)};
|
|
||||||
|
|
||||||
auto touches = [&](const Selection& lhs, const Selection& rhs) {
|
auto touches = [&](const Selection& lhs, const Selection& rhs) {
|
||||||
return lhs.min() <= rhs.min() ? buffer.char_next(lhs.max()) >= rhs.min()
|
return lhs.min() <= rhs.min() ? buffer.char_next(lhs.max()) >= rhs.min()
|
||||||
: lhs.min() <= buffer.char_next(rhs.max());
|
: lhs.min() <= buffer.char_next(rhs.max());
|
||||||
};
|
};
|
||||||
result.merge_overlapping(touches);
|
size_t main = 0;
|
||||||
|
merge_overlapping(ranges.begin(), ranges.end(), main, touches);
|
||||||
|
|
||||||
for (auto& sel : result)
|
for (auto& sel : ranges)
|
||||||
{
|
{
|
||||||
if (sel.anchor() != sel.cursor())
|
if (sel.anchor() != sel.cursor())
|
||||||
sel.cursor() = buffer.char_prev(sel.cursor());
|
sel.cursor() = buffer.char_prev(sel.cursor());
|
||||||
}
|
}
|
||||||
return result;
|
return ranges;
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo(Context& context, int)
|
void undo(Context& context, int)
|
||||||
|
@ -1216,8 +1212,8 @@ void undo(Context& context, int)
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||||
if (ranges)
|
if (not ranges.empty())
|
||||||
context.selections() = std::move(*ranges);
|
context.selections() = std::move(ranges);
|
||||||
}
|
}
|
||||||
else if (not res)
|
else if (not res)
|
||||||
context.print_status({ "nothing left to undo", get_color("Information") });
|
context.print_status({ "nothing left to undo", get_color("Information") });
|
||||||
|
@ -1232,8 +1228,8 @@ void redo(Context& context, int)
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||||
if (ranges)
|
if (not ranges.empty())
|
||||||
context.selections() = std::move(*ranges);
|
context.selections() = std::move(ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (not res)
|
else if (not res)
|
||||||
|
|
|
@ -166,7 +166,7 @@ void SelectionList::update()
|
||||||
sel.anchor() = m_buffer->clamp(sel.anchor());
|
sel.anchor() = m_buffer->clamp(sel.anchor());
|
||||||
sel.cursor() = m_buffer->clamp(sel.cursor());
|
sel.cursor() = m_buffer->clamp(sel.cursor());
|
||||||
}
|
}
|
||||||
merge_overlapping(overlaps);
|
m_selections.erase(merge_overlapping(begin(), end(), m_main, overlaps), end());
|
||||||
check_invariant();
|
check_invariant();
|
||||||
|
|
||||||
m_timestamp = m_buffer->timestamp();
|
m_timestamp = m_buffer->timestamp();
|
||||||
|
@ -208,7 +208,7 @@ void SelectionList::sort_and_merge_overlapping()
|
||||||
return begin < main_begin;
|
return begin < main_begin;
|
||||||
});
|
});
|
||||||
std::stable_sort(begin(), end(), compare_selections);
|
std::stable_sort(begin(), end(), compare_selections);
|
||||||
merge_overlapping(overlaps);
|
m_selections.erase(merge_overlapping(begin(), end(), m_main, overlaps), end());
|
||||||
}
|
}
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,6 +71,30 @@ enum class InsertMode : unsigned
|
||||||
OpenLineAbove
|
OpenLineAbove
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Iterator, typename OverlapsFunc>
|
||||||
|
Iterator merge_overlapping(Iterator begin, Iterator end, size_t& main, OverlapsFunc overlaps)
|
||||||
|
{
|
||||||
|
kak_assert(std::is_sorted(begin, end, compare_selections));
|
||||||
|
size_t size = end - begin;
|
||||||
|
size_t i = 0;
|
||||||
|
for (size_t j = 1; j < size; ++j)
|
||||||
|
{
|
||||||
|
if (overlaps(begin[i], begin[j]))
|
||||||
|
{
|
||||||
|
begin[i].merge_with(begin[j]);
|
||||||
|
if (i < main)
|
||||||
|
--main;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if (i != j)
|
||||||
|
begin[i] = std::move(begin[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return begin + i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct SelectionList
|
struct SelectionList
|
||||||
{
|
{
|
||||||
SelectionList(Buffer& buffer, Selection s);
|
SelectionList(Buffer& buffer, Selection s);
|
||||||
|
@ -122,30 +146,6 @@ struct SelectionList
|
||||||
bool operator==(const SelectionList& other) const { return m_buffer == other.m_buffer and m_selections == other.m_selections; }
|
bool operator==(const SelectionList& other) const { return m_buffer == other.m_buffer and m_selections == other.m_selections; }
|
||||||
bool operator!=(const SelectionList& other) const { return !((*this) == other); }
|
bool operator!=(const SelectionList& other) const { return !((*this) == other); }
|
||||||
|
|
||||||
template<typename OverlapsFunc>
|
|
||||||
void merge_overlapping(OverlapsFunc overlaps)
|
|
||||||
{
|
|
||||||
kak_assert(std::is_sorted(begin(), end(), compare_selections));
|
|
||||||
size_t i = 0;
|
|
||||||
for (size_t j = 1; j < size(); ++j)
|
|
||||||
{
|
|
||||||
if (overlaps((*this)[i], (*this)[j]))
|
|
||||||
{
|
|
||||||
(*this)[i].merge_with((*this)[j]);
|
|
||||||
if (i < m_main)
|
|
||||||
--m_main;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
if (i != j)
|
|
||||||
(*this)[i] = std::move((*this)[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_selections.erase(begin() + i + 1, end());
|
|
||||||
kak_assert(std::is_sorted(begin(), end(), compare_selections));
|
|
||||||
}
|
|
||||||
|
|
||||||
void sort_and_merge_overlapping();
|
void sort_and_merge_overlapping();
|
||||||
|
|
||||||
Buffer& buffer() const { return *m_buffer; }
|
Buffer& buffer() const { return *m_buffer; }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user