Triggering supertab on dot (and also Tab) - vim

i'm looking for a way to trigger SuperTab when writing a . (dot) in insert mode. I came up with something like this:
inoremap <buffer> . .<C-x><C-o>
But this just triggers Omnicompletion and not SuperTab. I want it to trigger SuperTab so I have my SuperTab configuration (preselect first entry, autoclose preview window).
Also I still want my normal SuperTab binding (which is Tab).
This could probably be solved by simulating a keypress (while in insert mode), but I just cant get it working.
inoremap <buffer> . .<Tab>
Just inserts a literal tab.
Any hints?
Thanks!

inoremap means exactly:
:ino[remap] {lhs} {rhs}
Map the key sequence {lhs} to {rhs} for the modes
where the map command applies. Disallow mapping of
{rhs}, to avoid nested and recursive mappings.
Have you tried:
:imap . .<tab>
?

Related

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.

Conflict between tab to insert spaces and superTab

I have conflict right now so that whenever I want to insert a tab (2 spaces since I have set expandtab in .vimrc) I get list options. Currently Im trying to make a mapping
inoremap <C-tab> <C-v-tab>
But this does not work. What am I doing wrong?
If you want to have an alternative mapping for the <Tab> key, that's
inoremap <C-Tab> <Tab>
The noremap part automatically ensures that SuperTab's mappings don't apply, and you get the built-in functionality.
Yours didn't work because of the invalid key notation, Ctrl + V followed by Tab would be (here with :imap to offer a worse alternative):
imap <C-Tab> <C-v><Tab>

Vim: overloaded mapping for multiple modes

I use mappings to normal mode commands that I'd also like to work in insert mode. This can be done by adding <C-o> to insert mode mapping:
nmap <C-Up> 10<Up>
imap <C-Up> <C-o>10<Up>
But this means repeating each mapping twice.
To avoid repetition, I've tried to "overload" some other key, then use it for mode-specific part:
" F12 selects prefix suitable for current mode
nmap <F12> <Nop>
imap <F12> <C-o>
" single mapping relying on "overloaded" F12
map <C-Up> <F12>10<Up>
For some reason, it doesn't work. F2 in insert mode just inserts <F2> as text.
Any idea what's wrong and how to fix it?
Bonus points if you can extend the solution to visual mode.
As ZyX has already pointed out, there is no single :map command for all modes, because it mostly doesn't make sense. If you really want to define a mapping for all modes, use both :map and :map!; see :help map-modes.
As you typically define mappings only once in your .vimrc, I would not worry too much about the little duplication, but if you do, you can use a wrapper function to avoid this:
function! MapBoth(keys, rhs)
execute 'nmap' a:keys a:rhs
execute 'imap' a:keys '<C-o>' . a:rhs
endfunction
call MapBoth('<C-Up>', '10<Up>')
Original
nnoremap <F2> :w<CR>
inoremap <F2> <Esc>:w<CR>a
map sometimes does not set it for all modes. I don't know the exact reason, so to be sure I like to explicitly set all mapping in my configuration file. I suggest that you do the same as there are cases where you can get something unexpected due to different modes. That's why it is important to consider every remapping that you do for each particular mode with care.
In addition, favor *noremap command instead of just *map everywhere you can as recursive mapping is a known source of errors, especially for beginners.
Lastly, I don't know what are you trying to achieve by binding writing of a file in visual mode. Are you aiming for partial buffer writing (it's when you selected something in visual mode, then hit this file-writing shortcut and only selected text is written)? Or do you want the whole file to be written when you are in visual mode, regardless of whether you selected anything or not when you hit the file-writing shortcut? Provide more information on that. Personally, in either case it is weird mapping for visual mode, as it is really not indented for that. It's rather better to keep such stuff in normal mode.
Update
As others have already given exhaustive answers on your question, I just thought that it would be helpful if add my 2 cents, but in slightly different direction. By looking on what you are trying to do, namely mapping navigation features involving arrow keys in insert mode, I can infer that you are very new to Vim. As you probably already know, the philosophy behind Vim is that you should never ever touch mouse during your work inside Vim - call it a kind of golden rule.
What I want to point out now, is what I call a silver rule, and it basically looks like this:
noremap <Up> <Nop>
noremap <Down> <Nop>
noremap <Left> <Nop>
noremap <Right> <Nop>
inoremap <Up> <Nop>
inoremap <Down> <Nop>
inoremap <Left> <Nop>
inoremap <Right> <Nop>
In other words, prevent yourself from using arrow keys (everywhere except command-line mode). Your fingers should always be only in the region of character keys. Vim is all about modes. Insert mode is not for navigation - it is intended for bursts of typing. When you work with code or just text (doesn't matter) you spend most of your time in normal mode - navigating - looking through the file, seeking where to land next in order to edit something, add something, i.e. to do your next input burst for which you switch to insert mode, and when you are finished you switch back to normal mode to look for some more meat - like a predator. :)
So what is it all about? I just want to head you to the right direction right from the beginning. This way you can become intermediate Vim user very quickly - just a few days. In order to get better feeling of all the aforementioned I suggest that you should definitely watch Vim Novice Video Tutorials by Derek Wyatt where he talks about all that stuff in more detail and shows it in action in the screencasts. There are also Intermediate and Advanced tutorials by him which you might also look when you are comfortable with the basics.
I wish you happy vimming! :)
There are no commands to define mappings for all modes: :map maps for normal, operator-pending and visual modes (really visual and select at once) which is clearly stated in documentation. It does not make any sense to have same mapping for all modes, though unlike movement ones saving may be done in all modes with exactly the same rhs:
function s:Save()
update
return ''
endfunction
noremap <expr> <F2> <SID>Save()
noremap! <expr> <F2> <SID>Save()
. noremap! is another multi-mode mapping command, it covers insert and command mode now. You can’t move the cursor from <SID>Save() function (textlock) thus this method is not applicable for cursor movement commands, but you can use variables in order not to repeat the same thing twice:
let s:tendownlhs='10j'
execute ' noremap <C-Down> '.s:tendownlhs
execute 'inoremap <C-Down> <C-o>'.s:tendownlhs
. Now without command mode as this is tricky and likely useless.
If it is okay for the mapping to end up in normal mode, you could combine a for loop with <C-\><C-n> mappings. <C-\><C-n> switches from any mode to normal mode.
For example, this allows switching panes with Alt-{h,j,k,l} from any mode:
for map_command in ['noremap', 'noremap!', 'tnoremap']
execute map_command . ' <silent> <M-h> <C-\><C-n><C-w>h'
execute map_command . ' <silent> <M-j> <C-\><C-n><C-w>j'
execute map_command . ' <silent> <M-k> <C-\><C-n><C-w>k'
execute map_command . ' <silent> <M-l> <C-\><C-n><C-w>l'
endfor
noremap maps in Normal, Visual, and Operator-pending mode
noremap! maps in Insert and Command mode
tnoremap maps in Neovim's Terminal mode

