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

How do I use a pattern-based range with an offset to operate on lines relative to a search match?

Answer

:/pattern/+N and :/pattern/-N

Explanation

Vim's Ex command ranges can use search patterns as line addresses, and those addresses can include a numeric offset (+N or -N) to target lines relative to the match. This makes it possible to operate on a block of code delimited by patterns without needing to know exact line numbers.

How it works

A range has the form {addr1},{addr2} where each address can be:

Form Meaning
/pattern/ Next line matching the pattern
/pattern/+N N lines after the match
/pattern/-N N lines before the match
?pattern? Previous line matching the pattern (search backward)
?pattern?+N N lines after a backward-matched pattern

These can be combined with any Ex command that accepts a range: :delete, :yank, :move, :copy, :substitute, :normal, etc.

Example

Given a file with:

// Section header
foo = 1
bar = 2
// End section

To delete everything between (and including) the two comment lines:

:/Section header/,/End section/delete

To delete only the lines inside (not the headers):

:/Section header/+1,/End section/-1delete

To yank from the current line to one line before the next }}:

:.,/^}}-1yank

Tips

  • Use . as the first address for "current line to match": :.+1,/end/delete
  • Offsets can be stacked: /pattern/+2-1 is valid (and equals /pattern/+1)
  • For searching backward, use ? instead of /: ?def ?,/^end/-1yank
  • Combine with visual-mode range marks: :'<,'> already has offsets baked in

Next

How do I highlight all occurrences of a yanked word without typing a search pattern?