Buffer: bump version on every content change
SetDirty(false) did not bump the version, so undo back to the saved state (and reload, and replace_all_bytes) left the highlighter serving spans for the old text. Reloading a file deleted on disk now also clears undo history recorded against the old content. Audit finding D9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
@@ -455,6 +455,10 @@ Buffer::OpenFromFile(const std::string &path, std::string &err)
|
|||||||
// Empty PieceTable
|
// Empty PieceTable
|
||||||
content_.Clear();
|
content_.Clear();
|
||||||
rows_cache_dirty_ = true;
|
rows_cache_dirty_ = true;
|
||||||
|
// History recorded against the previous content no longer applies.
|
||||||
|
if (undo_sys_)
|
||||||
|
undo_sys_->clear();
|
||||||
|
MarkContentChanged();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -520,6 +524,7 @@ Buffer::OpenFromFile(const std::string &path, std::string &err)
|
|||||||
undo_sys_ = std::make_unique<UndoSystem>(*this, *undo_tree_);
|
undo_sys_ = std::make_unique<UndoSystem>(*this, *undo_tree_);
|
||||||
// Clear any existing history for a fresh load
|
// Clear any existing history for a fresh load
|
||||||
undo_sys_->clear();
|
undo_sys_->clear();
|
||||||
|
MarkContentChanged();
|
||||||
|
|
||||||
// Reset cursor/viewport state
|
// Reset cursor/viewport state
|
||||||
curx_ = cury_ = rx_ = 0;
|
curx_ = cury_ = rx_ = 0;
|
||||||
@@ -829,6 +834,7 @@ Buffer::replace_all_bytes(const std::string_view bytes)
|
|||||||
if (!bytes.empty())
|
if (!bytes.empty())
|
||||||
content_.Append(bytes.data(), bytes.size());
|
content_.Append(bytes.data(), bytes.size());
|
||||||
rows_cache_dirty_ = true;
|
rows_cache_dirty_ = true;
|
||||||
|
MarkContentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -391,11 +391,19 @@ public:
|
|||||||
void SetDirty(bool d)
|
void SetDirty(bool d)
|
||||||
{
|
{
|
||||||
dirty_ = d;
|
dirty_ = d;
|
||||||
if (d) {
|
// Bump even when clearing: undo/redo back to the saved state changes the
|
||||||
++version_;
|
// text and then calls SetDirty(false). Without a bump the highlighter
|
||||||
if (highlighter_) {
|
// keeps serving spans for the pre-undo text.
|
||||||
highlighter_->InvalidateFrom(0);
|
MarkContentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Invalidate version-keyed caches (syntax highlighting) after a content change.
|
||||||
|
void MarkContentChanged()
|
||||||
|
{
|
||||||
|
++version_;
|
||||||
|
if (highlighter_) {
|
||||||
|
highlighter_->InvalidateFrom(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user