Friday, September 12, 2008

Question: Highlight From Insert?

Iyo writes:

"I offten do some coding in Vim and I miss an feature that will highlight
the word I`m writing in that moment and other same words. (It is mainly
for variables - sometimes I switched letters and afterwards I`m looking
for mistake for a quite long time. The NetBeans IDE has a feature like this.

I know about * but it`s for search in the text. I`m looking for something that work automaticly in insert mode."


You can use ctrl-o from inside of insert mode to enter a command, but to me typing ctrl-o * while I'm hammering out some code feels awfully cumbersome. There's also the negative side-effect that * jumps forward, so you'd lose cursor position, which would assuredly interrupt workflow. Instead, I'd just define a simple mapping along the lines of the following.

imap <F2> <Esc>#*A

So, you're inside insert mode, you just typed a word, and you want to match all occurrences. You would simply hit F2, and it would backward match the word nearest the cursor. This has the negative side effect of jumping backwards; thereby, losing cursor position. To compensate, we add a * to jump forward followed by "A" to return to insert mode and insure you're at the end of the line. Obviously, you can substitute any keybinding you want for F2.

This seems to work well on my machine; although, there might be more optimal solutions. If anybody has one, feel free to share.


Anonymous said...

You could also use a mark to make sure your cursor returns to the same place:

imap <F2> <Esc>ma#`aa

redbeard0531 said...

I have these lines in my gvimrc which do the trick when in normal mode. I use it when reading code to quickly see where a variable is used without moving my hands. If you'd like it to work in insert mode use CursorMovedI and InsertLeave. It's not perfect, but its the best i've found that doesn't slow down vim at all.

highlight Curword guibg=#334

autocmd CursorMoved * syntax clear Curword | if len(expand('<cword>')) | exe "syntax keyword Curword " . expand("<cword>") |endif

autocmd InsertEnter * syntax clear Curword

iyo said...

Thanks guys... The both solutions works, maybe redbeard0531`s one is a little bit better.

Scrooloose said...

id use gi instead of a mark. Like this:

imap <f2> <esc>*gi

You could wrap the whole thing up in a function to stop the screen from scrolling as well e.g.

imap <f3> <esc>:call HilightCWord()<cr>gi
function! HilightCWord()
  let top = line("w0") + &scrolloff
  normal! *
  call cursor(top,0)
  normal! zt

Derek Wyatt said...

There's a slightly more Vimish (?) way to do this: just set the search register to the current word. When you hit * or # you're putting something in @/, but you're also moving... so skip the movement and just stick it in @/:

imap <F2> <esc>:let @/=expand("<cword>") \| set hls<cr>a