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;
|
||||
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});
|
||||
}
|
||||
}
|
||||
if (ranges.empty())
|
||||
return {};
|
||||
|
||||
for (auto& sel : ranges)
|
||||
{
|
||||
sel.anchor() = buffer.clamp(sel.anchor());
|
||||
sel.cursor() = buffer.clamp(sel.cursor());
|
||||
}
|
||||
|
||||
SelectionList result{buffer, std::move(ranges)};
|
||||
|
||||
auto touches = [&](const Selection& lhs, const Selection& rhs) {
|
||||
return lhs.min() <= rhs.min() ? buffer.char_next(lhs.max()) >= rhs.min()
|
||||
: 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())
|
||||
sel.cursor() = buffer.char_prev(sel.cursor());
|
||||
}
|
||||
return result;
|
||||
return ranges;
|
||||
}
|
||||
|
||||
void undo(Context& context, int)
|
||||
|
@ -1216,8 +1212,8 @@ void undo(Context& context, int)
|
|||
if (res)
|
||||
{
|
||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||
if (ranges)
|
||||
context.selections() = std::move(*ranges);
|
||||
if (not ranges.empty())
|
||||
context.selections() = std::move(ranges);
|
||||
}
|
||||
else if (not res)
|
||||
context.print_status({ "nothing left to undo", get_color("Information") });
|
||||
|
@ -1232,8 +1228,8 @@ void redo(Context& context, int)
|
|||
if (res)
|
||||
{
|
||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||
if (ranges)
|
||||
context.selections() = std::move(*ranges);
|
||||
if (not ranges.empty())
|
||||
context.selections() = std::move(ranges);
|
||||
}
|
||||
|
||||
else if (not res)
|
||||
|
|
|
@ -166,7 +166,7 @@ void SelectionList::update()
|
|||
sel.anchor() = m_buffer->clamp(sel.anchor());
|
||||
sel.cursor() = m_buffer->clamp(sel.cursor());
|
||||
}
|
||||
merge_overlapping(overlaps);
|
||||
m_selections.erase(merge_overlapping(begin(), end(), m_main, overlaps), end());
|
||||
check_invariant();
|
||||
|
||||
m_timestamp = m_buffer->timestamp();
|
||||
|
@ -208,7 +208,7 @@ void SelectionList::sort_and_merge_overlapping()
|
|||
return begin < main_begin;
|
||||
});
|
||||
std::stable_sort(begin(), end(), compare_selections);
|
||||
merge_overlapping(overlaps);
|
||||
m_selections.erase(merge_overlapping(begin(), end(), m_main, overlaps), end());
|
||||
}
|
||||
namespace
|
||||
{
|
||||
|
|
|
@ -71,6 +71,30 @@ enum class InsertMode : unsigned
|
|||
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
|
||||
{
|
||||
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 !((*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();
|
||||
|
||||
Buffer& buffer() const { return *m_buffer; }
|
||||
|
|
Loading…
Reference in New Issue
Block a user