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

How do I search for a pattern that spans multiple lines?

Answer

/pattern1\_.*pattern2

Explanation

Vim's \_ modifier makes any character class match newlines too. The pattern \_.* matches any character including newlines, letting you search across line boundaries.

How it works

  • . matches any character except newline
  • \_.* matches any character including newline (zero or more times)
  • \_s matches whitespace including newlines
  • \_^ matches the start of any line (not just the first)

Examples

" Find 'function' followed by 'return' anywhere after (across lines)
/function\_.*return

" Find opening brace followed by closing brace (multi-line)
/{\_.*}

" Find empty HTML tags (across lines)
/<div>\_s*<\/div>

" Find 'if' followed by 'else' within a few lines
/if\_.*\%3lelse

Line-boundary atoms

\n     " Match a newline character in the search
\_s    " Whitespace or newline
\_^    " Start of a line (anywhere in match)
\_$    " End of a line (anywhere in match)
\_[a-z] " Character class that also matches newline

Practical example

Find Python functions with no return statement:

/def \w\+(.*)\_.*\(return\)\@!\ndef

Tips

  • Multi-line searches can be slow on large files since Vim must scan across lines
  • Use \_.\{-} for non-greedy multi-line matching (like .*? in other regex flavors)
  • Combine with \v (very magic) for cleaner syntax: /\vfunction\_.+return
  • This works in both / search and :s substitution commands

Next

How do I always access my last yanked text regardless of deletes?