Tip #780: Generalized VISUAL CONTENT onto COMMAND-LINE
| tip karma
Rating 68/20, Viewed by 1017
Read and edit this tip on the
Vim tip wiki.
The wiki may have a more recent version of this tip.
||September 3, 2004 19:41
||as of Vim:
Key idea: Yank the visual area for use on the command-line.
Key use: searches, complex substitutions, etc.
Refinement: Make sure all magic characters are escaped.
(Thanks to vimtip #777 for this.)
Focus on the content of the visual -- independent
of how it was formatted.
Usage: visual on the area, and hit the TAB key.
DISCUSSION: imagine searching for this line in your text:
"The price of foobars is $1.89 [see page 7]."
Typing it out literally will not work:
:/The price of foobars is $1.89 [see page 7]./
The problem is the magic characters. Escaping them will make it work:
:/The price of foobars is \$1\.89 \[see page 7\]\./
We really don't have to type it out, just use yank and the " register.
And let vim automatically figure out how to properly escape...
Now suppose elsewhere in the text we have this:
"The price of foobars
is $1.89 [see page 7]."
Will our previous command work? No. It's MULTI-LINE.
Here's what would work:
That would work even on this:
of foobars is $1.89
[see page 7]."
That's independence from formatting!
The secret is the substitution function using whitespace \_s\+
and the 'one or more' operator.
The CODE which magically puts the discussion
into action (three versions):
" Yank the " register onto the command-line.
"X- vmap <C-I> y:/<C-R>"/
" ^ plain version without escaping out of magic characters.
"X- vmap <C-I> y:/<C-R>=escape(@", '\/.*$^~')<CR>/
" ^ now more fancy.
vmap <C-I> y:/<C-R>=substitute(escape(@", '\/.*$^~'), "[ \t\n]\\+", "\\\\_s\\\\+", "g")<CR>/
" visual ^ HIGHLIGHTED text placed on the COMMAND LINE.
" Input <CR> to perform a SEARCH-,
" otherwise EDIT the COMMAND-LINE containing the yanked text.
" Function ESCAPE to prevent magic characters.
" 4-tuple function SUBSTITUTE will generalize white spaces & EOL,
" ^ so that string will be independent of formatting!
" USAGE: visual on desired area, and simply hit TAB.
" To search, follow up by carriage return.
" Else, you may modify the command line to suit your purpose.
<< OEM to ANSI conversion |
Changing the hotkey for "&Diff with Vim" >>
September 4, 2004 8:08
|Finally! I have been trying to figure this out
for 2 years. Thanks very much for adding to
visual mode toolset. Those functions are gems
in combination with vmap = visual mapping.
For a review, see
Now I can search for meaningful context without
worrying about how the text was shaped.
Even the period appearing in generic sentences
was a minor annoyance -- now solved with 'escape'.
mosh @ albany,
September 7, 2004 17:06
|Awesome, I had been asking for this since vim57 something like:
and all white spaces are treated identically as [\s\n]\+ inside regexp!
I thought of modifying the regexp engine to do it for everything
including search and replace.
September 9, 2004 15:27
|Combining this with another tip or two by Michael Naumann and JÃ¼rgen KrÃ¤mer, I now have:
" Visually select text, then search for it, forwards or backwards
vmap <silent> * :<C-U>let old_reg=@"<cr>
\escape(@", '\\/.*$^~'), "[ \t\n]\\+", '\\_s\\+', 'g')<CR><CR>
vmap <silent> # :<C-U>let old_reg=@"<cr>
\escape(@", '\\?.*$^~'), "[ \t\n]\\+", '\\_s\\+', 'g')<CR><CR>
February 25, 2006 22:37
|I use the following:
vmap <silent> * "yy:let @/='\(' . substitute( escape( @y, '$*^~\/.' ), '\_s\+', '\\_s\\+', 'g' ) . '\)'<cr>:set hls<cr>
The only thing this one does that seems to be an improvement on the example above (rather than simply being different) is the substitution for whitespace: '\_s\+' instead of '[ \t\n]\+'.
The differences between this and the example above:
- This doesn't move the cursor; it just highlights matches, allowing n to move forward and N to move back. (I like that it doesn't move the cursor. I usually just want to SEE the matches, not actually move to them.)
- It clobbers @y mercilessly. I don't use it elsewhere and haven't yet had any reason to try to save/restore it -- of course, it would be trivial to do so.
- If you don't use 'hlsearch', simply remove the last bit that sets it (simply setting @/ doesn't turn on the highlight back if :nohls was called before; this does...)