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) { + // 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(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; - struct HistoryNode : SafeCountable, UseMemoryDomain + struct HistoryNode : SafeCountable, UseMemoryDomain { HistoryNode(size_t id, HistoryNode* parent); UndoGroup undo_group; Vector, MemoryDomain::BufferMeta> childs; SafePtr parent; - SafePtr 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 @@ +ifoo:edit -fifo /dev/null %u