How do I append text with :normal without creating an extra undo step?
Answer
:undojoin | normal! A;<CR>
Explanation
When you automate edits from Ex commands, Vim usually creates a separate undo entry for each change. :undojoin lets you merge the next change into the previous undo block, so one u reverts the whole scripted operation. This is especially useful in mappings, command-line workflows, and one-off refactors where you want atomic undo behavior.
How it works
:undojointells Vim to join the next change with the previous undo step|chains another Ex command on the same command-linenormal! A;runs a Normal-mode append-at-end (A) and inserts;
A key detail: :undojoin only works if there was a change immediately before it. If no prior undoable edit exists, Vim raises an error instead of silently creating a new block.
Example
Suppose you run one scripted append, then a second append joined with :undojoin:
:normal! A,
:undojoin | normal! A;
Before:
result = value
After both commands:
result = value,;
Pressing u once reverts both scripted appends together, not one-by-one.
Tips
- Use this in custom commands when multiple edits should feel like one action
- Prefer
normal!(with!) so mappings do not interfere - If you see an
:undojoinerror, run it only after a successful change