diff --git a/src/context.cc b/src/context.cc index 3a0aadb4..0c1b8aad 100644 --- a/src/context.cc +++ b/src/context.cc @@ -225,24 +225,29 @@ void Context::SelectionHistory::undo() if (in_edition()) throw runtime_error("selection undo is only supported at top-level"); kak_assert(not empty()); + SelectionList old_selections = selections(); HistoryId next; - if constexpr (backward) - next = current_history_node().parent; - else - next = current_history_node().redo_child; - if (next == HistoryId::Invalid) - throw runtime_error(backward ? "no selection change to undo" : "no selection change to redo"); - auto select_next = [&, next] { - HistoryId previous_id = m_history_id; - m_history_id = next; + do + { if constexpr (backward) - current_history_node().redo_child = previous_id; - }; - Buffer& destination_buffer = history_node(next).selections.buffer(); - if (&destination_buffer == &m_context.buffer()) - select_next(); - else - m_context.change_buffer(destination_buffer, { std::move(select_next) }); + next = current_history_node().parent; + else + next = current_history_node().redo_child; + if (next == HistoryId::Invalid) + throw runtime_error(backward ? "no selection change to undo" : "no selection change to redo"); + auto select_next = [&, next] { + HistoryId previous_id = m_history_id; + m_history_id = next; + if constexpr (backward) + current_history_node().redo_child = previous_id; + }; + Buffer& destination_buffer = history_node(next).selections.buffer(); + if (&destination_buffer == &m_context.buffer()) + select_next(); + else + m_context.change_buffer(destination_buffer, { std::move(select_next) }); + } + while (selections() == old_selections); } void Context::SelectionHistory::forget_buffer(Buffer& buffer) diff --git a/test/normal/selection-undo/fold-redundant-entries/cmd b/test/normal/selection-undo/fold-redundant-entries/cmd new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/test/normal/selection-undo/fold-redundant-entries/cmd @@ -0,0 +1 @@ + diff --git a/test/normal/selection-undo/fold-redundant-entries/in b/test/normal/selection-undo/fold-redundant-entries/in new file mode 100644 index 00000000..94ebaf90 --- /dev/null +++ b/test/normal/selection-undo/fold-redundant-entries/in @@ -0,0 +1,4 @@ +1 +2 +3 +4 diff --git a/test/normal/selection-undo/fold-redundant-entries/out b/test/normal/selection-undo/fold-redundant-entries/out new file mode 100644 index 00000000..239c8675 --- /dev/null +++ b/test/normal/selection-undo/fold-redundant-entries/out @@ -0,0 +1,3 @@ +2 +3 +here4 diff --git a/test/normal/selection-undo/fold-redundant-entries/script b/test/normal/selection-undo/fold-redundant-entries/script new file mode 100644 index 00000000..456f92f2 --- /dev/null +++ b/test/normal/selection-undo/fold-redundant-entries/script @@ -0,0 +1,2 @@ +ui_out -ignore 4 +ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "gjgkxdihere" ] }'