I would like to duplicate the current buffer, which will act the same way only that I will use the rtl command on it:
:set rightleft
Except that the buffers will be the same, if I scroll down in the original one the second will scroll too and etc.
Is it possible in vim without any plugins?
Yes,
just split it
:sp or :vsp and then use the following:
:windo set scrollbind
windo will send the command to every open windo see :h windo
and scrollbind is what you are really looking for again see :h scrollbind for more
The rightleft or rl command is local to the window, so you can view the same buffer in two different windows with and without rl
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.
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(
I have noticed that when I use :cn :cp directly, vim always expands folds for me. But when I set my custom mapping to call :cn like :map <leader>n :cn<cr>, vim doesn't expand foldings when I use <leader>n in this case, I have to move horizontally after using that hotkey to unfold. I could script moving horizontally as well, but I still would like to understand why vim doesn't do that for me.
My foldopen setting contains quickfix.
Thanks.
According to this vim email archive.
This is the correct behavior and that you are supposed to open folds manually if you put :cn or :cp into mappings. The solution was to add zv to the end of the mappings.
So your maps should look like this
noremap <leader>n :cn<CR>zv
Note: I change map to noremap because noremap stops recursive mappings whereas map allows for it.
Recently I found out that I'm "using tabs incorrectly" in Vim. I've been trying to just use buffers in Vim since, assisted through MiniBufExplorer, but I find it painful because of how many keystrokes it takes to change buffers from normal mode. With tabs, I can just do gt or gT to hop back and forth between tabs in normal mode, and I can also do NUMBERgt to go to a specific tab.
With buffers, I either have to enter command mode with :bn, :bp, or with MiniBufExplorer, use Ctrl + k or Ctrl + Up to hop up to the buffer window, scroll left or right with h and l and then hit Enter to select the buffer I want. Or I can do something involving a leader sequence, but it always requires removing multiple fingers away from home row. That's a real pain.
How can I get something equivalent switching tabs in normal mode to switch buffers in normal mode, so I can do something like gn/gp for :bn/:bp and NUMBERgn for :buf NUMBER?
Add this to your .vimrc
map gn :bnext<cr>
map gp :bprevious<cr>
map gd :bdelete<cr>
" I personally use <leader>
map <leader>n :bnext<cr>
map <leader>p :bprevious<cr>
map <leader>d :bdelete<cr>
Note that you are remapping gp and gd, but maybe you don't care about that (:help gp, :help gd).
For more information on how to map key strokes see :help map-overview and :help map.txt.
Btw, I personally use <leader> instead of g in the mapping. My <leader> is set to ;. This puts my <leader> key on the home row which makes me willing to map all kinds of stuff using <leader>. :help mapleader if you want to change your <leader> key.
The way I usually switch between buffers is to use the :buffer command with the built-in autocompletion, e.g. :b prof<Tab> to switch to folder/path/LoginProfileFactory.php.
You can just start typing any part of the file name of the buffer you need, which is nice.
Less often, I actually remember the numbers of the buffers I want and I use something like :b 3 or :3b.
I see you mention you don't like :buf 3 though, so Rumple Stiltskin has an alternative to the :3b style that you may prefer.
{count}CTRL-^ switches to the count numbered buffer.
I have the following lines in .vimrc:
nnoremap <silent> <tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bnext<CR>
nnoremap <silent> <s-tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bprevious<CR>
Now a Tab let you go to the next buffer and a Shift-Tab to the previous.
This is based on Nick Knowlson's answer, but I wanted to expand on my comment there ...
Type :b <Tab> (note the space), then cycle through the open buffers with Tab or ← / →.
... which gets us closer to the Ctrl + Tab in all the other editors and browsers I use.
It's actually even better in some ways, you can then go backwards and forwards with ← / → arrows. It avoids the thumb + finger fu to type Ctrl + Shift + Tab to go backwards through the tabs in editors and browsers.
N.B. Shift + Tab just does the same as Tab
This is then actually something like Win + Tab in Windows 10, where once you first open up the window and you can then move around using the arrow keys.
Edit: I have two further tricks that I picked up for using buffers:
From this answer I have this in my .vimrc:
nnoremap <leader>bb :buffers<cr>:b<space>
it opens the :ls / :buffers command and pre-types the :b so that you just have to type the buffer number as you'll see a list with all the buffers and their numbers.
I also have
nnoremap <leader><tab> :b#<cr>
which toggles between the current and most recently used buffers, it's a bit like doing cd - when switching back and forth between directories
I use the plugin unimpaired.vim
it defines mappings [b and ]b that jump to the previous and next buffer in the list.
For jumping for a specific buffer the best option I know is the one you mentioned: :b<number>
If you go into another buffer you can came back quickly by typing <c-^>
Expanding on Rumple Stiltskin's answer, if you know that the file you want to get to is in buffer 4, for example, you can get there quickly with
4Ctrl-^
On my UK keyboard, I can actually do 4Ctrl-6, as explained in
:help CTRL-^
By the way, you can see the buffer numbers with
:buffers
or
:ls
I use LustyExplorer: I hit <leader>b to open a list of buffers then a couple of letters from the name of the buffer I want to open then enter. Easy.
But, you are not "using tabs incorrectly", you are using tabs the way you want. If it worked for you why go through the pain of unlearning your way to learn "the right way"?
I use F9 and F10 to move between the previous/next buffer with this mapping:
map <F9> :bprevious<CR>
map <F10> :bnext<CR>
For me this is the fastest way to switch buffers.
fzf.vim is another fast way to changes buffers using fuzzy matching. This plug-in ships with the default command:
:Buffers
which opens the list of all open buffers similar to :ls but a buffer can be (fuzzy) searched and selected.
Opening the buffer in the current window is through enter, but can can also be opened in a new split (h or v) or tab using ^X ^V or ^T respectively.
Noteworthy is also:
:Lines
Which allows to search through the content of all open buffers. This can be handy if you forget the name of a buffer but you know what it should contain.
Here is my solution:
" `<leader><Tab>` - next buffer;
nnoremap <silent> <leader><Tab> :bnext<CR>
" `<leader><S-Tab>` - previous buffer;
nnoremap <silent> <leader><S-Tab> :bprevious<CR>
" `_bufferNumber_ + <Tab>` - go exact the buffer number;
nnoremap <silent> <Tab> <C-^>
By the way, I use 'buftabline' plugin and set let g:buftabline_numbers = 1 to spread my buffer on the tabline.
I make it easier for myself:
In .vimrc :
nnoremap <leader>bf :buffers<CR>:buffer "<- Last spaces is necessary
For example, in normal mode, say your leader key is \(default it is), type \bf, then you have a list of opened buffers, type number of buffer you want and hit enter key.
NOTE: remember that last spaces not necessary at all if you wich type it after :D
Jut like that ;)
More detail:
<C-O> Navigate backward
<C-I> Navigate forward
So there is no need extra remapping, otherwise you remapped them.
I think bufexplorer is a nice plugin to use. <leader>be brings up an interactive buffer explorer that lists all open buffers. You could quickly move through the list and Enter puts you in the selected buffer. Unlike LustyExplorer It has no dependency to ruby.
I prefer navigating between buffers similarly to how I'm navigating between window panes: <alt-h> and <alt-l>. This is to straightforward to set on Mac because <alt>/<option> key binds are bounded to specific characters.
" Buffer navigation
map ˙ :bp<cr>
map ¬ :bn<cr>
map § <c-^>
Here is a good answer that shows how you can see characters maped to <alt-..> combinations