Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is an intriguing question.</p> <p>I think @sixtyfootersdude has the right idea -- let Vim's syntax highlighting tell you what's a comment and what's not, and then search for matches within the non-comments.</p> <p>Let's start with a function that mimics Vim's built-in <code>search()</code> routine, but also provides a "skip" parameter to let it ignore some matches:</p> <pre><code>function! SearchWithSkip(pattern, flags, stopline, timeout, skip) " " Returns true if a match is found for {pattern}, but ignores matches " where {skip} evaluates to false. This allows you to do nifty things " like, say, only matching outside comments, only on odd-numbered lines, " or whatever else you like. " " Mimics the built-in search() function, but adds a {skip} expression " like that available in searchpair() and searchpairpos(). " (See the Vim help on search() for details of the other parameters.) " " Note the current position, so that if there are no unskipped " matches, the cursor can be restored to this location. " let l:matchpos = getpos('.') " Loop as long as {pattern} continues to be found. " while search(a:pattern, a:flags, a:stopline, a:timeout) &gt; 0 " If {skip} is true, ignore this match and continue searching. " if eval(a:skip) continue endif " If we get here, {pattern} was found and {skip} is false, " so this is a match we don't want to ignore. Update the " match position and stop searching. " let l:matchpos = getpos('.') break endwhile " Jump to the position of the unskipped match, or to the original " position if there wasn't one. " call setpos('.', l:matchpos) endfunction </code></pre> <p>Here are a couple of functions that build on <code>SearchWithSkip()</code> to implement syntax-sensitive searches:</p> <pre><code>function! SearchOutside(synName, pattern) " " Searches for the specified pattern, but skips matches that " exist within the specified syntax region. " call SearchWithSkip(a:pattern, '', '', '', \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "' . a:synName . '"' ) endfunction function! SearchInside(synName, pattern) " " Searches for the specified pattern, but skips matches that don't " exist within the specified syntax region. " call SearchWithSkip(a:pattern, '', '', '', \ 'synIDattr(synID(line("."), col("."), 0), "name") !~? "' . a:synName . '"' ) endfunction </code></pre> <p>Here are commands that make the syntax-sensitive search functions easier to use:</p> <pre><code>command! -nargs=+ -complete=command SearchOutside call SearchOutside(&lt;f-args&gt;) command! -nargs=+ -complete=command SearchInside call SearchInside(&lt;f-args&gt;) </code></pre> <p>That was a long way to go, but now we can do stuff like this:</p> <pre><code>:SearchInside String hello </code></pre> <p>That searches for <code>hello</code>, but only within text that Vim considers a string.</p> <p>And (finally!) this searches for <code>double</code> everywhere except comments:</p> <pre><code>:SearchOutside Comment double </code></pre> <p>To repeat a search, use the <code>@:</code> macro to execute the same command repeatedly, like pressing <code>n</code> to repeat a search.</p> <p>(Thanks for asking this question, by the way. Now that I've built these routines, I expect to use them a lot.)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload