I'm trying to map Ctrl+[ and Ctrl+] to move between buffers.
I have this in my .vimrc:
nnoremap <c-[> :bprevious<CR>
nnoremap <c-]> :bnext<CR>
nnoremap <Esc> :noh<CR>
The Ctrl+] works. The Ctrl+[ trigger an :noh and I don't know why.
I would like to Ctrl+] and Ctrl+[ simply move between buffers and Esc to trigger an :nho.
ctrl+], ctrl+ [ and ESC are already being used by vim. Mapping keys which are already being used by vim is not recommended.
More at :help map-which-keys.
So, instead of mapping those keys, I would like to suggest, for example, to use F2 and F3
nnoremap <F2> :bprevious<CR>
nnoremap <F3> :bnext<CR>
#dlmeetei and #Lucas Beier are correct. These are poor keys for Vim.
Map safe keys like function keys, leader mappings, or unused mappings. Example (same as unimpaired.vim):
nnoremap [b :bprevious<c>r
nnoremap ]b :bnext<cr>
nnoremap ]B :blast<cr>
nnoremap [B :bfirst<cr>
For more help see:
:h map-which-keys
:h key-notation
:h :bfirst
:h :blast
We can do better! or The problem with cycling buffers
Cycling buffers is kind slow. I believe :bprevious and :bnext are only useful in a narrow set of conditions:
These commands become useful after you use more than 2 buffers (probably due to <c-6>/<c-^>).
Once you hit a certain buffer number threshold, there is sort of an upper limit on the usefulness of cycling with these commands. Is it faster to cycle forward? Backwards? Does it matter because it simply takes too long either way?
Instead of cycling with :bp and :bn you can jump directly to a buffer via :b command. Simply use :b {partial_name}<tab>.
Behold the power of :b:
Uses <tab> completion
Use <c-d> to list out completion
Use partial file name. e.g. :b foo. Works great with <tab>.
Globbing. e.g. :b foo*bar or :b foo/**/bar
Split variant of :b is :sb.
Also accepts a buffer number
A common mapping: nnoremap <leader>b :ls<cr>:b<space>
For more help see:
:h :b
:h :ls
:h cmdline-completion
:h file-searching
Can we do better than :b?
Skip the buffer management completely and use tags, cscope, and/or GNU Global. These will help you go directly to where you want to go not just the right buffer with where ever you last left the cursor.
For beginners to tags I suggest Gutentags and :h tags.
You can also use :find with tab completion and set your 'path' to .,,** for a basic less fuzzy finder.
For more help see:
:h CTRL-]
:h tags
:h cscope
:h :find
:h 'path'
Plugins?
A fuzzy finder like CtrlP or fzf allows for general file navigation. For more specific project navigation you can use something like Projectionist.vim.
Conclusion
I would suggest slowly learning more buffer and general navigation commands. These commands will serve you well and help you navigation quicker without resorting to buffer cycling.
Personally, I use a combination of :b, tags, cscope/GNU Global, and projectionist.vim for most of my navigation needs. I often have over 50+ buffers open and get to my desired file without ever resorting to buffer cycling.
Related
I want to show all buffers' names on statusline(I use powerline). And I hope current buffer can be highlighted, while others are not. When I use :bn or :bp it highlights the changed buffer. How can I make it?
I don't know how to do such a thing with powerline, however I have come across vim-buftabline which does what you ask but with the tabline instead of the statusline.
Personally, I would forget doing this in the statusline or tabline, because it is very easy to run out of space on either line. I would also stop using :bn/:bp and just use :b instead to jump directly to the buffer in question.
Behold the power of :b:
Uses <tab> completion
Use <c-d> to list out completion
Use partial file name. e.g. :b foo. Works great with <tab>.
Globbing. e.g. :b foo*bar or :b foo/**/bar
Might want to use 'hidden' via set hidden
Split variant of :b is :sb.
Also accepts a buffer number
A common mapping:
nnoremap <leader>b :ls<cr>:b<space>
For more help see:
:h :b
:h :ls
:h 'switchbuf'
:h 'hidden'
:h 'tabline'
In powerline, the list of open buffers can be displayed by adding the following line to your .vimrc configuration file:
set showtabline=2
This will add an additional status line at the top of your vim session and also highlight the active buffer.
Source: Powerline documentation
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!
How can I use a variable when mapping keys in vim? The specific problem that I am trying to solve is the following. I need these key mappings:
nnoremap <C-1> 1gt
nnoremap <C-2> 2gt
nnoremap <C-3> 3gt
... and so on.
Can I specify one mapping; something like
nnoremap <C-x> xgt
where x takes the value of the key pressed (which can be from 1..9)
Thank you.
Edit 1: Towards the solution (not yet complete) thanks to Peter Rincker
I can use the function
function gotoTab(num)
execute "normal" a:num."gt"
endfunction
If I :call goToTab(3), it goes to tab 3.
How do I map Command-x (D-x) to goToTab(x) where x is between 1..9. How do I read the number from a Command-x press?
I got bad news. You can not map <c-1>, etc. You can only bind <c-6> which I wouldn't do as it is very handy.
It also seems like you are doing a heavily tab centric workflow. I know it might sound weird but maybe use less tab panes and more buffers. Here are some nice posts about it:
Why do Vim experts prefer buffers over tabs?
Use buffers effectively!
... Ok, but I really want to do this variable mapping thing. You have options:
Use a for loop and use :execute to create mappings
The more Vim Way is to use a count so 7gt. The 7 is the count.
Example of using :for and :execute:
for i in range(1, 9)
execute "nnoremap \<d-" . i . "> " . i . "gt"
endfor
Note: this uses <d-...> syntax for Command which is only available on MacVim and no terminal support (See :h <D-). You can use <a-...> for Alt. However I must warn you using Alt on the terminal can be tricky.
For more help see:
:h keycodes
:h map-which-keys
:h :for
:h :exe
:h count
:h v:count
:h range(
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.
I'd like to bind these:
CTRLF one character forward
CTRLB one character backward
CTRLN go to the line below the current one ( not in insert mode )
CTRLP go to the line above the current one ( not in insert mode )
Which functions should I bind? How could I find them?
On vim.org you can find a script called Vimacs : Vim-Improved eMACS: Emacs emulation for Vim
The short description says:
Vimacs (Vim-Improved eMACS) brings Emacs's extensive key bindings and modeless editing features to the Vim world, while completely retaining Vim's powerful moded editing style.
So I guess this is all you need.
If you just want those four mappings and not the full Vimacs, you can do this:
nmap <c-f> l
nmap <c-b> h
nmap <c-n> j
nmap <c-p> k
To get ctrl-f and ctrl-b to work in insert mode add these:
imap <c-f> <right>
imap <c-b> <left>
Check out the map command.
:h :map
You might want to consider learning the vim mappings. (h/l and j/k are shorter than ctrl-f/ctrl-b and ctrl-n/ctrl-p).
Also, check out..
:h index
.. for a list of the mappings.