What's the meaning of 'inoremap' in vimrc

There is a line below in vimrc example file
inoremap Ctrl-u Ctrl-G u Ctrl-u
What's the meaning of inoremap and what's the function of this line?
For more on why the command has such a bizarre name see this excellent description between the difference between map and noremap. Really good to know!
To summarise that article, here's a choice quote:
One downside of the *map commands is the danger of recursing...
Vim offers another set of mapping commands that will not take mappings
into account when they perform their actions.
So noremap came about to avoid horrible recursion of mappings like
:nmap dd O<esc>jddk
where the dd in the right-hand side of the map recurses back to the left-hand side definition of the map, and Vim gets stuck in an infinite loop!
The vim :help inoremap is very poetic about this:
:ino[remap] {lhs} {rhs} mapmode-i :ino :inoremap
:ln[oremap] {lhs} {rhs} mapmode-l :ln :lnoremap
:cno[remap] {lhs} {rhs} mapmode-c :cno :cnoremap
Map the key sequence {lhs} to {rhs} for the modes
where the map command applies. Disallow mapping of
{rhs}, to avoid nested and recursive mappings. Often
used to redefine a command. {not in Vi}
Thus it makes some insert-mode mappings for ^U that show the filename (^G, undo the most recent change (u), and scrolls the buffer upwards by half a screen (^U).
I have no idea why someone would want this specific sequence of commands, except to demonstrate the inoremap feature -- the ^U at the refers to the meaning the command had when the definition was created, rather than calling back into the redefined ^U mapping.
I also wondered about this. See http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-Tutorial(Part_1)#Insert_mode_maps :
Insert mode maps
To map keys that work only in the insert and replace modes, use the 'imap' or 'inoremap' command.
Example: The following command maps to insert the directory name of the current buffer:
:inoremap <F2> <C-R>=expand('%:p:h')<CR>
To display the currently defined insert mode maps, use the 'imap' command without any argument:
:imap
To remove a keymap from insert mode, use the ':iunmap' command. For example, the following command removes the insert mode map for .
:iunmap <F2>
As printable keys insert a character in the current buffer in insert mode, you should use non-printable keys to create insert mode maps. Some examples for non-printable keys include the function keys , keys prefixed with the Ctrl or Alt key.
[snip]
So, for example, in my ~/.vimrc I have
inoremap jk <ESC>
inoremap jj <Esc>
which when pressed in Insert mode return me to Normal mode.

Custom keys with NERDComment plugin and remapped Leader?

I'm trying to set up the NERDComment plugin in vim, but I'm having some trouble with the keys. I'd like to set the basic toggle functionality (comment a line if it's uncommented, uncomment if it's commented) to be c. The problem is that I've remapped the Leader to be ,, which is the same key that NERD wants for all of it's hotkeys. Anyone have any idea as to how to set this up?
Just call NERDComment function in your mapping. For example, my mapping to comment the current line:
inoremap ,c <C-o>:call NERDComment(0,"toggle")<C-m>
Here's a breakdown of how this vim remap works.
The i in inoremap means that the remap only applies in insert mode.
The noremap means that the remap can't be overridden later in your .vimrc file by accident, or by a plugin.
The ,c is the key combination that triggers the key map.
The <C-o> temporarily takes you out of insert mode for one command, so the next section of the remap can call the NERDComment function.
The :call NERDComment(0,"toggle") is the NERDComment function being called.
Then <C-m> is another way of saying carriage return, which executes the command.
If you want the comment shortcut to work in normal mode and visual mode, but not in insert mode where it might do something weird when you try to type a comma, you can use the following remaps:
nnoremap ,c :call NERDComment(0,"toggle")<CR>
vnoremap ,c :call NERDComment(0,"toggle")<CR>
documented method of remapping key is located here:
remapping documentation
reference
map <leader>d <Plug>NERDCommenterToggle
"silently rejects remap will not work
nnoremap <leader>d <Plug>NERDCommenterToggle
I fell into the pitfall of attempting to use "nnoremap" to remap on my first attempt resulting in unresponsive mapping. You must use "map", "nmap", etc to properly remap the function
:map <C-z> <plug>NERDCommenterToggle
Maps 'toggle comments' to ctrl+z

Resources