Vim: Changing viewports quickly in normal mode - vim

I use viewports extensively in vim, I'm forever splitting files into new viewports etc. I typically navigate around the viewports using Ctrl+W and a movement key, ie: hjkl.
Since there is a normal mode command for switching tabs quickly, gt, gT and ^gt, I was wondering if there is a normal mode equivalent without the modifier. If not, what would a good mapping be? gv and gw are both taken already.

For switching viewports quickly, I use the following:
noremap <C-J> <C-W>j<CR>
noremap <C-K> <C-W>k<CR>
noremap <C-H> <C-W>h<CR>
noremap <C-L> <C-W>l<CR>

I have the following mappings:
map <tab> <c-w>
map <tab><tab> <c-w><c-w>
so I can move quickly between windows with <tab>j, <tab>k, etc...
Note that this also make easier to use all the other <c-w> mappings like <c-w>t to go to the first window or <c-w>b to go to the last window.
These just become <tab>t and <tab>b.
Before using these mappings I was using
map ,w <c-w>
so again you would use this followed by a letter to move around the windows.
If you just want to stick to left, right, up and down then you can directly
use something like
map ,l <c-w>l
and so on.

Related

Making a key binding to travel through Sublime Text 3's buffers (tabs)

I am using NeoVintageous package inside Sublime Text 3 to access vim/neovim keybindings. The package has support for remapping my default keys by editing .neovintageousrc. I recently mapped Ctrl-h and Ctrl-l to navigate through splits like this:
:nnoremap <C-h> <C-w>h
:nnoremap <C-l> <C-w>l
I was wondering if I could navigate through the buffers in somewhat similar fashion. Since <tab> is to be remapped here, I am facing some difficulties.
I tried this:
:nnoremap L <C-<tab>>
I thought this would allow me to move to next buffer similar to what Ctrl-tab would do. But this doesn't work. Does anyone happen to know a way to map this?

Ctrl + w + w obviously cannot perform to switch tab on a google compute engine window

Ctrl + w is a shortcut to closing an open window on VM instance of Google Compute Engine. Hence it will ask to perform that action before letting me type one more w, to enact switching of tabs between the directory tree and the script to work on in vim.
I've tried the following, as mentioned here
map <C-l> :tabn<CR>
map <C-h> :tabp<CR>
map <C-n> :tabnew<CR>
While I'm not sure what tabn and tabp indicate, I tried the first two line and (C as Ctrl) neither of these respond to anything new. I used source ~/.vimrc command before expecting a change is reflected. What is wrong here?
I think you're mixing up Vim tabs and Vim windows.
Vim windows will split the screen vertically or horizontally into separate panes, which are all visible at the same time. That's typically used by directory tree plug-ins which want to display a navigator on a sidebar.
Vim tabs group a set of windows, so that you can switch between whole sets of windows at once and still easily go back to where you were before. (People often use tabs to work on different projects and switch between them, though opening one file per tab, fullscreen, is also a somewhat common workflow.)
The mappings that use Control-W are window mappings, not tab mappings. (You can switch to next tab with gt and previous tab with gT).
The normal commands to cycle windows are Ctrl-W w (to move right/down) and Ctrl-W W (to move left/up), so you can use these two mappings:
nnoremap <C-l> <C-w>w
nnoremap <C-h> <C-w>W
If you want a mapping to open a new window with a new blank file, you can use:
nnoremap <C-n> <C-w>n
If your problem is with typing Control-W in specific, perhaps a better option is to map a key sequence you're not using to replace Control-W, but keep it to just the prefix, so that all other commands that follow are still available?
Perhaps use Control-Q, which is just next to W in the keyboard:
nmap <C-Q> <C-W>
And you might want to remap the commands that use the same key twice, so in your case use Q twice where there's two W's:
nmap <C-Q> <C-W>
nnoremap <C-Q>q <C-W>w
nnoremap <C-Q>Q <C-W>W
nnoremap <C-Q><C-Q> <C-W><C-W>
Those four there, that would be my recommendation, if Control-W is an inconvenient sequence for you.

Looking for better way to map some F key in Vim

I currently map my F2 and F3 as following:
map <F2> :tabn <CR>
map <F3> :tabp <CR>
imap <Esc> :tabn <CR>
imap <Esc> :tabp <CR>
I try to figure out how to map the normal/insert mode at the same time.
I spent some times on googling around without any luck.
Any suggestion would be appreciated.
The best I've found so far is:
nnoremap <F2> :tabn<CR>
imap <F2> <C-O><F2>
nnoremap <F3> :tabp<CR>
imap <F3> <C-O><F3>
Still an extra line for each key, but at least the actual command (:tabn, :tabp) is only mentioned once (and only needs to be changed in one place if you want to change it).
Honestly in my opinion, these mappings are probably not worth it.
gt/gT already exist to move between tabs. See :h gt
Normal mode is crucial to Vim and it makes sense to use this mode and not insert mode for movement between tabs. It is called normal mode for a reason as it is the mode you should normally be in.
Aside about tabs and buffers
Your mappings suggest a heavy tab centric workflow. I know it might sound weird but maybe try and use less tab panes together with a more buffers centric workflow. Here are some nice posts about it:
Why do Vim experts prefer buffers over tabs?
Use buffers effectively!

