Make selection undo skip over entries that are nop after buffer change
After buffer modification - in particular after deletion - adjacent selection history entries may correspond to the same effective selection when applied to the current buffer. This means that we sometimes need to press <c-h> multiple times to make one visible change. This is not what the user expects, so let's keep walking the selection history until we hit an actual change. Alternatively, we could minimize the selection history after buffer changes but I think that would make the it worse after content undo+redo.
This commit is contained in:
parent
8427379a5d
commit
516759bb2f
|
@ -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)
|
||||
|
|
1
test/normal/selection-undo/fold-redundant-entries/cmd
Normal file
1
test/normal/selection-undo/fold-redundant-entries/cmd
Normal file
|
@ -0,0 +1 @@
|
|||
|
4
test/normal/selection-undo/fold-redundant-entries/in
Normal file
4
test/normal/selection-undo/fold-redundant-entries/in
Normal file
|
@ -0,0 +1,4 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
3
test/normal/selection-undo/fold-redundant-entries/out
Normal file
3
test/normal/selection-undo/fold-redundant-entries/out
Normal file
|
@ -0,0 +1,3 @@
|
|||
2
|
||||
3
|
||||
here4
|
2
test/normal/selection-undo/fold-redundant-entries/script
Normal file
2
test/normal/selection-undo/fold-redundant-entries/script
Normal file
|
@ -0,0 +1,2 @@
|
|||
ui_out -ignore 4
|
||||
ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "gjgkxd<c-h>ihere<esc>" ] }'
|
Loading…
Reference in New Issue
Block a user