How do I search non-greedily across multiple lines between two markers?
/\vstart\_.{-}end
Multiline searches in Vim often overmatch because .
/\vstart\_.{-}end
Multiline searches in Vim often overmatch because .
/\vTODO:\s*\zs.{-}\ze\s*($|#)
When TODO comments include prefixes, owners, or trailing metadata, a plain search often lands on the wrong part of the line.
/foo\@<!bar
Vim regex supports zero-width assertions, so you can match text based on context without consuming the context itself.
/\%>20l\%<40lTODO
Vim's search engine can constrain matches by line number, which is useful when you want to scan a known section without touching the rest of the buffer.
:execute 'vimgrep /' . @/ . '/gj **/*'
If you already refined a search interactively with / or ?, retyping that pattern for project-wide grep is repetitive and error-prone.
:lgrep /pattern/ % | lopen
Quickfix is global, but sometimes you want a narrower search workspace tied to one window.
/\v<(TODO|FIXME|BUG)>
When you triage code, jumping among TODO, FIXME, and BUG markers quickly is often more useful than searching each token separately.
:let @/ = '\V' . escape(expand('<cword>'), '\')
This pattern lets you prepare a precise search target without jumping the cursor or triggering an immediate search motion.
:let @/ = '\V' .. escape(expand('<cword>'), '\\')
Sometimes * is too opinionated: it uses keyword boundaries and interprets regex metacharacters.
:lvimgrep /\<TODO\>/gj **/* | lopen
If you want project-wide search results without polluting the global quickfix list, use a location list.
*Ndgn
When you are reviewing repetitive text, you often need to remove one specific match without running a broad substitute.
:lvimgrep /TODO/j **/* | lopen\<CR>
When you are working in multiple windows, quickfix can become noisy because it is shared globally across the editor session.
:lvimgrep /pattern/j **/* | lopen
Quickfix is great, but it is global.
:lvimgrepadd /pattern/gj **/*
When investigating a bug or refactor, you often need to gather results from several related patterns before deciding what to edit.
:vimgrep /{pattern}/j **/*
For project-wide searches, :vimgrep is powerful but can feel disruptive if it jumps into files while populating quickfix.
:vimgrep /\<TODO\>/gj **/*.lua | copen
When you want a project-wide TODO pass without leaving Vim, :vimgrep plus quickfix is a strong built-in workflow.
search #search #quickfix #command-line #project-navigation #ex-commands
:vimgrep /pattern/j **/*<CR>:copen<CR>
When you need a project-wide search but do not want to leave Vim, :vimgrep gives you a built-in grep workflow with navigation, filtering, and batch editing thro
search #search #quickfix #vimgrep #project-workflow #command-line
:set shortmess+=S
Vim's search count feedback ([3/27]) is useful until it starts flooding the command area during rapid navigation.
:%s/\vfoo\zsbar/baz/g
When your match has a stable prefix but you only want to replace the trailing segment, \zs is often cleaner than introducing extra capture groups.
/pattern/e+1<CR>
Most Vim searches place the cursor at the start of the match.