Support counts for undo/redo
This commit is contained in:
parent
3edd2c127c
commit
03a4b3c73f
|
@ -310,31 +310,38 @@ void Buffer::commit_undo_group()
|
||||||
m_history_cursor = node;
|
m_history_cursor = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Buffer::undo() noexcept
|
bool Buffer::undo(size_t count) noexcept
|
||||||
{
|
{
|
||||||
commit_undo_group();
|
commit_undo_group();
|
||||||
|
|
||||||
if (not m_history_cursor->parent)
|
if (not m_history_cursor->parent)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (const Modification& modification : m_history_cursor->undo_group | reverse())
|
while (count-- and m_history_cursor->parent)
|
||||||
apply_modification(modification.inverse());
|
{
|
||||||
|
for (const Modification& modification : m_history_cursor->undo_group | reverse())
|
||||||
|
apply_modification(modification.inverse());
|
||||||
|
|
||||||
|
m_history_cursor = m_history_cursor->parent;
|
||||||
|
}
|
||||||
|
|
||||||
m_history_cursor = m_history_cursor->parent;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Buffer::redo() noexcept
|
bool Buffer::redo(size_t count) noexcept
|
||||||
{
|
{
|
||||||
if (not m_history_cursor->redo_child)
|
if (not m_history_cursor->redo_child)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
kak_assert(m_current_undo_group.empty());
|
kak_assert(m_current_undo_group.empty());
|
||||||
|
|
||||||
m_history_cursor = m_history_cursor->redo_child.get();
|
while (count-- and m_history_cursor->redo_child)
|
||||||
|
{
|
||||||
|
m_history_cursor = m_history_cursor->redo_child.get();
|
||||||
|
|
||||||
for (const Modification& modification : m_history_cursor->undo_group)
|
for (const Modification& modification : m_history_cursor->undo_group)
|
||||||
apply_modification(modification);
|
apply_modification(modification);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,8 +833,8 @@ UnitTest test_undo{[]()
|
||||||
buffer.commit_undo_group();
|
buffer.commit_undo_group();
|
||||||
buffer.erase({2, 1}, {2, 5}); // change 5
|
buffer.erase({2, 1}, {2, 5}); // change 5
|
||||||
buffer.commit_undo_group();
|
buffer.commit_undo_group();
|
||||||
buffer.undo();
|
buffer.undo(2);
|
||||||
buffer.redo();
|
buffer.redo(2);
|
||||||
buffer.undo();
|
buffer.undo();
|
||||||
buffer.replace(2_line, buffer.end_coord(), "foo"); // change 6
|
buffer.replace(2_line, buffer.end_coord(), "foo"); // change 6
|
||||||
buffer.commit_undo_group();
|
buffer.commit_undo_group();
|
||||||
|
|
|
@ -132,8 +132,8 @@ public:
|
||||||
void set_fs_timestamp(timespec ts);
|
void set_fs_timestamp(timespec ts);
|
||||||
|
|
||||||
void commit_undo_group();
|
void commit_undo_group();
|
||||||
bool undo() noexcept;
|
bool undo(size_t count = 1) noexcept;
|
||||||
bool redo() noexcept;
|
bool redo(size_t count = 1) noexcept;
|
||||||
bool move_to(size_t history_id) noexcept;
|
bool move_to(size_t history_id) noexcept;
|
||||||
|
|
||||||
String string(ByteCoord begin, ByteCoord end) const;
|
String string(ByteCoord begin, ByteCoord end) const;
|
||||||
|
|
|
@ -1414,37 +1414,34 @@ void restore_selections(Context& context, NormalParams params)
|
||||||
context.print_status({format("Restored selections from register '{}'", reg), get_face("Information")});
|
context.print_status({format("Restored selections from register '{}'", reg), get_face("Information")});
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo(Context& context, NormalParams)
|
void undo(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
size_t timestamp = buffer.timestamp();
|
size_t timestamp = buffer.timestamp();
|
||||||
bool res = buffer.undo();
|
if (buffer.undo(std::max(1, params.count)))
|
||||||
if (res)
|
|
||||||
{
|
{
|
||||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||||
if (not ranges.empty())
|
if (not ranges.empty())
|
||||||
context.selections_write_only() = std::move(ranges);
|
context.selections_write_only() = std::move(ranges);
|
||||||
context.selections().avoid_eol();
|
context.selections().avoid_eol();
|
||||||
}
|
}
|
||||||
else if (not res)
|
else
|
||||||
context.print_status({ "nothing left to undo", get_face("Information") });
|
context.print_status({ "nothing left to undo", get_face("Information") });
|
||||||
}
|
}
|
||||||
|
|
||||||
void redo(Context& context, NormalParams)
|
void redo(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
size_t timestamp = buffer.timestamp();
|
size_t timestamp = buffer.timestamp();
|
||||||
bool res = buffer.redo();
|
if (buffer.redo(std::max(1, params.count)))
|
||||||
if (res)
|
|
||||||
{
|
{
|
||||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||||
if (not ranges.empty())
|
if (not ranges.empty())
|
||||||
context.selections_write_only() = std::move(ranges);
|
context.selections_write_only() = std::move(ranges);
|
||||||
context.selections().avoid_eol();
|
context.selections().avoid_eol();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
else if (not res)
|
|
||||||
context.print_status({ "nothing left to redo", get_face("Information") });
|
context.print_status({ "nothing left to redo", get_face("Information") });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user