How do I trim trailing whitespace while preserving marks, jumplist, and search state?
Answer
:lockmarks keepjumps keeppatterns %s/\s\+$//e
Explanation
Bulk cleanup commands are easy to automate, but many implementations quietly damage editor state by moving marks, polluting the jumplist, or replacing your last search pattern. This one-liner performs a full-buffer trailing-whitespace cleanup while keeping those navigation/search affordances intact. It is ideal for save hooks and project-wide hygiene where editor state stability matters.
How it works
:lockmarksprevents mark shifts during text changeskeepjumpsavoids recording jump locations caused by the commandkeeppatternspreserves the current search register (@/)%s/\s\+$//eremoves trailing whitespace on all lines and suppresses "pattern not found" errors
Example
Before cleanup, assume lines contain trailing whitespace:
let total = sum(items)<space><space>
return total<tab>
Run:
:lockmarks keepjumps keeppatterns %s/\s\+$//e
After cleanup:
let total = sum(items)
return total
Your marks and jumplist remain stable, and your previous search context is still available.
Tips
- Use this in
BufWritePreautocommands for non-disruptive formatting - If you also want cursor/view preservation, wrap with
winsaveview()/winrestview() - Keep
eon substitutions in automation to avoid noisy errors when there is nothing to fix