Tab Navigation mapping is not working

NOTE: I am using Terminator instead of terminal. But as all other mappings are working fine why does these are not working.
I have tried to use these mappings in my vimrc file to be able to use Tab Navigation. But its not working at all.
nnoremap <C-S-tab> :tabprevious<CR>
"nnoremap <C-tab> :tabnext<CR>
nnoremap <C-tab> :tabn<CR> "I also tried this
nnoremap <C-t> :tabnew<CR>
inoremap <C-S-tab> <Esc>:tabprevious<CR>i
inoremap <C-tab> <Esc>:tabnext<CR>i
inoremap <C-t> <Esc>:tabnew<CR>
inoremap <C-S-w> <Esc>:tabclose<CR>
"Also to go to the nth tabpage Use <A-Fn>
nnoremap <A-F1> 1gt
nnoremap <A-F2> 2gt
nnoremap <A-F3> 3gt
nnoremap <A-F4> 4gt
nnoremap <A-F5> 5gt
nnoremap <A-F6> 6gt
nnoremap <A-F7> 7gt
nnoremap <A-F8> 8gt
nnoremap <A-F9> 9gt
nnoremap <A-F10> 10gt
NOTE: I have ctags and cscope installed. So I think there might be some confliction as ctrl-t is to jump back from a certain tag. And only this mapping is working for new tab.
Also I have checked ctrl-PageDown is working fine for the same purpose.
2nd Question:
How does this key notation works in vimrc.
Is it something like this:
All modifier keys should be used in Caps like
C for Ctrl.
A for Alt.
S for Shift.
And other keys are all in small.
But what about keys like:
Home
End
Backspace
Escape
PageUp
PageDown
Tab
Function keys etc.
How to use them?
Here
I read that how these should be used in mapping but even they have used tab instead of Tab in mappings.
Brace yourself for disappointment.
The terminal keycodes
Vim accepts terminal keycodes, so not all key combinations are possible. The best way to figure out which keys are recognizable is to open insert mode and press ctrl+v followed by your key combination. This will show you the raw codes. Do this for another key combination. If the raw codes are the same then Vim can not distinguish between them. e.g. ctrl+v ctrl+shift+tab.
Your mappings
You should probably avoid doing insert mode mappings to switch tabs. It simply isn't the Vim Way as insert mode should only be used in short bursts.
Your :tabprev and :tabnext mappings can simplified into gT and gt mappings. Personally I do not mind the default gt or gT mappings.
<key> notation
As far as I know the case does not matter. All my mappings are lowercase. For a list of <> notation please see :h key-notation.
You are correct on the <c-..> for control, <a-...> for alt, and <s-...> for shift. Example combination would be <c-s-space>. Note: most <c-s-...> mappings are going to fail.
Using Tabs
Vim's tabs are not like most text editors tab. They are more like viewports into a group of windows/splits. Additionally, Vim is buffer centric, not tab centric like most editors. For example using features like Vim's quickfix list is often easier without tabs (See :h 'switchbuf if you must use tabs). Vim's tabs often get in the way of using a splits as there are better window and buffer navigation commands available. I personally have many files open (sometimes 100+) using no tabs and use on average 1-2 splits without any issue.
Bottom line: Learn to use buffers effectively.
Conclusion
I would suggest you break this tab workflow quickly and learn to love buffers. You won't really need your mappings and you will not be working against Vim's nature.
Read :help key-notation for an explanation of… Vim's key notation.
It is generally a good idea to play it safe so I recommend to follow these conventions when mapping combos:
always use an uppercase letter for the modifier key, C for Control, S for Shift, A for Alt, D for Command (MacVim GUI only), M for Meta,
always use a lowercase letter for the alphabetical keys, abc…xyz,
always capitalize the first letter of "special" keys, Tab, Space, Up, etc.
Examples:
<S-Up>
<C-r>
<A-LeftMouse>
However, the following notation works just as well so… whatever notation you choose, try to be consistent:
<s-UP>
Using multiple modifiers in a single mapping doesn't work reliably so you will be better in the long run if you completely avoid them.
nnoremap <C-S-j> :echo "csj"<CR>
nnoremap <C-j> :echo "cj"<CR>
now press <C-j> and <C-S-j> in normal mode.
<C-S-w> is indistinguishable from <C-w>.
:verbose map <C-t>
shows you what is mapped to <C-t> and where the mapping occurred. You can use it to debug your mappings.
And I agree with Peter, you are using both tab pages and insert mode wrongly.

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

Resources