Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I don't understand buffers. When I open 3 files on the same tab and close my window, I'm generally annoyed to find out next time I open one of those files that there are strange swap files lingering and giving me pesky messages. But time and time again I read that these things are the productivity nirvana I'm missing out on and that tabs were made for the plebeians to use.
So I ask you, the Vim expert: what are the advantages of using buffers over tabs? I don't see how the difference could be profoundly different, but I would consider myself only at the beginner-intermediate level at operating Vim. Is :ls :b# really that much faster than gting around? I feel it must go deeper than this.
As ZyX said on #vim, this question sounds like "Why do Vim experts prefer tasty over warm?".
"Vim experts" don't prefer buffers over tabs: they use buffers as the file proxies they are and tab pages as the workspaces they are. Buffers and tab pages have different purposes so preferring one to the other makes no sense whatsoever.
The issue with buffers and tabs is one of confusion, caused by a combination of independent facts.
Most "modern" text editors and IDEs use a tab metaphor to represent loaded files. That metaphor acts as an information system — it shows the user what files are opened and their state — and as an interactive device — it allows the user to manipulate (reorder, select, close…) those opened files. Despite their many limitations, tabs are everywhere and people are used to them and expect them everywhere.
Vim introduced tab pages in 7.0 as a way for its users to create ad-hoc "workspaces". Nothing in their features, their specific options, their specific commands or their :help sections suggests that tab pages could or should be used as file proxies.
Nothing except the name and the appearance of "tab pages", of course, which leads to much confusion.
Without :set hidden, which is disabled by default and not very easy to find, Vim makes it impossible to switch to another buffer without writing the current one or abandoning its changes. New users, unaware of that option, have no choice but to turn to heavy windows use or to the closest "tab-like" feature they can find: tab pages.
"Tab page" is an unfortunate name choice for that feature, especially in an era dominated by the idea that reading documentation is a waste of time.
In Vim, tab pages are an abstraction built on top of windows, themselves an abstraction built on top of buffers. Each new level adds useful features but restricts your workflow.
The "buffer way"
With a buffer-based workflow, the files you are working with are distributed along a single dimension. You can cycle through your buffers, you can access a specific buffer by typing part of its name (with completion) or its number, you can alternate between buffers, you can target them pretty easily. There's basically no friction.
Eight buffers open, only one visible:
Switching by number:
Switching by name:
Buffers are Vim's file-proxies. If you think in terms of files, you think in terms of buffers.
The "window way"
With a window-based workflow, your "files" are both distributed along the same single "virtual" dimension as they would if you only used buffers and along two other "physical" dimensions. But the cartesian spaces in which those dimensions are found are almost completely separated: moving to another buffer still means "moving to another file" but moving to another window doesn't. The buffer that corresponds to the desired file may be displayed in that window but it could also be displayed in another one, maybe in another tab page, or not at all.
With windows, navigating between open files either becomes too complex or too simplistic, even with 'switchbuf' and :sb. Mostly because you are forced to use two sets of commands for what is essentially the same thing: accessing a buffer.
Windows have their use, as described below, but they don't have what it takes to replace buffers in anybody's workflow.
Here I am working on a Vim colorscheme. The two windows are different views of the same buffer: the top one serves as reference, with a table of the color codes used in the colorscheme, and the bottom one is where I work:
Windows are not designed as file-proxies and can't be made into ones: they are "containers" or "viewports" designed to offer you a view into a buffer. No more, no less.
The "tab way"
With a tab-based workflow, you essentially try to mimic the user experience you are used to from your previous editor while completely ignoring the very nature of Vim's tab pages. If we forget for a moment that this strategy is generally very unproductive, it is also impossible, just like with windows, to force Vim to adhere to that "one file = one tab" paradigm without losing a lot of flexibility.
Still working with the same files as above, the tabline takes up a significant space for virtually no benefit. All my files and all my tabs are called javascript*.vim so I can't do 3gt and be confident I'll end up at the right place and it is impossible to reach a specific tab by name. Add to that the fact that its label can very well be the very unhelpful but perfectly logical [Quickfix List]… Since there is no practical way to tie a file/buffer to a tab page, you are basically left with only one practical way to navigate between tab pages/buffers/files: cycling.
And yeah, my tabline is clobbered with only 8 tabs, imagine if I had 20!
Eight buffers open in eight tab pages (wrong)
Two tabs for two specific tasks (right)
Tab pages are "containers" or "viewports" designed to contain one or more windows, themselves also "containers" designed to contain buffers.
In conclusion
"Vim experts" (let's assume I can speak as if I was one) don't prefer buffers over tabs: they just use Vim as it was designed and are perfectly comfortable with that design:
"Vim experts" have 2, 30 or 97 buffers loaded and are very happy they don't have to deal with spatial distribution;
when they need to compare two files or work in one part of the current buffer while keeping another as a reference, "Vim experts" use windows because that's how they are meant to be used;
when they need to work for a while on a separate part of the project without messing with their current view, "Vim experts" load a brand new tab page.
I used to keep every buffer in a separate tab, but I grew tired of constantly gt and gT-ing around everywhere.
I also felt that buffers were too difficult to manage.
Here are some techniques that totally changed my earlier opinion:
Buffer management: :b. You get surprisingly fast at this. See vim, switching between files rapidly using vanilla Vim (no plugins)
Jump/Change lists (ctrl o/i and g;)
Alternate file (^)
tpope's Unimpaired plugin. Convenient mappings for flying through your buffers (among others).
Here is my typical workflow:
Open Vim, and use :e (usually with a regex like :e src/**/F*Bar.js) to open a buffer
Realize I need to open another file. Use :e for that as well. If I want to toggle between this buffer and the currently open buffer I will use :sp or :vsp to open it in a separate window.
Repeat until I've got the 3-5 files that I will be switching between using the techniques in the above bulleted list to fly between your buffers.
If I want to "start over" with my buffers, just close Vim and re-open.
I felt that after a week or so of forcing these new patterns, it became much easier to visualize which buffers I had open, and how to get to any one of them in only a few automatic strokes.
Tosses 2c into the pile.
TLDR; :b *part-of-filename* is the best way to find a file you need in the buffer list i.e. it is FASTER and has LESS cognitive load than buffer numbers, tabs, or windows for tracking files.
It's nothing for me to have 30 buffers open (I.e. I haven't been housekeeping), and the beauty of buffers used-well is that it doesn't slow me down at all. In fact, it speeds things up when four days after I opened the file I need it, call :b *part-of-filename* and it magically appears, impressing co-workers and toady collectivists alike.
Buffers are for files.
To be effective:
Open an important first file from a devilishly well chosen root directory
Open subsequent files with :e
Use ls ALL the time when you first start to get a good mental model (you can't grok what you can't see, mentally or literally)
Never :q, it blows
Enter :b into your muscle memory
:b1 is good for the first file you know you opened, otherwise numbers and letters get clumsy quick
:b# is good for switching to your last file, which is a common need
:bd# is good for when you've switched to a temp file, done what you needed to do, switched back with :b#, and now want to close that temp file
:b *part-of-filename* is otherwise the best way to find a file you need in the list i.e. it is FASTER and has LESS cognitive load than buffer numbers, tabs, or windows for tracking files.
The only annoyance of :b *part-of-filename* is that sometimes you haven't opened the file yet, and you need to go back and :e path/to/full-filename first.
Tabs are for differentiating truly unrelated files.
Or keeping a particular windows layout handy (disclaimer: I've never used it for this myself).
Or for files rarely used, but predictably needed. For me, that's usually a commitMessage file that I annotate as I work so I don't have to do too much thinking when it comes time to make a commit. gt is faster than :b com<enter> (if you're feeling lucky, otherwise :b com<tab><enter>)
:tabe commitMessage
gt or gT also a muscle memory favorite
Window splits are for visually comparing information
Or having immediate access to important information (truthfully, unless that info is somehow something I need to live update with :e i.e. a log file, I usually just pull the content into the current file and deal with it there).
:vsp or C-w v opens a vertical split i.e. left | right, then use :b or :e to get the file you want
:sp or C-w s open a horizontal split i.e. top / bottom
C-w C-w i.e. double Ctrl-w, rotates you around the available windows
C-w c close current window
C-w o close all other windows, keep current ONLY
The downside of tabs is that you can only see the contents of one at a time. So if you use them like in a browser, you're losing out on viewing multiple buffers side by side, or even viewing separate parts of the same file in splits. Therefore, many recommend to use tabs only to segregate different workspaces (e.g. have one for a Java project, another for a todo list, a third to hack on a script on the side).
The problems you describe make it appear that you're using Vim wrong. Either have (mostly) a single, dedicated instance. Then, buffers that become hidden will simply "reappear" if you re-edit them (and you can now use the buffer list to recall them), and there won't be swap file messages. Or, use separate Vim instances per project / file / edit session, but then make it a habit to fully :quit each instance when you're done with the file.
Another tip, when using the buffer name as the argument to :buffer, you don't have to specify entire names. However, if more than one buffer matches the given argument, the buffers won't be switched.
Any fragment of the buffer name can be used to match. For example, if you have the buffers request_manager.java and queue_manager.java then :buffer que or :b que matches both of them, but will switch to queue_manager.java as it matches at the beginning.
Tabs and Buffers are two different standards in Vi.
Read these three definitions:
A buffer is the in-memory text of a file
A window is a viewport on a buffer.
A tab page is a collection of windows.
Read this article for more https://joshldavis.com/2014/04/05/vim-tab-madness-buffers-vs-tabs/
I use tabs, Ctrl-P and Vim sessions in my workflow and have for over a year now:
I have ) and ( mapped to "go to next tab" and "go to previous tab" respectively. tn opens a new tab. I also make use of tabm to help keep things organized.
I use Vim sessions for groups of files relating to the current story/bug I'm working on, usually done by category. These sessions get overwritten during the course of the process.
I have yet to find anything better than Ctrl-P, but it does take a bit to process all the files for finding.
I would like to suggest a brillent implementation from a good number of years ago: kien/tabman.vim. It clarifies the following:
One can have as many buffers that are carefully hidden, somewhere;
By design, tabs are meant to display bufferes in creative ways.
With some proper tabline plugin, one can display all the hidden buffers at the top row (tabline);
Per my experience with vim-airline, the tabline will show very few relevant information when I create a new tab.
Two tags will occupy the tabline slot, side by side, wasting the rest of the horizontal spaces
Worst still, I no longer have any idea of what are the buffers that are hidden.
It has been a wonderful rediscovery of this magic plugin, which should have been staying in my Vim configuration for a good number of years as well.
While I would continue to look for some thing that also displays all the hidden buffers, TabMan is my superman when it comes to having a bird's eye view of how buffers were arranged across different tabs.
I load "selected" buffers as tabs to quickly (TAB/S-TAB) toggle between them.
The framework of workspaces fits here as for me buffers VS tabs is mostly the visibility thing. I can pop important/work files in windows and tabs and hide the ones I don't currently need to utilize in the background on the fly without having to remember paths or take time to search and load them up again once the need arises. This allows for handling several tasks or projects in one VIM session, I guess this used to be important in low-memory machines but is also good for concentrating all editing tasks under one application frame. I also have buffer shifting shortcuts set to Ctrl-Right/Left so I can quickly shift through various buffers as well.
Bottom line, one can only split up to some windows for his uses as much as screen estate goes, but one can hold multiple windows settings in several tabs thus expanding one's workspace and improving workflow allowing the convenient division of complicated tasks revolving more than one file.
For the swap files, you can tell VIM to keep all of them in one folder of your designation. For this use :set directory.
Add these to your .vimrc and start loving buffers:
:nnoremap <Tab> :n<cr>
:nnoremap <S-Tab> :N<cr>
That way you can cycle forward/backward through them in normal mode via Tab/ShiftTab.
Am used to IDE style tab'd panels and am hitting some arggghh inducing scenarios with vim when trying to replicate this functionality using buffers and splits.
I have the following relevant .vimrc settings:
set hidden
set switchbuf=useopen,usetab
Now, let's say I open up 4 buffers, split vertically and then horizontally so that 1 buffer displays on the left and 2 buffers display stacked on the right. The 4th buffer is hidden (opened on the left split).
With the cursor in the left split, using :bnext and :bprevious rotates through all buffers in the left split; that's not desirable as I really have no use for seeing the same file contents in 2 different splits (is there a way to opt-in to the vim cloned buffer affect?). Using :sbnext and :sbprevious works great for visible buffers, but as soon as a hidden buffer is encountered then it opens up in a new split thus wreaking havoc on my layout. The problem gets worse when working with 10+ buffers.
Ideally I'd like to rotate through all buffers visible and hidden within a given split (i.e. where the buffers were opened).
Suggestions appreciated.
p.s. am trying out vim ctrl-space plugin now, quite good but does not address above issue.
Thanks
Why rotate through the buffers when you can go directly to the one you want via :buffer command?
:b foo
:b take either a buffer number or a partial filename (with globs too!). I recommend the partial filename approach. You can also use tab completion to distinguish between ambiguous partial filenames.
You can use :sbuffer (:sb for short) the same way but to open a split instead.
For more help see:
:h :b
:h :sb
The basic navigation unit is the buffer. Windows and tab pages are abstractions built on top of buffers that introduce their own good and bad idiosyncrasies and, most of the time, don't play well with traditional buffers.
You are having troubles because you are trying to apply buffer commands to a window-centered workflow.
As soon as you split your workspace in more than one window you are bound to use window commands for navigation and tab-navigation becomes your standard as soon as you use tab pages. As you noticed, not only is it hard (impossible, AFAIK) to make buffer-navigation window/tab-aware but the alternative techniques actually lack quite a bit in terms of power.
The 4th buffer is hidden (opened on the left split).
That's your first problem: that 4th buffer is hidden and thus transient. It is not opened in any window and could be displayed in any window. You can choose to display a specific buffer in a specific window but you can't really "pin" it to that window.
With the cursor in the left split, using :bnext and :bprevious rotates through all buffers in the left split; that's not desirable as I really have no use for seeing the same file contents in 2 different splits (is there a way to opt-in to the vim cloned buffer affect?).
Again, you are using buffer commands that don't care at all about windows and tab pages.
Using :sbnext and :sbprevious works great for visible buffers, but as soon as a hidden buffer is encountered then it opens up in a new split thus wreaking havoc on my layout.
Again, the wrong tool for the job.
It is possible to keep as many window-local argument lists as you have windows and use those lists with :next and :previous, though, but that would require quite a bit of focus and forethinking. Maybe there's a plugin for that? Anyway:
Create your layout:
:vs|sp
Go back to the large window on the left:
<C-w>w
Put two files in the local argument list:
:arglocal aaa.txt bbb.txt
Move to the next window, edit your local argument list and repeat:
<C-w>w
:arglocal ccc.txt ddd.txt
<C-w>w
:arglocal eee.txt fff.txt
You can now do :next and :previous to switch arguments or <C-^> to switch to the alternate file.
Note that, while you were able to "force" somehow your buffers to specific windows, you are now seriously limited in your ability to navigate around and you now have to deal with a multi-dimensional construction that's rather fragile and requires to too many braincells.
You should consider working with Vim and not against it by using straight buffers as much as possible.
I'm using vim dwm plugin, and it is working very well for my workflow. I'm used to open a lot of buffers in the same window. With this plugin I can manage all of them with easy. I'm using vim-ctrlspace plugin too, and this two plugins are wonderful working together. Well, that's it. I hope this help!
This is how I use vim's tabs:
I have shortcuts to move a tab to left/right with <ctrl>j <ctrl>k and to move between tabs with <ctrl>h, <ctrl>l. According to answer to this question, I'm doing it wrong. How to effectively use buffers then? Constantly listing hidden buffers to know which to switch to doesn't seem like an imprevement.
There is no right or wrong way of handling buffers in Vim. First, learn and understand the difference between buffers, windows, and tab pages. Then adopt a style that suits you. There are many "buffer management" plugins on http://www.vim.org/, but you can also just use the built-in commands like :buffer together with file completion.
If you solely stick to the "one file per tab" rule (like in a browser), you're losing the benefits of window splits, and you'll still occasionally encounter splits in the form of the preview and quickfix windows, and in order to use diff mode.
I mostly use tab pages to separate different workspaces (I only have a single GVIM instance running); sometimes I open the same set of buffers in different tabs in different arrangements, like the perspectives in IDEs such as Eclipse.
I have a list of buffer in vim, how can I turn all of them into tab page like ones in, say Notepad++?
I know I can use :tabe or something to open new file in tab view, but what if I have opened several buffers in single vim and I want to turn all of them into tab pages?
You can type this command:
:tab ball
It will display all buffers in tabs.
If I understood, you have several buffers in splits and wish every one of them in a separate tab. <Ctrl-w>T will open a buffer in a new tab page removing it from the split.
But tab pages are really not what they are in Notepad++ - separate files. In Vim they're more of a placeholders for splits, so my guess is you'll have a hard time working with them if you mean to just copy your Notepad++'s way of work to Vim.
I don't know your motivations of to turn all buffers into tab pages. Usually, we have many buffers when doing one job, but for tabs, I think it don't have enough spaces to display the tabbars, especially in laptop. Imaging if there were 20 tabs on the top...
So if you want to turn the current buffer into tab page, you can use :tab split. I think it is what you exactly need.
You can see why-do-vim-experts-prefer-buffers-over-tabs for more help.
In Using vim's tabs like buffers:
This is not how vim's tabs are
designed to be used. In fact, they're
misnamed. A better name would be
"viewport" or "layout", because that's
what a tab is -- it's a different
layout of windows of ALL of your
existing buffers.
If each tab in vim is just a different layout of all existing buffers (so doing :ls in each tab, shows the same list), isn't the existence of tabs in vim useless? If I can use plugins to handle buffers like minibufexplorer and such, why do tabs exist? Shouldn't at least buffers opened in a tab be shown when doing :ls only on that tab (acting somehow like a "workspace" feature)?
I think that having multiple tabs with different files opened, but when trying to do :bn on the tabs it goes to all opened buffers, it becomes a mess. Some people like to open different tabs for each "domain" of problem when developing, but I to me it would be really useful if it was possible to have a different buffer list for each tab in Vim.
(I have search SO a lot, and couldn't find WHY tabs exist, only "stop using tabs in vim like tabs in others editors, use buffers instead", so why do tabs in vim were implemented? That's why I don't think this question is a duplicate)
Summarizing... How do you feel about this subject - usefulness of tabs in Vim when programming? How do you use it?
Tabs can each have their own working directory which makes grouping and working with similar groups of files much more convenient.
Also, directly from :help tabpage:
Tabs are also a nice way to edit a buffer temporarily without changing
the current window layout. Open a new tab page, do whatever you want
to do and close the tab page.
I use tabs often, and use them to logically group files.
For instance, I'll open views or HTML in one tab, in another have the associated controllers and another has the associated models. Then I'll save out the layout using :mksession! and reload it later with the -S flag.
Other times I'll use tabs to keep one of vim's help pages open just so it's immediately available.
I think the main thing is tabs allow you to organize your buffers in a different way than using split windows and that flexibility allows vim to work with more people's brains, because we all think differently.
This answer to a related question might help: Using Vim's tabs like buffers
I normally use the -O flag to open files in split windows, but if you insist on opening them in separate tabs you can use -p. I prefer splits because I can easily see two separate files side by side, something you can't do with tabs.
And finally, here's some key defs I use to make it easy to move between splits:
" Switch between window splits using big J or K and expand the split to its
" full size.
"
" Move vertically in the window through the horizontal splits...
map <C-J> <C-w>j<C-w>_
map <C-K> <C-w>k<C-w>_
" Move horizontally in the window through the vertical splits...
map <C-H> <C-w>h<C-w>\|
map <C-L> <C-w>l<C-w>\|
I normally use tabs when my current view is split as much as it can while still allowing me to read and program efficiently. Most of the time it is there so that I have quick access to the information of that file (generally some kind of include file).
I rarely use tabs for actual development but rather a placeholder for information that I want to occasionally look at.
So normaly I have
Tab0 -> source file and test file
Tab1 -> include file and sometimes a related interface file