Move Editor::{undo,redo} to free functions in normal.cc
This commit is contained in:
parent
cb9384f8a7
commit
8047cc97d3
|
@ -24,72 +24,6 @@ std::vector<String> Editor::selections_content() const
|
|||
return contents;
|
||||
}
|
||||
|
||||
class ModifiedRangesListener : public BufferChangeListener_AutoRegister
|
||||
{
|
||||
public:
|
||||
ModifiedRangesListener(Buffer& buffer)
|
||||
: BufferChangeListener_AutoRegister(buffer) {}
|
||||
|
||||
void on_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
||||
{
|
||||
m_ranges.update_insert(buffer, begin, end);
|
||||
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
|
||||
[](BufferCoord c, const Selection& sel)
|
||||
{ return c < sel.min(); });
|
||||
m_ranges.emplace(it, begin, buffer.char_prev(end));
|
||||
}
|
||||
|
||||
void on_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
||||
{
|
||||
m_ranges.update_erase(buffer, begin, end);
|
||||
auto pos = std::min(begin, buffer.back_coord());
|
||||
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), pos,
|
||||
[](BufferCoord c, const Selection& sel)
|
||||
{ return c < sel.min(); });
|
||||
m_ranges.emplace(it, pos, pos);
|
||||
}
|
||||
SelectionList& ranges() { return m_ranges; }
|
||||
|
||||
private:
|
||||
SelectionList m_ranges;
|
||||
};
|
||||
|
||||
inline bool touches(const Buffer& buffer, const Range& lhs, const Range& rhs)
|
||||
{
|
||||
return lhs.min() <= rhs.min() ? buffer.char_next(lhs.max()) >= rhs.min()
|
||||
: lhs.min() <= buffer.char_next(rhs.max());
|
||||
}
|
||||
|
||||
bool Editor::undo()
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
ModifiedRangesListener listener(buffer());
|
||||
bool res = m_buffer->undo();
|
||||
if (res and not listener.ranges().empty())
|
||||
{
|
||||
m_selections = std::move(listener.ranges());
|
||||
m_selections.set_main_index(m_selections.size() - 1);
|
||||
m_selections.merge_overlapping(std::bind(touches, std::ref(buffer()), _1, _2));
|
||||
}
|
||||
check_invariant();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Editor::redo()
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
ModifiedRangesListener listener(buffer());
|
||||
bool res = m_buffer->redo();
|
||||
if (res and not listener.ranges().empty())
|
||||
{
|
||||
m_selections = std::move(listener.ranges());
|
||||
m_selections.set_main_index(m_selections.size() - 1);
|
||||
m_selections.merge_overlapping(std::bind(touches, std::ref(buffer()), _1, _2));
|
||||
}
|
||||
check_invariant();
|
||||
return res;
|
||||
}
|
||||
|
||||
void Editor::check_invariant() const
|
||||
{
|
||||
#ifdef KAK_DEBUG
|
||||
|
|
|
@ -30,9 +30,6 @@ public:
|
|||
SelectionList& selections() { return m_selections; }
|
||||
std::vector<String> selections_content() const;
|
||||
|
||||
bool undo();
|
||||
bool redo();
|
||||
|
||||
private:
|
||||
friend struct scoped_edition;
|
||||
friend class InputModes::Insert;
|
||||
|
|
|
@ -1094,6 +1094,73 @@ void align_indent(Context& context, int selection)
|
|||
}
|
||||
}
|
||||
|
||||
class ModifiedRangesListener : public BufferChangeListener_AutoRegister
|
||||
{
|
||||
public:
|
||||
ModifiedRangesListener(Buffer& buffer)
|
||||
: BufferChangeListener_AutoRegister(buffer) {}
|
||||
|
||||
void on_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
||||
{
|
||||
m_ranges.update_insert(buffer, begin, end);
|
||||
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
|
||||
[](BufferCoord c, const Selection& sel)
|
||||
{ return c < sel.min(); });
|
||||
m_ranges.emplace(it, begin, buffer.char_prev(end));
|
||||
}
|
||||
|
||||
void on_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
||||
{
|
||||
m_ranges.update_erase(buffer, begin, end);
|
||||
auto pos = std::min(begin, buffer.back_coord());
|
||||
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), pos,
|
||||
[](BufferCoord c, const Selection& sel)
|
||||
{ return c < sel.min(); });
|
||||
m_ranges.emplace(it, pos, pos);
|
||||
}
|
||||
SelectionList& ranges() { return m_ranges; }
|
||||
|
||||
private:
|
||||
SelectionList m_ranges;
|
||||
};
|
||||
|
||||
inline bool touches(const Buffer& buffer, const Range& lhs, const Range& rhs)
|
||||
{
|
||||
return lhs.min() <= rhs.min() ? buffer.char_next(lhs.max()) >= rhs.min()
|
||||
: lhs.min() <= buffer.char_next(rhs.max());
|
||||
}
|
||||
|
||||
void undo(Context& context, int)
|
||||
{
|
||||
ModifiedRangesListener listener(context.buffer());
|
||||
bool res = context.buffer().undo();
|
||||
if (res and not listener.ranges().empty())
|
||||
{
|
||||
auto& selections = context.selections();
|
||||
selections = std::move(listener.ranges());
|
||||
selections.set_main_index(selections.size() - 1);
|
||||
selections.merge_overlapping(std::bind(touches, std::ref(context.buffer()), _1, _2));
|
||||
}
|
||||
else if (not res)
|
||||
context.print_status({ "nothing left to undo", get_color("Information") });
|
||||
}
|
||||
|
||||
void redo(Context& context, int)
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
ModifiedRangesListener listener(context.buffer());
|
||||
bool res = context.buffer().redo();
|
||||
if (res and not listener.ranges().empty())
|
||||
{
|
||||
auto& selections = context.selections();
|
||||
selections = std::move(listener.ranges());
|
||||
selections.set_main_index(selections.size() - 1);
|
||||
selections.merge_overlapping(std::bind(touches, std::ref(context.buffer()), _1, _2));
|
||||
}
|
||||
else if (not res)
|
||||
context.print_status({ "nothing left to redo", get_color("Information") });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class Repeated
|
||||
{
|
||||
|
@ -1225,8 +1292,8 @@ KeyMap keymap =
|
|||
{ '*', use_selection_as_search_pattern<true> },
|
||||
{ alt('*'), use_selection_as_search_pattern<false> },
|
||||
|
||||
{ 'u', repeated([](Context& context, int) { if (not context.editor().undo()) context.print_status({ "nothing left to undo", get_color("Information") }); }) },
|
||||
{ 'U', repeated([](Context& context, int) { if (not context.editor().redo()) context.print_status({ "nothing left to redo", get_color("Information") }); }) },
|
||||
{ 'u', undo },
|
||||
{ 'U', redo },
|
||||
|
||||
{ alt('i'), select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd | ObjectFlags::Inner> },
|
||||
{ alt('a'), select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd> },
|
||||
|
|
Loading…
Reference in New Issue
Block a user