[Red] Block cookies [Red] Block scripts [Red] Block ads [Red] Block images [Red] Block referrer




vim online home |  news |  scripts |  tips |  support |  search |  account |  links |  huh? Vim Book Ad

basic Tip #102: smart mapping for tab completion

tip karma Rating 258/84, Viewed by 3346

created August 21, 2001 12:17 complexity basic
author benoit.cerrina@writeme.com as of 6.0

I'm used to complete words with <tab>, however when editing source I can't just map that to vim keyword completion because I sometime need to insert real tabs,
since it mostly happen when at the beginning of the line or after a ; and before a one line comma (java, c++ or perl anyone...) I've come to find the following really usefull
This is how you can map the <tab> key in insert mode while still being able to use it when at the start of a line or when the preceding char is not a keyword character.
in a script file in a plugin directory or in your .vimrc file:
first define a function which returns a <tab> or a <C-N> depending on the context:

function InsertTabWrapper()
      let col = col('.') - 1
      if !col || getline('.')[col - 1] !~ '\k'
          return "\<tab>"
      else
          return "\<c-p>"
      endif
endfunction

then define the appropriate mapping:
inoremap <tab> <c-r>=InsertTabWrapper()<cr>

the trick here is the use of the <c-r>= in insert mode to be able to call your function without leaving insert mode.
:help i_CTRL-R
Benoit

rate this tip Life Changing Helpful Unfulfilling 
<<Change automatically to the directory the file in the current buffer is in | Move to next/previous line with same indentation >>

Additional Notes

igor@tyumbit.ru, August 26, 2001 2:01
WOW!
I've wanted this for year and now i've got it!
Thanks for the tip!
anon@xyz.com, September 2, 2001 1:23
This is pretty cool. How would we simulate ^X^N, I wonder...
octorock@doubtful.com, September 5, 2001 17:56
this is wonderful.  however it would be helpful if it could be made to cycle through all completions like a proper ctrl-p would.
octorock@doubtful.com, September 5, 2001 20:33
i'm a giant fool.  nevermind.  (when i copied and pasted the snippet, it left trailing whitespace characters.)

thank you for such a killer tip.
Anonymous, September 6, 2001 10:50
With a minor addition you can also go in either direction:

function! InsertTabWrapper(direction)
    let col = col('.') - 1
    if !col || getline('.')[col - 1] !~ '\k'
        return "\<tab>"
    elseif "backward" == a:direction
        return "\<c-p>"
    else
        return "\<c-n>"
    endif
endfunction

inoremap <tab> <c-r>=InsertTabWrapper ("forward")<cr>
inoremap <s-tab> <c-r>=InsertTabWrapper ("backward")<cr>


benoit.cerrina@writeme.com, September 25, 2001 19:42
Anonymous,
Good, actually in my setting I had define two wrappers for tab and shift tab effectively achieving the same effect.
By the way I made a mistake in my orginal e-mail, it is .com not .fr
Benoit
Anonymous, December 9, 2001 23:52
This tip is great. But,  when type in 'tab' , it will have a additional space. How to fix it ? thanks.
lee@dashf.com, January 16, 2002 9:45
this tip truly does kick ass.
mayureshk@aftek.com, January 24, 2002 23:38
This is freaking fabulous. Thankx man !! Its way too cool. i too, have been searching for this for quite some time now. Kudos !
kgergely@mcl.hu, April 9, 2002 10:30
See also vimscript#182.
It is a complete system, and the completion remembers the completion mode!
anon, April 29, 2002 22:10
This tip is absolutely fantastic.  In response to the
problem of a space after hitting tab, there is most likely a
space after the line

inoremap <tab> <c-r>=InsertTabWrapper()<cr>

In your vimscript, remove this and you should be fine
anon, May 22, 2002 10:17
Darned space!


Questions about this site should go to vimonline-support@lists.sourceforge.net.
Questions about vim should go to vim@vim.org after searching the archive. Help Bram help Uganda. Please use this site responsibly.
SourceForge Logo