Vim: overloaded display for multiple modes

I use mappings for normal mode commands, which I would also like to work in insert mode. This can be done by adding <Co> to insert the display mode:

 nmap <C-Up> 10<Up> imap <C-Up> <Co>10<Up> 

But that means repeating each display twice. To avoid repetition, I tried to “overload” another key, and then use it for the mode-specific part:

 " F12 selects prefix suitable for current mode nmap <F12> <Nop> imap <F12> <Co> " single mapping relying on "overloaded" F12 map <C-Up> <F12>10<Up> 

For some reason this does not work. F2 in insert mode just inserts <F2> as text. Any idea what is wrong and how to fix it? Bonus points if you can expand the solution to visual mode.

+6
source share
4 answers

There are no commands for determining comparisons for all modes:: :map maps for normal, operational-waiting and visual modes (really visually and immediately selected), which is clearly indicated in the documentation. It makes no sense to have the same display for all modes, although unlike movement, saving can be performed in all modes with exactly the same values:

 function s:Save() update return '' endfunction noremap <expr> <F2> <SID>Save() noremap! <expr> <F2> <SID>Save() 

. noremap! - This is another multi-mode display command, now it covers the insert and command mode. You cannot move the cursor from the <SID>Save() function (text block), therefore this method is not applicable for cursor movement commands, but you can use variables to avoid repeating the same thing twice:

 let s:tendownlhs='10j' execute ' noremap <C-Down> '.s:tendownlhs execute 'inoremap <C-Down> <Co>'.s:tendownlhs 

. Now without a command mode, since it is difficult and probably useless.

+5
source

As ZyX already pointed out, for all modes there is no single command :map , because basically it does not make sense. If you really want to define a map for all modes, use both :map and :map! ; see :help map-modes .

As you usually define mappings only once in your .vimrc , I wouldn’t worry too much about a 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 '<Co>' . a:rhs endfunction call MapBoth('<C-Up>', '10<Up>') 
+8
source

Original


 nnoremap <F2> :w<CR> inoremap <F2> <Esc>:w<CR>a 

map sometimes does not set it for all modes. I do not know the exact reason, therefore, to be sure that I want to explicitly set the entire mapping to my configuration file. I suggest you do the same thing as when you can get something unexpected due to different modes. Therefore, it is important to carefully monitor each reassignment that you do for each particular mode.

Also, use the *noremap instead of everything *map wherever you can, since recursive mapping is a known source of errors, especially for beginners.

Finally, I don’t know what you are trying to achieve by attaching a file record in visual mode. Are you aiming for a partial write to the buffer (this is when you selected something in visual mode, and then click this shortcut to write files and only the selected text)? Or do you want the whole file to be recorded when you are in visual mode, regardless of whether you have selected something or not when you click on the shortcut to save the files? Provide more information about this. Personally, in any case, this is a strange display for the visual mode, because for this it really does not back down. It is much better to store such things in normal mode.

Update


Since others have already given comprehensive answers to your question, I just thought it would be useful to add my 2 cents, but in a slightly different direction. If you look at what you are trying to do, namely display navigation functions using the arrow keys in insert mode, I can conclude that you are very new to Vim. As you probably already know, the philosophy of Vim is that you should never ever touch the mouse while working inside Vim - call it a kind of golden rule .

Now I want to point out what I call the 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, disable the use of the arrow keys (everywhere except in command line mode). Your fingers should always be in the symbol area only. Wim is all about modes. The insert mode is not intended for navigation - it is intended for input bursts . When you work with code or just with text (it doesn’t matter), you spend most of your time in normal mode - navigation - browse the file, looking for where to land nearby to edit something, add something, i.e. make the next next input packet for which you switch to insert mode, and when you are done, you will return to normal mode to find some more meat - like a predator . :)

So what's the deal? I just want to direct you in the right direction from the very beginning. Thus, you can become an intermediate user of Vim very quickly - just a few days. To better understand all of the above, I suggest you definitely watch the Vim Novice Video Tutorials from Derek Wyeth, where he talks about all these things in more detail and shows him in action in the screenshots. There are also Intermediate and Advanced study guides of it, which you can also see at your convenience.

I wish you happiness!:)

+7
source

If it is ok to display in normal mode, you can combine a for loop with <C-\><Cn> mappings. <C-\><Cn> switches from any mode to normal.

For example, this allows you to switch panels using Alt- {h, j, k, l} from any mode:

 for map_command in ['noremap', 'noremap!', 'tnoremap'] execute map_command . ' <silent> <Mh> <C-\><Cn><Cw>h' execute map_command . ' <silent> <Mj> <C-\><Cn><Cw>j' execute map_command . ' <silent> <Mk> <C-\><Cn><Cw>k' execute map_command . ' <silent> <Ml> <C-\><Cn><Cw>l' endfor 
  • noremap in normal, visual and pending mode
  • noremap! cards in input mode and commands
  • tnoremap cards in Neovim terminal mode.
+2
source

All Articles