- Redoing an insert and undoing a delete put the cursor at col + size
on the start row even when the text spans lines, i.e. past the end of
the line. Later edits and their undo records then went to the wrong
place (a join recorded at column 2 of 'a' re-split the text wrongly)
and delete-word-prev read past the line (heap-buffer-overflow under
ASan). The cursor now goes after the text's last newline, and undo and
redo clamp it to the buffer.
- A recovered buffer stays modified in every undo state
(mark_base_unsaved): one edit and its undo made it look clean, and
closing it then discarded the recovered text and its journal.
- Save-and-quit records the saved undo state.
- Visual-line selections are clamped to the buffer when read; the
visual newline counts the cursor's own line only if it was selected.
A stale selection put the cursor rows past the end, where typed text
could not be undone.
- The yank size cap accounts for visual-line yanks (once per line).
- After an exception escapes a command, open undo groups are closed so
later edits do not join them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB