Vim 在 C/C++ 代码行中搜索 [英] Vim search in C/C++ code lines

查看:32
本文介绍了Vim 在 C/C++ 代码行中搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在跳过注释行的同时搜索 C/C++ 源文件中的字符串?

Is there any way to search a string in a C/C++ source file while skipping commented lines?

推荐答案

这是一个有趣的问题.

我认为@sixtyfootersdude 的想法是正确的 -- 让 Vim 的语法突出显示告诉您什么是注释,什么不是,然后在非注释中搜索匹配项.

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.

让我们从一个模仿 Vim 内置 search() 例程的函数开始,但也提供了一个跳过"参数让它忽略一些匹配:

Let's start with a function that mimics Vim's built-in search() routine, but also provides a "skip" parameter to let it ignore some matches:

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) > 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

以下是一些建立在 SearchWithSkip() 之上的函数,用于实现对语法敏感的搜索:

Here are a couple of functions that build on SearchWithSkip() to implement syntax-sensitive searches:

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

以下是使语法敏感搜索功能更易于使用的命令:

Here are commands that make the syntax-sensitive search functions easier to use:

command! -nargs=+ -complete=command SearchOutside call SearchOutside(<f-args>)
command! -nargs=+ -complete=command SearchInside  call SearchInside(<f-args>)

那还有很长的路要走,但现在我们可以做这样的事情:

That was a long way to go, but now we can do stuff like this:

:SearchInside String hello

搜索 hello,但只在 Vim 认为是字符串的文本中搜索.

That searches for hello, but only within text that Vim considers a string.

并且(终于!)除了注释之外的所有地方都搜索 double :

And (finally!) this searches for double everywhere except comments:

:SearchOutside Comment double

要重复搜索,请使用 @: 宏重复执行相同的命令,例如按 n 重复搜索.

To repeat a search, use the @: macro to execute the same command repeatedly, like pressing n to repeat a search.

(顺便说一句,感谢您提出这个问题.现在我已经构建了这些例程,我希望能经常使用它们.)

(Thanks for asking this question, by the way. Now that I've built these routines, I expect to use them a lot.)

这篇关于Vim 在 C/C++ 代码行中搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