Is there an easy way to cycle between two windows (buffers!) in vim?
With vim file1 file2 one can use :n and :N to go back and forth. But this is cumbersome, leads to errors if either :n or :N is typed twice.
I'm hoping for something simple as ZZ to go back and forth with a single key.
Is there an easy way to cycle between two windows (buffers!)
Well… "windows", "buffers", or, since you are using :n and :N, "files"? They are not the same thing at all.
Files
As was mentioned in the comments, <C-^> (or <C-6> on some keyboards) can be used to switch between two files but, since it relies on the notion of "alternate file", you must do :next first in order to establish the relationship between the two files.
The problem with the argument list, the list where the files you passed as argument to Vim are stored, is that it is quite low-level. :n and :N don't wrap around, the alternate file is not set automatically, etc. Bummer.
Example:
$ vim file1 file2 # open two files, file1 is current
:n " switch to file2
<C-^> " switch to file1
<C-^> " switch to file2
<C-^> " switch to file1
…
See :help argument-list.
Buffers
Every "file" you open in Vim (from within Vim or from the shell) becomes a buffer so, in addition to the low-level argument list, you have the buffer list which operates at a slightly higher level.
Since you only opened two files, you only have two buffers, between which you can switch with :help :bnext because, unlike :n and :N, :bn (and :bN) wrap around.
Example:
$ vim file1 file2 # open two files and therefore two buffers, file1 is current
:bn " switch to file2
:bn " switch to file1
:bn " switch to file2
:bn " switch to file1
…
Note that you can map :bn to something easier if you want.
<C-^> can also be used in this context because the boundary between "file" and "buffer" is a bit murky, but you still have to establish the relationship first by doing a manual switch.
Windows
You can switch between two windows with <C-w>p: :help CTRL-W_p.
Going forward
<C-^> is quite useful but you need to establish a relationship between two files/buffers for it to work and Vim unfortunately doesn't do that at startup. It is possible to force it, though, but it is not exactly intuitive. YMMV:
$ vim +n +N file1 file2
See :help -+c.
I set the following in my ~/.vimrc for this purpose.
"""" Faster buffer cycling """
nnoremap <C-n> :bnext<CR>
nnoremap <C-p> :bprev<CR>
Doing this sacrifices the <c-n> and <c-p> native behavior, but those are literally duplicates of the behavior of the k and j keys.
Related
I have a lot of buffers open and to switch between then I Ctrl+w and then Ctrl+[movement key]. Is there a better way? Because this way when I've to do more than one movement I end up having to press 4 keys.
If you want to move between windows, you always can map Ctrl-W, H/J/K/L to anything you want:
map <C-h> <C-w>h
map <C-j> <C-w>j
map <C-k> <C-w>k
map <C-l> <C-w>l
If you want to move between buffers, you can use :buffer command, print a part of the file name you want to go to: pressing Tab will cycle through all files that contains this part in the names. E.g you want to show buffer with filename 'some_long_c_file.c' and you know you don't have any other opened file whose name ends with 'file.c': just type :buffer file.c and press Tab (or even 'ile.c' or shorter), this will complete it to 'some_long_c_file.c'.
For quick switching between the two last buffers, use Ctrl-^
The best way I've found to do this is to install bufexplorer.vim. That let's you quickly switch to a screen in which you can select any buffer. You can also close buffers etc..
Here's a screenshot of my vim with bufexplorer open showing it's help screen:
For me the solution was two-fold:
1) Use unimpaired - so ]b and [b
2) map :b# to switch to previous buffer. I used map <cr> :b#<cr> . (so enter key would toggle back and forth between two open buffers).
I opened a files in vim using
gf
command.which opened a file that the current cursor position.
I used
ctrl + ^
is used to toggle between the last two opened files.
But,
How can i go forward and backward opened the files?
:bn & :bp to cycle buffers
To cycle windows I use ctrl+w+w
To cycle opened file :next & :prev
To list opened buffers: :ls
from good old vi :e# reopens previous file ^^ (not using it since ages... well since VIM comes to my systems ^^)
EDIT: a quick test on gvim in windows (set nocp)
map <C-tab> ^[:bn^M
in order to enter escape (^[) and enter (^M) you have to press ctrl+v and then the special char
EDIT 2: a cleaner way to do this is putting this in .vimrc
map <C-tab> <esc>:bn<cr>
but just remember that using mnemonics for the keys depends on some other options (I cannot remember which one).
The best way is IMHO to write a VIM function saving the actual mode, performing switch and then restoring it, then mapping it to in every mode (:[xxx]map commands)
:next to next file
:prev to previous file
Alternatively, you might want to check out any one of the plugins trying to make buffer navigation easier
I myself have reduced it to <leader>bx, x being the number of the buffer.
Selecting the buffer is done via a nice popup list at the bottom.
To get this behavior, you would first install LustyJuggler ( https://github.com/vim-scripts/LustyJuggler ), and then set up the shortcut like so in your vimrc file:
nmap <leader>b :LustyJuggler<CR>
Note that this mapping only works when you are in normal mode.
You can also map the TAB key to quickly cycle through open buffers.
Add the following to your vimrc file:
:nnoremap <Tab> :bnext<CR>
:nnoremap <S-Tab> :bprevious<CR>
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
If you are editing a file in VIM and then you need to open an existing buffer (e.g. from your buffer list: :buffers) how can you open it in a vertical split?
I know that you already can open it with a normal split like:
:sbuffer N
Wehere N is the buffer number you want, however, the above opens that N buffer horizontally, not vertically.
I'm also aware that you can change the window placement after opening and have a Vertical Split like so:
Ctrl-W H
Ctrl-W L
Which will vertically split the window to the right or the left.
It seems to me that if there is a sbuffer there should be a vsbuffer but that doesn't exist (not that I am aware of)
Also, please note that I am not looking for a plugin to solve this question. I know about a wealth of plugins that will allow you to do this.
I am sure I might be missing something that is already there.
EDIT:
In the best spirit of collaboration, I have created a simple Function with a Mapping if someone else stumbles across this issue and do not want to install a plugin:
Function:
" Vertical Split Buffer Function
function VerticalSplitBuffer(buffer)
execute "vert belowright sb" a:buffer
endfunction
Mapping:
" Vertical Split Buffer Mapping
command -nargs=1 Vbuffer call VerticalSplitBuffer(<f-args>)
This accomplishes the task of opening a buffer in a right split, so for buffer 1, you would call it like:
:Vbuffer 1
Try:
:vert sb N
which will open a left vertical split (by default, unless you have modified some options).
To open a split to the right, on the other hand:
:vert belowright sb N
:vsp | b1
1 being some buffer number. Use buffers to list all buffers.
Here's some additional info on splits, if you're interested.
Link
The answer to the OP that I found most useful is embedded deep in Jerinaw's answer and a comment on it, and in Wolfson's answer. But I felt it might be brought out more. (Nor have those been voted most highly, even though they seemed to me the ones that answered OP best.)
The answer to the question, Why is there not :vsbuffer, is that there is. It's called :vsplit and does the trick either as
:vsplit NameOfBuffer
OR
:vsplit #NumberOfBuffer.
(In this second use, take care to note that the hash # is significant. If you want to get to buffer number 3, you need to say :vsplit #3, not just :vsplit 3 which will instead create a new file named "3".)
Again, this answer is embedded above, it's just not brought out clearly enough for the quick scanner, IMV.
You can ease your pain by adding the following to your .vimrc
cabbrev vb vert sb
Now you can use it in the following way.
:vb <buffer>
You can also combine :ls that lists your current buffers and the commands to open the desired buffer in either
current window: :b <N/bufname>
vertical split: :vsp | b <N/bufname>
horizontal split: :sp | b <N/bufname>
For this, I've added the following mappings to my ~/.vimrc (order of mappings represents the above list of desired windows)
nnoremap <leader>b :ls<cr>:b<space>
nnoremap <leader>v :ls<cr>:vsp<space>\|<space>b<space>
nnoremap <leader>s :ls<cr>:sp<space>\|<space>b<space>
Based on this, you can see the buffer list as soon as you hit
<leader>b
<leader>v
<leader>s
and then just enter the desired buffer number N. This will then open the buffer in the desired window. You can of course still use a part of the buffer name bufname as well.
I mapped the <leader> to , based on
let mapleader = ","
For some people (e.g. me) this could even replace plugins like MiniBufExpl and thus save space on the screen.
you can use Neovim,like that:
autocmd FileType python nmap <F5> :rightbelow vertical split <bar> :term python %<cr>
I've tried MiniBufExplorer, but I usually end up with several windows showing it or close it altogether. What I'd like is something like LustyJuggler with incremental search, the way I switch between buffers in Emacs. Surely there is a script like this?
I used to use a combination of tabs and multiple gvim instances, keeping groups of related files as tabs in each instance. So long as I didn't end up with too many tabs in one instance, the tab bar shows you the name of each file you're editing at a glance.
Then I read a post by Jamis Buck on how he switched from TextMate back to vim, and learned some great tricks:
Ctrl+w s and Ctrl+w v to split the current window
Ctrl+6 to switch back and forth between two buffers in the same window.
the awesome fuzzyfinder.vim which gives you auto-completing search of files in your current directory or of buffers you currently have open
Jamis' own fuzzy_file_finder and fuzzyfinder_textmate, which slightly modify how fuzzyfinder works to behave more like a similar feature in TextMate (as far as I can tell, the difference is that it matches anywhere in the filename instead of only from the start). Watch this video to see it in action.
Now I just have one gvim instance, maximised, and split it into multiple windows so I can see several files at once. I bound Ctrl+F to fuzzyfinder\_textmate, so now if I type (say) Ctrl+F mod/usob it opens up app/models/user\_observer.rb. I almost never bother with tabs any more.
Update 2010/08/07
While fuzzyfinder\_textmate remains awesome, as Casey points out in the comments, it's no longer maintained. Also, it (and/or fuzzyfinder.vim) gets a bit slow and unstable when working with large projects (lots of directories or files), so I've been looking for an alternative.
Fortunately, there seems to be a very nice alternative in the form of Wincent Colaiuta's Command-T plugin. This has very similar (if not slightly better) behaviour to fuzzyfinder\_textmate, but is noticeably faster; it also has nice features like being able to open the found file in a split or vertical split. Thanks (and upvotes!) to David Rivers for pointing to it.
I use the basics - ':ls' + ':bn'/':bp' + ':b <part-of-name>'
I like "ctrl-w s" and "ctlr-w v" to split the window. Then I map the movement keys (h, j, k, l) with ctrl held down to move between the split windows:
" Map ctrl-movement keys to window switching
map <C-k> <C-w><Up>
map <C-j> <C-w><Down>
map <C-l> <C-w><Right>
map <C-h> <C-w><Left>
Having to move my hand over to the arrow keys is annoying.
Next, I set up ctlr-tab to switch between buffers in the current window (like a lot of other environments):
" Switch to alternate file
map <C-Tab> :bnext<cr>
map <C-S-Tab> :bprevious<cr>
These have worked pretty well for me over the last several years although vim always has more secrets than you can know.
I have been using Wincent Colaiuta's Command-T vim plugin for a couple months now. Wincent wrote the parts of it that need to be fast in C, and I must say that it is! And, I think its file pattern matching logic is even better than Textmate's Command-T. Check out the screencast.
The Command-T plug-in for VIM provides
an extremely fast, intuitive mechanism
for opening files with a minimal
number of keystrokes. It's named
"Command-T" because it is inspired by
the "Go to File" window bound to
Command-T in TextMate.
Files are selected by typing
characters that appear in their paths,
and are ordered by an algorithm which
knows that characters that appear in
certain locations (for example,
immediately after a path separator)
should be given more weight.
Easier buffer switching contains many useful tips. I have adapted the following to my .vimrc, which does buffer-name auto-completion, maps the most useful buffer-switching commands to my <Leader> and left-side home row keys, and shows the current buffer number in the status line:
"" Tab triggers buffer-name auto-completion
set wildchar=<Tab> wildmenu wildmode=full
let mapleader = ","
map <Leader>t :CommandT<Return>
map <Leader>a :bprev<Return>
map <Leader>s :bnext<Return>
map <Leader>d :bd<Return>
map <Leader>f :b
"" Show the buffer number in the status line.
set laststatus=2 statusline=%02n:%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
I also use MiniBufExplorer, which provides a compact listing of each listed buffer in its own horizontal split up top.
nmap <Leader>bb :ls<CR>:buffer<Space>
and nobody mentioned nice plugin ctrlp.vim. Using this plugin you can search buffer by name.
I use
CTRL-J for next buffer
CTRL-K for previous buffer
CTRL-L for next tab
CTRL-H for previous tab
Here is the .vimrc configuration:
map <C-J> :bnext<CR>
map <C-K> :bprev<CR>
map <C-L> :tabn<CR>
map <C-H> :tabp<CR>
See http://syskall.com/my-biggest-vim-productivity-boost/
imap <A-1> <Esc>:tabn 1<CR>i
imap <A-2> <Esc>:tabn 2<CR>i
imap <A-3> <Esc>:tabn 3<CR>i
imap <A-4> <Esc>:tabn 4<CR>i
imap <A-5> <Esc>:tabn 5<CR>i
imap <A-6> <Esc>:tabn 6<CR>i
imap <A-7> <Esc>:tabn 7<CR>i
imap <A-8> <Esc>:tabn 8<CR>i
imap <A-9> <Esc>:tabn 9<CR>i
map <A-1> :tabn 1<CR>
map <A-2> :tabn 2<CR>
map <A-3> :tabn 3<CR>
map <A-4> :tabn 4<CR>
map <A-5> :tabn 5<CR>
map <A-6> :tabn 6<CR>
map <A-7> :tabn 7<CR>
map <A-8> :tabn 8<CR>
map <A-9> :tabn 9<CR>
I've recently gone more minimalistic.
To cycle buffers I use ]b and [b from unimpaired: https://github.com/tpope/vim-unimpaired
To jump straight to an open buffer just use Vim's tab completion with :b. A few letters is enough to get to any open buffer with a tab or two.
Similarly to open buffers I use :e with relative paths and tab complete.
I also use :ls occasionally to see what buffers I have open (and to check their modified status).
To get rid of a buffer I use :bw to wipe the buffer. I usually make a temporary split and change buffers to preserve my layout though since :bw also closes the active window.
All the minibuf things I tried just ended up annoying me, and I don't want some smart-matching thing opening random files for me. If I really need to browse for something I use NERDtree (:e .).
IDK, Lately I also dropped Yankring (because it screws up xp) and started using registers, and I recently decided the f/t movements are the greatest thing ever...
To list and switch between buffers I use:
nnoremap <Leader>l :ls<CR>:b<space>
To switch between buffers:
map <Leader>n :bn<CR>
map <Leader>p :bp<CR>
The excellent Buffer Explorer, the be has gotten to be such strong muscle memory that I find myself wishing I could use it in other applications. I find it to be extremely fast when actively editing more than two files.
I've spent quite a while building my .vimrc to work with this HTML::Mason project I've been on for four years, so I have an odd mix of tabs and split windows. For your viewing enjoyment:
map ;o :Sex <CR>
map <C-J> <C-W>j
map <C-K> <C-W>k
map <C-l> <C-W>l
map <C-h> <C-W>h
map ;] :tabnext<CR>
map ;[ :tabprev<CR>
map <C-t> :tabe +"browse ."<CR>
map <C-O> :NERDTreeToggle ~/curr/trunk/<CR>
I use tselectbuffer. It's really fast and unlike bufexplorer doesn't take space in your window. It also has a incremental search.I tried minibufexplorer and I found the navigation in the buffer a bit difficult.
I have mapped <S-J> and <S-K> to :bp and :bn, although I admit I don't use it as the number of files is greater than 10. I have then mapped <C-J> and <C-K> to Gnome Terminal's previous and next tabs, and I usually run 4 instances of vim for each of the 4 different projects I work on. I still really wish next and previous buffer would go to the history of buffers I have been working on, and not the order int he buffer list.
I use tselectbuffer. It's really fast and unlike bufexplorer doesn't take space in your window. It also has a incremental search.I tried minibufexplorer and I found the navigation in the buffer a bit difficult.
i use simple :vsplit with ^W+w/^W+r and :tabnew with Ctrl+Alt+PgUp/PgDown key combinations.
When there are several buffers open in a Vim session, it can become difficult to keep track of the buffers and their respective buffer numbers. If this is the case, switching to a different file can be made easier using a simple map:
:nnoremap (F5) :buffers(CR):buffer(Space)
vim.wikia.com