vimtricks.wiki Concise Vim tricks, one at a time.

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

  • :lockmarks prevents certain commands from updating marks while they run
  • keepjumps avoids adding jump entries caused by the command
  • keeppatterns keeps your current search register (@/) unchanged
  • %s/foo/bar/ge runs the substitution across the full buffer
  • g replaces all matches per line, and e suppresses "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 | update if 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

Next

How do I copy a register to another register while preserving its character/line/block type?