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

How do I run a substitution without displacing my marks?

Answer

:keepmarks %s/pattern/replacement/g

Explanation

The :keepmarks modifier prevents Vim from adjusting mark positions when a buffer-modifying command runs. Normally, a global substitution shifts marks on affected lines to account for inserted or deleted characters. Prefixing the command with :keepmarks freezes all marks at their original positions regardless of what the substitution changes.

How it works

  • :keepmarks is a command modifier that applies to the Ex command that follows it
  • Without it, a substitution that changes line lengths will update mark column positions to keep them on the same character
  • With it, every mark ('a, 'b, `[, `], etc.) stays at its exact line and column from before the command ran
  • This is especially valuable inside scripts, functions, or complex macros where you set marks, transform the buffer, and need marks to remain at the pre-change positions

Example

Set mark a on a line, run a substitution, then check if the mark moved:

" Without keepmarks: mark adjusts with text changes
:%s/short/a much longer replacement/g
" 'a may now point to a different column

" With keepmarks: mark stays put
:keepmarks %s/short/a much longer replacement/g
" 'a still points to the original position

Tips

  • Combine with :keepjumps to also preserve the jump list: :keepjumps keepmarks %s/.../.../g
  • Commonly used in plugin code and autoload functions that reformat buffers
  • :help :keepmarks for the full specification

Next

How do I enable matchit so % jumps between if/else/end style pairs?