How do I run a full-buffer substitution without disturbing marks, jumplist, or search history?
Answer
:lockmarks keepjumps keeppatterns %s/foo/bar/ge
Explanation
Large substitutions are efficient, but they often leave side effects: your last search changes, your jumplist gets noisy, and marks can shift in ways that break your navigation flow. Vim command modifiers let you prevent that. By combining :lockmarks, :keepjumps, and :keeppatterns, you can do structural edits while preserving editor context for the next task.
How it works
:lockmarksprevents certain commands from updating marks while they runkeepjumpsavoids adding jump entries caused by the commandkeeppatternskeeps your current search register (@/) unchanged%s/foo/bar/geruns the substitution across the full buffergreplaces all matches per line, andesuppresses "pattern not found" errors
This combination is especially helpful in long files where you depend on mark/jump history for orientation.
Example
You are in the middle of a debugging session, with marks and search state already set, and need to rename an identifier in the current file. Run:
:lockmarks keepjumps keeppatterns %s/OldClient/NewClient/ge
Before:
OldClient.connect()
if OldClient.ready?
OldClient.run()
end
After:
NewClient.connect()
if NewClient.ready?
NewClient.run()
end
Your existing / pattern and jump navigation remain intact.
Tips
- Add
| updateif you want to write only when modified - Use a visual range (
'<,'>) instead of%for partial-file changes - Prefer this pattern in macros/scripts where context preservation matters