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-1is 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