limit search scope

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

limit search scope

William Pursell
I often would like to limit the scope of a search (for example,
searching for a variable name only in the current code block.)
I'm wondering if there's an easy way to tie that to a syntax block,
or something.  Really, I'm looking for ideas to improve the following
function, which requires that I explicitely set g:limit to the line
that I don't want to search past.

function! Search(...)
    if a:0 > 0
        let g:target_string = a:1
    else
        let g:target_string = g:target_string
    endif
    let previous_line= line(".")
    let previous_col  = col(".")
    call search(g:target_string)
    if line(".") > g:limit
        call cursor(previous_line,previous_col)
    endif
endfunction



Reply | Threaded
Open this post in threaded view
|

Re: limit search scope

Tim Chase-2
> I often would like to limit the scope of a search (for example,
> searching for a variable name only in the current code block.)

While it may not be quite what you're looking for, the solution I often
use is to just highlight the range in question (say, with "vip" or
"viB") and then do

        :'<,'>g/searchRegexp/#

This will return each line in the selected range, along with its line
number.  You can then just jump to the returned line number(s) of
interest by typing the line number followed by "G".  As long as you
don't change the contents of the command line, you can then get that
list back again by using

        @:

(see ":help @:" for more on reissuing the last command [*])

You might also tweak your expression using the \%>l and \%<l operators
(those are "ell"s, not "one"s), as described in

        :help /\%l

(again, an "ell", rather than a "one") which, if you know the line
numbers, allow you to specify that your matches can only occur within a
certain range of lines, such as

        /\%>25l\%<50lMyRegexp

will find "MyRegexp" on lines 26..49 (or is it 25..50, darn off-by ones)

Just a few ideas.

-tim

[*] if your expression has any control characters entered using ^V, they
can cause trouble here.  I understand Bram fixed this in Vim7.



Reply | Threaded
Open this post in threaded view
|

Re: limit search scope

Charles E Campbell Jr
In reply to this post by William Pursell
bill wrote:

> I often would like to limit the scope of a search (for example,
> searching for a variable name only in the current code block.)
> I'm wondering if there's an easy way to tie that to a syntax block,
> or something.  Really, I'm looking for ideas to improve the following
> function, which requires that I explicitely set g:limit to the line
> that I don't want to search past.
>
> function! Search(...)
>    if a:0 > 0
>        let g:target_string = a:1
>    else
>        let g:target_string = g:target_string
>    endif
>    let previous_line= line(".")
>    let previous_col  = col(".")
>    call search(g:target_string)
>    if line(".") > g:limit
>        call cursor(previous_line,previous_col)
>    endif
> endfunction
>
Hello!

I have a plugin that will do that!   You'll find it at my website,
http://mysite.verizon.net/astronaut/index.html#VimFuncs
(see "funcsrch.vim" -- its alphabetically arranged).

The help for it addresses vim's functions in particular.  The
function limits the search to a code block whose extents
may be determined by [[ (for top-of-block) to ][ (for bottom
of block).  The help for funcsrch which will set up those
maps for vim (and ]] and [], too).  The idea is to put those
maps into .vim/ftplugin/vim.vim  (or .vim/ftplugin/vim/vim.vim).

Thus they'll take effect only when you're editing vim scripts.

Funcsrch itself provides two commands:

:FS pattern
:FSB pattern

:FS searches forward, and FSB searches backwards.

Regards,
Chip Campbell


Reply | Threaded
Open this post in threaded view
|

Re: limit search scope

William Pursell
Charles E. Campbell, Jr. wrote:

> bill wrote:
>
>> I often would like to limit the scope of a search (for example,
>> searching for a variable name only in the current code block.)
>
>
>
> I have a plugin that will do that!   You'll find it at my website,
> http://mysite.verizon.net/astronaut/index.html#VimFuncs
> (see "funcsrch.vim" -- its alphabetically arranged).
>
That works very nicely!  Thanks.  I have a question (below)
about  the following modification that allows
 :FS with no arguments to search for the previously
sought string.

com! -nargs=? FS  call s:FuncSrch(1,<f-args>)
com! -nargs=? FSB call s:FuncSrch(2,<f-args>)

" ---------------------------------------------------------------------
" FuncSrch: {{{1
fun! s:FuncSrch(dir,...)
"  call Dfunc("FuncSrch(dir=".a:dir." pat<".a:pat.">)")
    if a:0 > 0
        let pat=a:1
    else
        let pat= g:previous_pattern
    endif
    let g:previous_pattern = pat
  let swp      = SaveWinPosn()
...

I'm curious to know if there's a better way to maintain the
previous search pattern  (eg. a static variable for the function).  I
don't like cluttering the global namespace.  Does vimscript
provide support for doing that sort of thing cleanly?

Reply | Threaded
Open this post in threaded view
|

Re: limit search scope

William Pursell
In reply to this post by Charles E Campbell Jr
Charles E. Campbell, Jr. wrote:

> bill wrote:
>
>> I often would like to limit the scope of a search (for example,
>> searching for a variable name only in the current code block.)
>>
>> <snip>
>> I have a plugin that will do that!   You'll find it at my website,
>
<snip>

I've added the following lines to my .vimrc, attempting to
map '/' and 'n' to your function, relying on the global variable
limit_search_scope to either call the limiting function, or the
normal search function.  It doesn't quite work right, and I'm hoping
someone can shed light on it.  Here's what's in my .vimrc:

nmap / :call Search(1)<cr>
nmap n :call Search(0)<cr>

function! Search(prompt_needed)
    if g:limit_search_scope == 1
        if a:prompt_needed
            let @/ = input('FS/')
        endif
        normal :FS
    else
        if a:prompt_needed
            let @/ = input('/')
        endif
        call search(@/)
    endif
endfunction

(note that I'm using a modified version of Chip's function which
searches for @/ if no argument is passed)
This works very well, except that 'n' doesn't.  I can
use / with a limited search and @/ gets set properly, at which
point I can use the mapping with 'n' if g:limit_search_scope
is not set, and I can do ':FS' to get the repeated limited search to
happen, but
the mapping 'n' fails if the search is limited.  Can anyone explain why
it fails?
(If g:limit_search_scope
is set and I do 'n', absolutely nothing (seems to) happen).