Repeatedly adding new terms to the existing search pattern

22 views
Skip to first unread message

lessthanideal

unread,
Nov 8, 2012, 1:11:29 PM11/8/12
to vim...@googlegroups.com
I want to add more terms to the existing search pattern. *
picks up the word at the cursor and searches on it. I want
to pick up the word, add its pattern to the existing
pattern, and so search on both. Then I want to repeat the
operation to search on all three words, etc.

I've ended up with a complicated mapping which uses * to get
the word so it becomes the last item in the search history; adds
the last item to the one before it and assigns this value to
the search register; finally adds the search register contents
back into the history:

nnoremap £ *:let @/=histget("/",-2) . '\\|' . histget("/",-1)<CR>:call histadd("/",@/)<CR>

This works fine but I'm just wondering if I'm missing
something much simpler? Can anyone comment?

It's just out of interest since this solution works (so far :)

regards,
Geoff

More details about how I got to this point...

I started out thinking the search register and the last item
in the history were the same thing, but they're not. Here's
some other simpler likely mappings I tried:

This works to combine last two items in the search register
and does a search, but doesn't change history, so the
changes don't build up.
nnoremap £ *:let @/=histget("/",-2) . '\\|' . histget("/",-1)<CR>

This may be as expected, I'm not sure. It's discussed in
':help history' but it's a bit obscure to me:

"All searches are put in the search history, including the
ones that come from commands like "*" and "#". But for a
mapping, only the last search is remembered (to avoid that
long mappings trash the history)".

------
This combines last two items in history so the last item in
the history is as I expect, but the search register doesn't
change:
nnoremap £ *:call histadd("/", histget("/",-2) . '\\|' . histget("/",-1))<CR>

------
This does an actual search on what I want, but doesn't put
the expression in history or the search register:
nnoremap £ *:call search(histget("/",-2) . '\\|' . histget("/",-1))<CR>

------
Background: For analysing log files I want to consider
individual errors then hide all the lines matching them. I
use the searchfold.vim plugin which allows me to quickly
fold away lines that match the search expression, and it
works great in itself. I press * to highlight a term, then
\iz to fold matching lines away.

When I see another error, I have to manually get its pattern
and add it to the search register. I do this by pressing *
on it, then type /, 'up' twice the previous pattern, '\|'
then 'Ctrl-R/' to append the new search to the previous
one.

Tim Chase

unread,
Nov 8, 2012, 2:04:45 PM11/8/12
to vim...@googlegroups.com, lessthanideal
> When I see another error, I have to manually get its pattern and
> add it to the search register. I do this by pressing * on it,
> then type /, 'up' twice the previous pattern, '\|' then 'Ctrl-R/'
> to append the new search to the previous one.

Am I missing something, or would the following do roughly what you
describe:

:nnoremap £ /<c-r>/<bslash><bar><c-r><c-w><cr>

or possibly

:nnoremap £ /<c-r>/<bslash><bar><bslash><lt><c-r><c-w><bslash>><cr>

(note the double ">" in the last "<bslash>>")

It sounds like you were mostly there with this solution you almost
relegate to a footnote. The only downside I see would be if you
happened to have a literal "/" in your search pattern already (or
it's included in 'iskeyword'), it would treat it as the ending
terminator for the search (before the search flags), and cause it to
choke. In that case, you should be able to use something like

:nnoremap £ :let
@/.='<bslash><bar><bslash><lt>'.expand('<cword>').'<bslash>>'<cr>

-tim



lessthanideal

unread,
Nov 12, 2012, 9:57:29 AM11/12/12
to vim...@googlegroups.com, lessthanideal
Thanks a lot Tim! These mappings are much simpler, simply using Ctrl-R
to get the previous search value and the text beneath the cursor.

I like the second approach since the search is not actually made so
the cursor does not move, but it does mean search highlighting
is not turned on, which I found I missed.

I also realised I use this plugin to make * search on whatever
is highlighted in Visual Mode: http://vim.wikia.com/wiki/VimTip171

So putting it all together these are the mappings I've got now:

nnoremap £ :let @/.='<bslash><bar><bslash><lt>'.expand('<cword>').'<bslash>>'<cr>:set hls<cr>
vnoremap £ <esc>:let @/.='<bslash><bar>'.@*<cr>:set hls<cr>

The Visual one relies on the * register being populated with
visual selections, i.e. having 'guioptions' include 'a'.

regards,
Geoff
Reply all
Reply to author
Forward
0 new messages