How do I write an Ex range where the second address is evaluated relative to the first match instead of the cursor?
Answer
/pattern/;+3
Explanation
In Vim's range notation, a semicolon (;) between two addresses makes the second address relative to the line the first address matched, not to the current cursor position. This lets you anchor both endpoints of a range to a search result regardless of where the cursor is.
How it works
Compare the two range forms:
| Syntax | Second address is relative to |
|---|---|
/pattern/,+3 |
current cursor line |
/pattern/;+3 |
the line matched by /pattern/ |
With ;, the matched line becomes a temporary "current position" for evaluating the next address. So /pattern/;+3 means: find the next line matching pattern, then take 3 lines after that line — always a predictable 4-line block anchored to the match.
The same logic applies when the second address is another search pattern:
:/def /;/^}/ delete
This deletes from the next line containing def through the next } on its own line — searched forward from the def line, not from the cursor.
Example
Suppose your cursor is on line 5 and the pattern matches line 20:
:/error/;+2 yank a
Yanks the error line plus the two lines after it into register a, regardless of cursor position. With a comma, +2 would be relative to line 5, not line 20.
Tips
- The
;form works in macros and scripts where cursor position is unpredictable. - Chain multiple semicolons:
:/start/;/middle/;/end/ d— each search anchors to the previous result. - Use
.;/pattern/to operate from the current line to the next pattern match:.;/^}/ =auto-indents from cursor to the next closing brace.