Friday, January 8, 2010

Re: Is there a way to predefine search patterns?

lessthanideal wrote:
> What's a good way to predefine commonly used but complex search
> patterns so they can be quickly invoked? I'm sure this is a common
> requirement but I can't find anything searching around.
>
> Specific example: I often want to search for IP addresses in files, so
> I'll search like this:
>
> /\([0-9]\{1,3}\.\)\{3}[0-9]\{1,3}
>
> The best solution I've come up with is
>
> :nmap /ip /\([0-9]\{1,3}\.\)\{3}[0-9]\{1,3}
>
> but if I'm too slow to type it gives up and works as the literal
> command /ip. (Actually that might be quite useful in some
> circumstances.) I don't want to change the general timeout time just
> for this case. "ip" is trivial to type but I'm thinking of the more
> general case of defining long pattern names.
>
> I was thinking I'd be able to configure patterns somewhere so I could
> do something like the below command (following character class
> syntax), but I can't find a way to do it.
>
> /[:ip:]

Several ideas come to mind:

1) your timeout problem seems to be with how long it takes you to
type the mapping (the three characters "/ip"), so you can choose
a single key like <f4> and get the same results:

:nnoremap <f4> /ip /\([0-9]\{1,3}\.\)\{3}[0-9]\{1,3}<cr>

(I'm lazy and would have it hit enter for me too)

2) you can assign to the search register, so you can store
patterns however you like (say, in variables) and then
assign+search for them as you need. Untested but should be right
except possibly for "\" escaping levels:

:let ip_pattern='\([0-9]\{1,3}\.\)\{3}[0-9]\{1,3}'
:let other_pattern='...'
:let @/=ip_pattern
n

That's more helpful for scripts, but not as useful for general use.

3) you can pull any stored variable into your current search with
control+R followed by "=expression<cr>", so you can do something like

:let ip='\([0-9]\{1,3}\.\)\{3}[0-9]\{1,3}'
/<c-r>=ip<cr>

to pull in the value of "ip" as part of the search. You can even
combine #2 and #3 to make sure that you get the regexp you want
without messing with esccapes:

/\([0-9]\{1,3}\.\)\{3}[0-9]\{1,3}
:let ip=@/
[do stuff that loses the current search]
/<c-r>=ip<cr>

4) you can always go back/forward through your search history if
it's been recently executed with control+P/control+N, or bring up
the history command-window with control-F after you've typed the
"/" (or with q/ in normal mode). You can then select the one
you want, optionally modify it if you need, and then hit <enter>
to execute that search.

For more info, you can read at

:help @/
:help quote_/
:help c_CTRL-R
:help c_CTRL-P
:help cmdwin

Hope this helps,

-tim

No comments: