What does TAB do in vim? - vim

I normally don't write tabs, so I mapped <TAB> to <ESC> in insert mode so that it's faster to leave insert mode. However, when I accidentally press TAB in normal mode, it jumps to some location in the file, without saving the jump location. I first suspected that a plugin is doing that, but I find no mapping for TAB in normal mode. Even explicitly unmapping it doesn't help, so it must be a built-in command. What does it do, why isn't this jump saved to history, and how do I disable it?

You're seeing the built-in :help CTRL-I; <C-I> and <Tab> are the same in (G)Vim. That command is the opposite of <C-O>; it goes to a newer position in the jump list. You don't see the "saving to history", because it operates on existing jumps.
If you don't want any action on Tab in normal mode, just put
:nnoremap <Tab> <Nop>
into your ~/.vimrc; :help <Nop>.

What does it do, why isn't this jump saved to history, and how do I disable it?
"Tab" (or <C-I>, which is really the same thing) goes forward through the jumplist ("undo" for <C-O>), so it's either no-op, or still there's nothing to save ;-) To see the embedded help topic use :h <tab>
If you really want to disable it, just remap it:
nnoremap <tab> <nop>

Related

How to disable vim built-in keyword autocompletion?

It's quite often that I accidentally hit Ctrl-P when I want to hit Ctrl-[ for esc from insert mode on my Macbook Pro which has no physical esc key. Then vim's keyword autocomplete menu will popup and insert some gibberish in my file. It's simply annoying. How do I disable vim's built-in keyword autocompletion? Thanks a lot.
To disable ctrl-p in insert mode, the following line can be added to your .vimrc, which maps ctrl-p to a no-op with inoremap. More details on that command are available with :help inoremap (or on a prior Stack Overflow question).
inoremap <c-p> <nop>
If you'd prefer to remap ctrl-p to ctrl-[—as you've specified that as your intended keypress—the following can alternatively be added to your .vimrc.
inoremap <c-p> <c-[>
In either case, you'll still be able to access Vim's completion functionality with ctrl-n, although this works differently than ctrl-p, as it searches for the next match as opposed to the previous match.

Adding to mapping rather than completely remapping

I'm working on a plugin to allow bracket completion (I know it's available, it's more of a learning exercise). To properly implement it, I need to add to the backspace mapping. However, as it's an important key, I'd rather keep the existing functionality and just add to it rather than reimplementing the functionality. The steps would basically be when in insert mode and press backspace, execute the original backspace key, then check for some conditions and maybe remove more characters.
I've tried something like imap <backspace> <backspace><call_func_here>, but that doesn't seem to work. Again, I know I could remap backspace to just the function and try to recreate the backspace functionality, but I'd prefer to not do that.
Is this possible in vim?
I think what you are trying to do is the following:
inoremap <silent> <BS> <BS><C-o>:call MyFunction()<CR>
inoremap allows to create a non recurrent mapping in insert mode (it is often a good idea to use nore in your mappings). :h :inoremap
<silent> precise that the mapping will not be echoed on the command line (You will not see :call MyFunction() in the command line) :h :map-silent
<BS> is the reference to the backspace key that you want to remap.
The second <BS> is here to issue a backspace in insert mode
<C-o> switches to normal mode for only a command. :h i_CTRL-O
:call MyFunction() is the call to your function the way you would do it in normal mode.
<CR> correspond to the Enter key which validate the call to your function.

Assigning save (:w<cr>) to <leader>w in vim

I want to be able to save a file in vim while in the insert mode. I thought of using the following shortcut:
inoremap <leader>w <Esc>:w<cr>
While the shortcut saves the file in the insert mode, it leaves the cursor one spot ahead of where the cursor would be if I physically typed out the keys
Esc :w followed by Enter. This is a problem because when I use the shortcut whenever I am at the end of a line, it takes me to the next line, and I have to then come back to the spot where I initiated the save.
Any help would be appreciated on how I can map <leader>w to the exact actions that occur in Vim when I physically type out the Esc :w followed by Enter key sequence.
I should add that if I instead use the following key-mapping, things work exactly as I want:
inoremap <C-s> <esc>:w<CR>
However, I would like to avoid pressing CTRL and s at the same time. It is possible there is some problem with the <leader>, but I cannot figure out what it is (I am using , as my leader key).
Though one could discuss the suitability of your insert-mode mapping, the root cause of your problem is a trailing space in the mapping definition; i.e. Vim reads this as follows:
inoremap <leader>w <Esc>:w<cr><Space>
You'll even see this in the :imap <Leader>w output! <Space> in normal mode advances the cursor one to the right (like l); that explains the unexpected move.
Try this instead:
inoremap <silent> <leader>w <C-o>:w<CR>
The idea is Ctrl-o can be used to run commands directly from insert mode. See :help i_CTRL-O for details.
Why not simply doing
inoremap <leader>w <Esc>h:w<cr>
(not the additional h for going back one character)?

Create a command in vim for all modes

If I want to remap <C-s> to :w<CR> I'd have to do something like this
nnoremap <C-s> :w<CR>
inoremap <C-s> <Esc>:w<CR>
since insert mode would requre escaping to normal mode before entering the command (sure, another <Esc> wouldn't kill anything, but it's ugly, my terminal bell goes off and with all the other modes available [n, i, v, s, x, c and o] there are plenty of cases where extra <Esc> wouldn't cut it).
Is there an easy way to map a command "for all modes" in Vim?
You can get quite close by taking advantage of the CTRL-\ CTRL-N command. CTRL-\ CTRL-N goes to Normal mode from any mode.
We can define just two mappings with identical right-hand side to cover Normal, Visual, Select, Operator-pending, Insert, and Command-line mode.
noremap <C-S> <C-\><C-N>:write<CR>
noremap! <C-S> <C-\><C-N>:write<CR>
See :h CTRL-\_CTRL-N.
There is no easy "One mapping to rule them all" way to do such a thing. On the plus side when you do make all your mappings you put them in your ~/.vimrc and forget about it.
However I must say it is the Vim Way to do a save from normal mode (as a matter a fact do most thing from normal mode). If you did it form insert mode for example you would be breaking up your undo block if you wanted to exit from insert mode, save, and then reinsert insert mode (See :h i_Ctrl-o). Not to mention such a mapping may affect the . command which is super handy.
You may also want to avoid the <c-s> key on the terminal because it will often trigger terminal's software flow control (XON/XOFF). You can disable this for your terminal by using stty -ixon.

vim jump forward with <c-i> doesn't work for me too (snipmate)

I have the same problem as many others users. Jump back <C-o> works, but jump forward don't.
I read same questions and answers but don't get any result.
I try :verbose map <C-I> command and get this:
How to disable snipmate mappings?
First, if that isn't clear to you, <C-i> is the same as <Tab>; unfortunately, you cannot map them separately.
You screenshot shows that snipMate has grabbed <C-i> in visual and select mode; it needs those mappings to jump to the next snippet tab stop. You can change that by editing the snipMate file, but these mappings do not interfere with the normal-mode <C-i> mapping that you're concerned about.
In normal mode, you've remapped <C-i> / <Tab> to gt in your .vimrc; you need to re-assign or remove that to get back the original <C-i> command.

Resources