summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-08-04 11:39:28 +0700
committerMaxime Coste <mawww@kakoune.org>2017-08-04 11:39:28 +0700
commitfc64369f9d8d3279f73b89fdd76df2fa1468ff72 (patch)
tree1efec616364f72c6ca00cc7ec754cb8f6aa49efb
parent45a7496f545bf7b10940bc55c27ddf018a1ffd17 (diff)
Purge history on buffer reload when NoUndo flag is on
We were preserving the history in that case, so on fifo buffers (that set the NoUndo flag until the fifo is closed), we still had the history from the "previous life" of the buffer, leading crashes when trying to apply it. Fixes #1518
-rw-r--r--src/buffer.cc9
-rw-r--r--src/buffer.hh4
-rw-r--r--test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd1
3 files changed, 9 insertions, 5 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index b85d01ee..147e1bbf 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -242,10 +242,13 @@ void Buffer::reload(StringView data, timespec fs_timestamp)
if (not record_undo)
{
- m_changes.push_back({ Change::Erase, {0,0}, line_count() });
+ // Erase history about to be invalidated history
+ m_history_cursor = &m_history;
+ m_last_save_history_cursor = &m_history;
+ m_history = HistoryNode{m_next_history_id++, nullptr};
+ m_changes.push_back({ Change::Erase, {0,0}, line_count() });
static_cast<BufferLines&>(m_lines) = std::move(parsed_lines.lines);
-
m_changes.push_back({ Change::Insert, {0,0}, line_count() });
}
else
@@ -340,7 +343,7 @@ bool Buffer::redo(size_t count) noexcept
while (count-- != 0 and m_history_cursor->redo_child)
{
- m_history_cursor = m_history_cursor->redo_child.get();
+ m_history_cursor = m_history_cursor->redo_child;
for (const Modification& modification : m_history_cursor->undo_group)
apply_modification(modification);
diff --git a/src/buffer.hh b/src/buffer.hh
index ee03c0a0..7cf2db7b 100644
--- a/src/buffer.hh
+++ b/src/buffer.hh
@@ -252,14 +252,14 @@ private:
using UndoGroup = Vector<Modification, MemoryDomain::BufferMeta>;
- struct HistoryNode : SafeCountable, UseMemoryDomain<MemoryDomain::BufferMeta>
+ struct HistoryNode : SafeCountable, UseMemoryDomain<MemoryDomain::BufferMeta>
{
HistoryNode(size_t id, HistoryNode* parent);
UndoGroup undo_group;
Vector<std::unique_ptr<HistoryNode>, MemoryDomain::BufferMeta> childs;
SafePtr<HistoryNode> parent;
- SafePtr<HistoryNode> redo_child;
+ HistoryNode* redo_child = nullptr; // not a SafePtr to avoid lifetime issues between this and childs
size_t id;
TimePoint timepoint;
};
diff --git a/test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd b/test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd
new file mode 100644
index 00000000..a8902d2d
--- /dev/null
+++ b/test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd
@@ -0,0 +1 @@
+<a-O>ifoo<c-u><esc>:edit -fifo /dev/null <c-r>%<ret>u