VIM command to explore buffers - vim

I often use the command :Explore to switch to another file. I also use a lot the command :buffer to switch between previously opened files, but it is not always convenient when a lot of files are opened.
Is there a way to display a list of all opened files (buffers) in the current window, in a "explore" way, without using plugin?

:help :ls is the closest you can get with basic built-in tools.

I would recommend creating a normal map like this in your ~/vimrc file.
" list buffers and jump to a chosen one
nnoremap <Leader>b :ls<CR>:b<Space>
It triggers your <Leader> plus b to execute two commands at once, first it shows all open buffers, then it allows you to type the buffer number to open it. It wort reading :h leader.

Related

vim, switching between files rapidly using vanilla Vim (no plugins)

I understand that limiting myself to vanilla Vim (not using plugins) limits the power of the editor, but as I switch between different machines frequently, it is often too much trouble to move my environment around everywhere. I want to just stay in vanilla Vim.
Something that holds me back is the ability to quickly switch between files.
I (believe at least) have a good understanding of buffers, windows, tabs, as well as netrw (Vex, Ex, etc).
But in an editor such as Sublime Text, I can just type ctrl-p and instantly I am at the file.
I know that I can drop down to the shell, but I wonder if there are any other "hidden" secrets to rapidly switching between files in Vim based off more than just the filename.
The closest equivalent ("closest", not "exact") to ST2's Ctrl+P is a plugin called, get ready… CtrlP. There are other similar plugins like Command-T or FuzzyFinder.
I use CtrlP and I love it but I wholeheartedly support your decision to go "plugin-free". It's not the easiest way to go but it will pay off in the long run.
Opening files
The most basic way to open a file is :e /path/to/filename. Thankfully, you get tab-completion and wildcards: the classic * and a special one, **, which stands for "any subdirectory".
Combining all of that, you can do:
:e **/*foo<Tab>
to choose from all the files containing foo in their name under the working directory or:
:e **/*foo/*bar<Tab>
to choose from all the files containing bar in their name under any subdirectory containing foo in its name, anywhere under the working directory.
Of course, that works for :tabe[dit], :sp[lit] and :vs[plit], too.
Those commands are limited to one file, though. Use :next to open multiple files:
:next **/*.js
and take a look at :help arglist.
Jumping between buffers
:b[uffer] is the basic buffer-switching command:
:b4 " switch to buffer number 4
:bn " switch to next buffer in the buffer list
:bp " switch to previous buffer in the buffer list
:bf " switch to first buffer in the buffer list
:bl " switch to last buffer in the buffer list
:b foo<Tab> " switch by buffer name with tab-completion
:b# " switch to the alternate file
Note that many of these commands and their relatives accept a count.
The :ls command shows you a list of loaded buffers. It is a bit "special", though: buffers are assigned a number when they are created so you can have a list that looks like 1 2 5 if you delete buffers. This is a bit awkward, yes, and that makes switching to a buffer by its number a bit too troublesome. Prefer switching by partial name, :b foo<Tab> or cycling, :bn :bp.
Anyway, here is a cool mapping that lists all loaded buffers and populates the prompt for you, waiting for you to type the number of a buffer and press <enter>:
nnoremap gb :ls<CR>:b<Space>
With this mapping, switching to another buffer is as simple as:
gb
(quickly scanning the list)
3<CR>
or:
gb
(quickly scanning the list)
foo<tab><CR>
The idea comes from this image taken from Bairui's collection of Vim infographics:
Vim also has <C-^> (or <C-6> on some keyboards)—the normal mode equivalent of :b#—to jump between the current buffer and the previous one. Use it if you often alternate between two buffers.
Read all about buffers in :help buffers.
Go to declaration
Within a file, you can use gd or gD.
Within a project, Vim's "tags" feature is your friend but you'll need an external code indexer like ctags or cscope. The most basic commands are :tag foo and <C-]> with the cursor on a method name. Both tools are well integrated into Vim: see :help tags, :help ctags and :help cscope.
For what it's worth, I use tag navigation extensively to move within a project (using CtrlP's :CtrlPTag and :CtrlPBufTag commands, mostly, but the buit-in ones too) and my favorite "generic" buffer switching method is by name.
Deploying your config
A lot of Vim users put their config under version control which makes it very quick and easy to install your own config on a new machine. Think about it.
EDIT
A few months ago, I had to work on a remote machine with an outdated Vim. I could have installed a proper Vim and cloned my own beloved config but I decided to travel light, this time, in order to "sharpen the saw". I quickly built a minimalist .vimrc and revisited a couple of half forgotten native features. After that gig, I decided CtrlP wasn't that necessary and got rid of it: native features and custom mappings are not as sexy but they get the job done without much dependencies.
Juggling with files
set path=.,**
nnoremap <leader>f :find *
nnoremap <leader>s :sfind *
nnoremap <leader>v :vert sfind *
nnoremap <leader>t :tabfind *
:find is a truly great command as soon as you set path correctly. With my settings, ,ffoo<Tab> will find all the files containing foo under the current directory, recursively. It's quick, intuitive and lightweight. Of course, I benefit from the same completion and wildcards as with :edit and friends.
To make the process even quicker, the following mappings allow me to skip entire parts of the project and find files recursively under the directory of the current file:
nnoremap <leader>F :find <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>S :sfind <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>V :vert sfind <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>T :tabfind <C-R>=expand('%:h').'/*'<CR>
WARNING! The path option is extremely powerful. The value above—.,**—works for me, as a default fallback value. In the real world, the exact value of the option will differ from project/language/framework/workflow to project/language/framework/workflow, so the proper value depends entirely on your needs. Don't blindly copy that line and expect it to solve all your problems.
Juggling with buffers
set wildcharm=<C-z>
nnoremap <leader>b :buffer <C-z><S-Tab>
nnoremap <leader>B :sbuffer <C-z><S-Tab>
The mappings above list the available buffers in the "wildmenu" with an empty prompt, allowing me to either navigate the menu with <Tab> or type a few letters and <Tab> again to narrow down the list. Like with the file mappings above, the process is quick and almost friction-less.
nnoremap <PageUp> :bprevious<CR>
nnoremap <PageDown> :bnext<CR>
Those mappings speak for themselves.
Juggling with tags
nnoremap <leader>j :tjump /
This mapping uses regex search instead of whole word search so I can do ,jba<Tab> to find tag foobarbaz().
Yes, fuzzy matching is addictive but you can be just as productive without it. And for a fraction of the cost.
MORE EDIT
A couple of additional tips/tricks…
Wildmenu options
The "wildmenu", enabled with set wildmenu, makes file/buffer navigation easier. Its behavior is governed by a bunch of options that are worth investigating:
wildmode tells Vim how you want the "wildmenu" to behave:
set wildmode=list:full
wildignore filters out all the cruft:
set wildignore=*.swp,*.bak
set wildignore+=*.pyc,*.class,*.sln,*.Master,*.csproj,*.csproj.user,*.cache,*.dll,*.pdb,*.min.*
set wildignore+=*/.git/**/*,*/.hg/**/*,*/.svn/**/*
set wildignore+=tags
set wildignore+=*.tar.*
wildignorecase allows you to search for foo and find Foo:
set wildignorecase
File marks
augroup VIMRC
autocmd!
autocmd BufLeave *.css normal! mC
autocmd BufLeave *.html normal! mH
autocmd BufLeave *.js normal! mJ
autocmd BufLeave *.php normal! mP
augroup END
I recently found this gem in someone else's ~/.vimrc. It creates a file mark at the exact position of the cursor whenever you leave a buffer so that, wherever you are, 'J jumps to the latest JavaScript buffer you edited. Awesome.
The answer depends a lot on your preferences and circumstances. Some examples:
If it's mostly two files (e.g. a C header and implementation file), <C-^> is very handy. In general, the alternate file is an important concept.
If you use a large editor window, window :splits turn the problem of locating a buffer from locating the window (once you've got all buffers opened). You can use [N]<C-w><C-w> to quickly switch to it.
If you can memorize (a few) buffer numbers, the :[N]b[uffer] and :[N]sb[uffer] commands are quite handy; :ls tells you the numbers.
Plugins (or at least custom mappings) can improve things a lot, and there's a whole variety on this topic on vim.org. There are various mechanisms to distribute your config (Pathogen + GitHub, Dropbox, ...), or you could remotely edit server files through the netrw plugin that ships with Vim.
Sometimes it is also handy to go sequentially through a list of files (e.g., if you did something like vim *.php to open several files at once). Then you can use :n[ext] (as well as :prev[ious], :fir[st], and :la[st]) for navigation (in addition to what was suggested in the other answers).
You can do wildcard tab completion on the command line without any plugins. e.g.
:e src/**/foo*<tab>
will let you cycle through all the files starting with 'foo' in the directory tree under ./src and select the one you want to edit.
If you have already edited the file and it is still in a buffer then you can switch to it with:
:b foo<tab>
which will cycle through all the buffers with 'foo' in the path.
You may need to set the wildmode and wildmenu options to get the behaviour you want. I have
wildmode=longest:full
wildmenu
in my .vimrc.
If you are on a filename and want to jump to that file, gf will do it for you. I also like using ctags, which isn't a plugin; you just build the tags and can easily jump around your codebase.
If you want switch between files in vim editor, please see below answer
First press Esc key to exit from edit mode.
Then type :e to check current file path.
if you want to go another file then type :e /path-of-file.txt/ using this you are able to switch.
If you want to go previous file simply type :e# which switch to previous file path.
I had the same issue with Vim.
The last thing I want is to depend on plugins for a task as mundane as file switching.
I added the following lines to .vimrc
set path+=**
set wildmenu
And BAM! I can now :find any/filename/in/any/folder/ as long as vim is in the root directory of the project. Tab completion works. Wildcards work!
Once files are opened already, and there are a ton of buffers in the background (you could use :ls to see all buffers), running :b any/file <TAB> will fuzzy search for all buffers and jumps to the required file. In case it is not unique there will be a wildmenu of tabs (hence the 2nd line in .vimrc) which can be selected using tab.
My answer is coming from this awesome video
https://www.youtube.com/watch?v=XA2WjJbmmoM&feature=youtu.be&t=489
There are more tricks in and I recommend watching it.

Edit multiple files without splitting window

I am new to VIM.
It seems like, in order for copy and paste functionality to work between different files, one must open the files in the same VIM instance. Doing this, however, splits the terminal screen into 2. Opening a new file, splits it into 3, etc.
what happens if i have to open, say, 10+ files? how do developers who use VIM deal with this issue?
You can open files in the same vim instance and in the same window (without spliting it). That's what is called buffers. The view you see is current buffer, but the others buffers are still opened.
Here you have an introduction on how to work in vim with buffers.
Or type :help buffers in vim.
You can use some plugin to work more user friendly with vim buffers. I recommend you bufexplorer or minibufexpl.
You can as well use tabs, but I have been always more confortable with buffers, but it's just my case.
Use tabedit instead of split to open more files.
Open all your txt files in tabs:
$ vim -p *.txt
Use gtgT to switch between tabs.
Or you can put these key-mappings in your .vimrc:
nmap <C-H> gT
nmap <C-L> gt
nmap <leader>t :tabnew<CR>
Most users use splits only for simultaneous viewing of two files, when it is needed. You can open as many files as you want in different buffers, while only displaying one buffer on screen.
:e File1.txt
:e File2.txt and so on ...
and then switch through buffers with :bprevious and :bnext (and a variety of other commands). That is really the Vim's way of work.
There are many plugins for manipulating and navigating buffers.
One tab per file is really the wrong way to go ...
You will find that VIM is a very flexible and customizable tool, so there are probably several approaches to this. Personally, I like to only have one buffer open at the time (I rarely need to split up) and use the Minibufexpl plugin to keep track of how many buffers are open and switch more efficiently between them.
If your only requirement is to copy paste between files. You can do this between different instances of vim if you set clipboard=unnamed
This causes vim to use the system clipboard instead of it's own internal buffer. so you can <C-c> from firefox and then p into vim, y from one vim p into another etc.
See http://vim.wikia.com/wiki/VimTip21
If you like having the files open in the same window I would use one of the other answers here and use either buffers (instead of splits) or tabs. I personally often have 10 or more buffers open in a single gvim window and 2 split windows that I use to view the buffer that I switch between using :bn and :bp.

How to survive the transition from tabbed-based to buffer-based coding (Vim)

I recently changed from notepad++ to Vim. In notepad++ I used to be aware of my open files by
seeing them as tabs, so when I wanted to close or change them I just pressed Shift-Tab or Ctrl-W. In Vim there are also tabs, but when I use them I feel like I'm just going back to my notepad++ way of managing my files. Is there a good way of list, manage, switch and delete buffers other than splitting them?
Yep. I recommend a buffer explorer plugin as well as learning buffer commands. I use this plugin.
http://www.vim.org/scripts/script.php?script_id=42
The buffer paradigm is quite elegant once you are used to it. Less visual clutter. but you are free with vim to find your own thing
You can use these commands:
ls - list all open buffers
bp, bn - switch to the previous or next buffer
b number - switch to the buffer with that number
b text - switch to the buffer whose name includes the string text
I've tried several setups for Vim. My previous was one where I tried to use tabs instead of buffers. It was not very satisfying.
Now I've returned to buffers and for navigating files and buffers I use only the NERDTree and fuzzyfinder (I guess ex Textmate users may prefer fuzzyfinder_textmate) plugins, both are great.
For locating files I use either NERDTree bound to n or fuzzyfinder's File mode. For navigating open buffers I use fuzzfinder's buffer mode solely, bound to b.
Recently I also discovered that I could switch to the previously open buffer with Ctrl-6 (I think maybe that is Ctrl-^ on most keyboard).
There are so many ways to deal with buffers in vim.
CTRL-^ to switch between buffers.
:q is the same as Ctrl-W
For further details see http://vim.wikia.com/wiki/Easier_buffer_switching
BufferExplorerLight
" quick buffer selection including unlisted
nnoremap <leader>b :buffers!<cr>:buffer<space>
Alternatively
nnoremap <leader>b :buffer<space> <c-d>
But really you have to try FuzzyFinder!

How do I close a single buffer (out of many) in Vim?

I open several files in Vim by, for example, running
vim a/*.php
which opens 23 files.
I then make my edit and run the following twice
:q
which closes all my buffers.
How can you close only one buffer in Vim?
A word of caution: “the w in bw does not stand for write but for wipeout!”
More from manuals:
:bd
Unload buffer [N] (default: current
buffer) and delete it from
the buffer list. If the buffer was changed, this fails,
unless when [!] is specified, in which case changes are
lost.
The file remains unaffected.
If you know what you’re doing, you can also use :bw
:bw
Like |:bdelete|, but really delete the
buffer.
If this isn't made obvious by the the previous answers:
:bd will close the current buffer. If you don't want to grab the buffer list.
Check your buffer id using
:buffers
you will see list of buffers there like
1 a.php
2 b.php
3 c.php
if you want to remove b.php from buffer
:2bw
if you want to remove/close all from buffers
:1,3bw
Rather than browse the ouput of the :ls command and delete (unload, wipe..) a buffer by specifying its number, I find that using file names is often more effective.
For instance, after I opened a couple of .txt file to refresh my memories of some fine point.. copy and paste a few lines of text to use as a template of sorts.. etc. I would type the following:
:bd txt <Tab>
Note that the matching string does not have to be at the start of the file name.
The above displays the list of file names that match 'txt' at the bottom of the screen and keeps the :bd command I initially typed untouched, ready to be completed.
Here's an example:
doc1.txt doc2.txt
:bd txt
I could backspace over the 'txt' bit and type in the file name I wish to delete, but where this becomes really convenient is that I don't have to: if I hit the Tab key a second time, Vim automatically completes my command with the first match:
:bd doc1.txt
If I want to get rid of this particular buffer I just need to hit Enter.
And if the buffer I want to delete happens to be the second (third.. etc.) match, I only need to keep hitting the Tab key to make my :bd command cycle through the list of matches.
Naturally, this method can also be used to switch to a given buffer via such commands as :b.. :sb.. etc.
This approach is particularly useful when the 'hidden' Vim option is set, because the buffer list can quickly become quite large, covering several screens, and making it difficult to spot the particular buffer I am looking for.
To make the most of this feature, it's probably best to read the following Vim help file and tweak the behavior of Tab command-line completion accordingly so that it best suits your workflow:
:help wildmode
The behavior I described above results from the following setting, which I chose for consistency's sake in order to emulate bash completion:
:set wildmode=list:longest,full
As opposed to using buffer numbers, the merit of this approach is that I usually remember at least part of a given file name letting me target the buffer directly rather than having to first look up its number via the :ls command.
Use:
:ls - to list buffers
:bd#n - to close buffer where #n is the buffer number (use ls to get it)
Examples:
to delete buffer 2:
:bd2
You can map next and previous to function keys too, making cycling through buffers a breeze
map <F2> :bprevious<CR>
map <F3> :bnext<CR>
from my vimrc
Close buffer without closing the window
If you want to close a buffer without destroying your window layout (current layout based on splits), you can use a Plugin like bbye. Based on this, you can just use
:Bdelete (instead of :bdelete)
:Bwipeout (instead of :bwipeout)
Or just create a mapping in your .vimrc for easier access like
:nnoremap <Leader>q :Bdelete<CR>
Advantage over vim's :bdelete and :bwipeout
From the plugin's documentation:
Close and remove the buffer.
Show another file in that window.
Show an empty file if you've got no other files open.
Do not leave useless [no file] buffers if you decide to edit another file in that window.
Work even if a file's open in multiple windows.
Work a-okay with various buffer explorers and tabbars.
:bdelete vs :bwipeout
From the plugin's documentation:
Vim has two commands for closing a buffer: :bdelete and :bwipeout. The former removes the file from the buffer list, clears its options, variables and mappings. However, it remains in the jumplist, so Ctrl-o takes you back and reopens the file. If that's not what you want, use :bwipeout or Bbye's equivalent :Bwipeout where you would've used :bdelete.
How about
vim -O a a
That way you can edit a single file on your left and navigate the whole dir on your right...
Just a thought, not the solution...
[EDIT: this was a stupid suggestion from a time I did not know Vim well enough. Please don't use tabs instead of buffers; tabs are Vim's "window layouts"]
Maybe switch to using tabs?
vim -p a/*.php opens the same files in tabs
gt and gT switch tabs back and forth
:q closes only the current tab
:qa closes everything and exits
:tabo closes everything but the current tab
Those using a buffer or tree navigation plugin, like Buffergator or NERDTree, will need to toggle these splits before destroying the current buffer - else you'll send your splits into wonkyville
I use:
"" Buffer Navigation
" Toggle left sidebar: NERDTree and BufferGator
fu! UiToggle()
let b = bufnr("%")
execute "NERDTreeToggle | BuffergatorToggle"
execute ( bufwinnr(b) . "wincmd w" )
execute ":set number!"
endf
map <silent> <Leader>w <esc>:call UiToggle()<cr>
Where "NERDTreeToggle" in that list is the same as typing :NERDTreeToggle. You can modify this function to integrate with your own configuration.

How to effectively work with multiple files in Vim

I've started using Vim to develop Perl scripts and am starting to find it very powerful.
One thing I like is to be able to open multiple files at once with:
vi main.pl maintenance.pl
and then hop between them with:
:n
:prev
and see which file are open with:
:args
And to add a file, I can say:
:n test.pl
which I expect would then be added to my list of files, but instead it wipes out my current file list and when I type :args I only have test.pl open.
So how can I add and remove files in my args list?
Why not use tabs (introduced in Vim 7)?
You can switch between tabs with :tabn and :tabp,
With :tabe <filepath> you can add a new tab; and with a regular :q or :wq you close a tab.
If you map :tabn and :tabp to your F7/F8 keys you can easily switch between files.
If there are not that many files or you don't have Vim 7 you can also split your screen in multiple files: :sp <filepath>. Then you can switch between splitscreens with Ctrl+W and then an arrow key in the direction you want to move (or instead of arrow keys, w for next and W for previous splitscreen)
Listing
To see a list of current buffers, I use:
:ls
Opening
To open a new file, I use
:e ../myFile.pl
with enhanced tab completion (put set wildmenu in your .vimrc).
Note: you can also use :find which will search a set of paths for you, but you need to customize those paths first.
Switching
To switch between all open files, I use
:b myfile
with enhanced tab completion (still set wildmenu).
Note: :b# chooses the last visited file, so you can use it to switch quickly between two files.
Using windows
Ctrl-W s and Ctrl-W v to split the current window horizontally and vertically. You can also use :split and :vertical split (:sp and :vs)
Ctrl-W w to switch between open windows, and Ctrl-W h (or j or k or l) to navigate through open windows.
Ctrl-W c to close the current window, and Ctrl-W o to close all windows except the current one.
Starting vim with a -o or -O flag opens each file in its own split.
With all these I don't need tabs in Vim, and my fingers find my buffers, not my eyes.
Note: if you want all files to go to the same instance of Vim, start Vim with the --remote-silent option.
:ls
for list of open buffers
:bp previous buffer
:bn next buffer
:bn (n a number) move to n'th buffer
:b <filename-part> with tab-key providing auto-completion (awesome !!)
In some versions of vim, bn and bp are actually bnext and bprevious respectively. Tab auto-complete is helpful in this case.
Or when you are in normal mode, use ^ to switch to the last file you were working on.
Plus, you can save sessions of vim
:mksession! ~/today.ses
The above command saves the current open file buffers and settings to ~/today.ses. You can load that session by using
vim -S ~/today.ses
No hassle remembering where you left off yesterday. ;)
To add to the args list:
:argadd
To delete from the args list:
:argdelete
In your example, you could use :argedit test.pl to add test.pl to the args list and edit the file in one step.
:help args gives much more detail and advanced usage
I use buffer commands - :bn (next buffer), :bp (previous buffer) :buffers (list open buffers) :b<n> (open buffer n) :bd (delete buffer). :e <filename> will just open into a new buffer.
I think you may be using the wrong command for looking at the list of files that you have open.
Try doing an :ls to see the list of files that you have open and you'll see:
1 %a "./checkin.pl" line 1
2 # "./grabakamailogs.pl" line 1
3 "./grabwmlogs.pl" line 0
etc.
You can then bounce through the files by referring to them by the numbers listed, e.g.
:3b
or you can split your screen by entering the number but using sb instead of just b.
As an aside % refers to the file currently visible and # refers to the alternate file.
You can easily toggle between these two files by pressing Ctrl Shift 6
Edit: like :ls you can use :reg to see the current contents of your registers including the 0-9 registers that contain what you've deleted. This is especially useful if you want to reuse some text that you've previously deleted.
Vim (but not the original Vi!) has tabs which I find (in many contexts) superior to buffers. You can say :tabe [filename] to open a file in a new tab. Cycling between tabs is done by clicking on the tab or by the key combinations [n]gt and gT. Graphical Vim even has graphical tabs.
Things like :e and :badd will only accept ONE argument, therefore the following will fail
:e foo.txt bar.txt
:e /foo/bar/*.txt
:badd /foo/bar/*
If you want to add multiple files from within vim, use arga[dd]
:arga foo.txt bar.txt
:arga /foo/bar/*.txt
:argadd /foo/bar/*
Many answers here! What I use without reinventing the wheel - the most famous plugins (that are not going to die any time soon and are used by many people) to be ultra fast and geeky.
ctrlpvim/ctrlp.vim - to find file by name fuzzy search by its location or just its name
jlanzarotta/bufexplorer - to browse opened buffers (when you do not remember how many files you opened and modified recently and you do not remember where they are, probably because you searched for them with Ag)
rking/ag.vim to search the files with respect to gitignore
scrooloose/nerdtree to see the directory structure, lookaround, add/delete/modify files
EDIT: Recently I have been using dyng/ctrlsf.vim to search with contextual view (like Sublime search) and I switched the engine from ag to ripgrep. The performance is outstanding.
EDIT2: Along with CtrlSF you can use mg979/vim-visual-multi, make changes to multiple files at once and then at the end save them in one go.
Some answers in this thread suggest using tabs and others suggest using buffer to accomplish the same thing. Tabs and Buffers are different. I strongly suggest you read this article "Vim Tab madness - Buffers vs Tabs".
Here's a nice summary I pulled from the article:
Summary:
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.
To change all buffers to tab view.
:tab sball
will open all the buffers to tab view. Then we can use any tab related commands
gt or :tabn " go to next tab
gT or :tabp or :tabN " go to previous tab
details at :help tab-page-commands.
We can instruct vim to open ,as tab view, multiple files by vim -p file1 file2.
alias vim='vim -p' will be useful.
The same thing can also be achieved by having following autocommand in ~/.vimrc
au VimEnter * if !&diff | tab all | tabfirst | endif
Anyway to answer the question:
To add to arg list: arga file,
To delete from arg list: argd pattern
More at :help arglist
When using multiple files in vim, I use these commands mostly (with ~350 files open):
:b <partial filename><tab> (jump to a buffer)
:bw (buffer wipe, remove a buffer)
:e <file path> (edit, open a new buffer>
pltags - enable jumping to subroutine/method definitions
You may want to use Vim global marks.
This way you can quickly bounce between files, and even to the marked location in the file. Also, the key commands are short:
'C takes me to the code I'm working with,
'T takes me to the unit test I'm working with.
When you change places, resetting the marks is quick too:
mC marks the new code spot,
mT marks the new test spot.
If using only vim built-in commands, the best one that I ever saw to switch among multiple buffers is this:
nnoremap <Leader>f :set nomore<Bar>:ls<Bar>:set more<CR>:b<Space>
It perfectly combines both :ls and :b commands -- listing all opened buffers and waiting for you to input the command to switch buffer.
Given above mapping in vimrc, once you type <Leader>f,
All opened buffers are displayed
You can:
Type 23 to go to buffer 23,
Type # to go to the alternative/MRU buffer,
Type partial name of file, then type <Tab>, or <C-i> to autocomplete,
Or just <CR> or <Esc> to stay on current buffer
A snapshot of output for the above key mapping is:
:set nomore|:ls|:set more
1 h "script.py" line 1
2 #h + "file1.txt" line 6 -- '#' for alternative buffer
3 %a "README.md" line 17 -- '%' for current buffer
4 "file3.txt" line 0 -- line 0 for hasn't switched to
5 + "/etc/passwd" line 42 -- '+' for modified
:b '<Cursor> here'
In the above snapshot:
Second column: %a for current, h for hidden, # for previous, empty for hasn't been switched to.
Third column: + for modified.
Also, I strongly suggest set hidden. See :help 'hidden'.
I use the same .vimrc file for gVim and the command line Vim. I tend to use tabs in gVim and buffers in the command line Vim, so I have my .vimrc set up to make working with both of them easier:
" Movement between tabs OR buffers
nnoremap L :call MyNext()<CR>
nnoremap H :call MyPrev()<CR>
" MyNext() and MyPrev(): Movement between tabs OR buffers
function! MyNext()
if exists( '*tabpagenr' ) && tabpagenr('$') != 1
" Tab support && tabs open
normal gt
else
" No tab support, or no tabs open
execute ":bnext"
endif
endfunction
function! MyPrev()
if exists( '*tabpagenr' ) && tabpagenr('$') != '1'
" Tab support && tabs open
normal gT
else
" No tab support, or no tabs open
execute ":bprev"
endif
endfunction
This clobbers the existing mappings for H and L, but it makes switching between files extremely fast and easy. Just hit H for next and L for previous; whether you're using tabs or buffers, you'll get the intended results.
If you are going to use multiple buffers, I think the most important thing is to
set hidden
so that it will let you switch buffers even if you have unsaved changes in the one you are leaving.
I use the following, this gives you lots of features that you'd expect to have in other editors such as Sublime Text / Textmate
Use buffers not 'tab pages'. Buffers are the same concept as tabs in almost all other editors.
If you want the same look of having tabs you can use the vim-airline plugin with the following setting in your .vimrc: let g:airline#extensions#tabline#enabled = 1. This automatically displays all the buffers as tab headers when you have no tab pages opened
Use Tim Pope's vim-unimpaired which gives [b and ]b for moving to previous/next buffers respectively (plus a whole host of other goodies)
Have set wildmenu in your .vimrc then when you type :b <file part> + Tab for a buffer you will get a list of possible buffers that you can use left/right arrows to scroll through
Use Tim Pope's vim-obsession plugin to store sessions that play nicely with airline (I had lots of pain with sessions and plugins)
Use Tim Pope's vim-vinegar plugin. This works with the native :Explore but makes it much easier to work with. You just type - to open the explorer, which is the same key as to go up a directory in the explorer. Makes navigating faster (however with fzf I rarely use this)
fzf (which can be installed as a vim plugin) is also a really powerful fuzzy finder that you can use for searching for files (and buffers too). fzf also plays very nicely with fd (a faster version of find)
Use Ripgrep with vim-ripgrep to search through your code base and then you can use :cdo on the results to do search and replace
My way to effectively work with multiple files is to use tmux.
It allows you to split windows vertically and horizontally, as in:
I have it working this way on both my mac and linux machines and I find it better than the native window pane switching mechanism that's provided (on Macs). I find the switching easier and only with tmux have I been able to get the 'new page at the same current directory' working on my mac (despite the fact that there seems to be options to open new panes in the same directory) which is a surprisingly critical piece. An instant new pane at the current location is amazingly useful. A method that does new panes with the same key combos for both OS's is critical for me and a bonus for all for future personal compatibility.
Aside from multiple tmux panes, I've also tried using multiple tabs, e.g. and multiple new windows, e.g. and ultimately I've found that multiple tmux panes to be the most useful for me. I am very 'visual' and like to keep my various contexts right in front of me, connected together as panes.
tmux also support horizontal and vertical panes which the older screen didn't (though mac's iterm2 seems to support it, but again, the current directory setting didn't work for me). tmux 1.8
In my and other many vim users, the best option is to,
Open the file using,
:e file_name.extension
And then just Ctrl + 6 to change to the last buffer. Or, you can always press
:ls to list the buffer and then change the buffer using b followed by the buffer number.
We make a vertical or horizontal split using
:vsp for vertical split
:sp for horizantal split
And then <C-W><C-H/K/L/j> to change the working split.
You can ofcourse edit any file in any number of splits.
I use the command line and git a lot, so I have this alias in my bashrc:
alias gvim="gvim --servername \$(git rev-parse --show-toplevel || echo 'default') --remote-tab"
This will open each new file in a new tab on an existing window and will create one window for each git repository.
So if you open two files from repo A, and 3 files from repo B, you will end up with two windows, one for repo A with two tabs and one for repo B with three tabs.
If the file you are opening is not contained in a git repo it will go to a default window.
To jump between tabs I use these mappings:
nmap <C-p> :tabprevious<CR>
nmap <C-n> :tabnext<CR>
To open multiple files at once you should combine this with one of the other solutions.
I use multiple buffers that are set hidden in my ~/.vimrc file.
The mini-buffer explorer script is nice too to get a nice compact listing of your buffers. Then :b1 or :b2... to go to the appropriate buffer or use the mini-buffer explorer and tab through the buffers.
have a try following maps for convenience editing multiple files
" split windows
nmap <leader>sh :leftabove vnew<CR>
nmap <leader>sl :rightbelow vnew<CR>
nmap <leader>sk :leftabove new<CR>
nmap <leader>sj :rightbelow new<CR>
" moving around
nmap <C-j> <C-w>j
nmap <C-k> <C-w>k
nmap <C-l> <C-w>l
nmap <C-h> <C-w>h
I made a very simple video showing the workflow that I use. Basically I use the Ctrl-P Vim plugin, and I mapped the buffer navigation to the Enter key.
In this way I can press Enter in normal mode, look at the list of open files (that shows up in a small new window at the bottom of the screen), select the file I want to edit and press Enter again. To quickly search through multiple open files, just type part of the file name, select the file and press Enter.
I don't have many files open in the video, but it becomes incredibly helpful when you start having a lot of them.
Since the plugin sorts the buffers using a MRU ordering, you can just press Enter twice and jump to the most recent file you were editing.
After the plugin is installed, the only configuration you need is:
nmap <CR> :CtrlPBuffer<CR>
Of course you can map it to a different key, but I find the mapping to enter to be very handy.
I would suggest using the plugin
NERDtree
Here is the github link with instructions.
Nerdtree
I use vim-plug as a plugin manager, but you can use Vundle as well.
vim-plug
Vundle
When I started using VIM I didn't realize that tabs were supposed to be used as different window layouts, and buffer serves the role for multiple file editing / switching between each other. Actually in the beginning tabs are not even there before v7.0 and I just opened one VIM inside a terminal tab (I was using gnome-terminal at the moment), and switch between tabs using alt+numbers, since I thought using commands like :buffers, :bn and :bp were too much for me. When VIM 7.0 was released I find it's easier to manager a lot of files and switched to it, but recently I just realized that buffers should always be the way to go, unless one thing: you need to configure it to make it works right.
So I tried vim-airline and enabled the visual on-top tab-like buffer bar, but graphic was having problem with my iTerm2, so I tried a couple of others and it seems that MBE works the best for me. I also set shift+h/l as shortcuts, since the original ones (moving to the head/tail of the current page) is not very useful to me.
map <S-h> :bprev<Return>
map <S-l> :bnext<Return>
It seems to be even easier than gt and gT, and :e is easier than :tabnew too. I find :bd is not as convenient as :q though (MBE is having some problem with it) but I can live with all files in buffer I think.
Most of the answers in this thread are using plain vim commands which is of course fine but I thought I would provide an extensive answer using a combination of plugins and functions that I find particularly useful (at least some of these tips came from Gary Bernhardt's file navigation tips):
To toggle between the last two file just press <leader> twice. I recommend assigning <leader> to the spacebar:
nnoremap <leader><leader> <c-^>
For quickly moving around a project the answer is a fuzzy matching solution such as CtrlP. I bind it to <leader>a for quick access.
In the case I want to see a visual representation of the currently open buffers I use the BufExplorer plugin. Simple but effective.
If I want to browse around the file system I would use the command line or an external utility (Quicklsilver, Afred etc.) but to look at the current project structure NERD Tree is a classic. Do not use this though in the place of 2 as your main file finding method. It will really slow you down. I use the binding <leader>ff.
These should be enough for finding and opening files. From there of course use horizontal and vertical splits. Concerning splits I find these functions particularly useful:
Open new splits in smaller areas when there is not enough room and expand them on navigation. Refer here for comments on what these do exactly:
set winwidth=84
set winheight=5
set winminheight=5
set winheight=999
nnoremap <C-w>v :111vs<CR>
nnoremap <C-w>s :rightbelow split<CR>
set splitright
Move from split to split easily:
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>
if you're on osx and want to be able to click on your tabs, use MouseTerm and SIMBL (taken from here). Also, check out this related discussion.
You can be an absolute madman and alias vim to vim -p by adding in your .bashrc:
alias vim="vim -p"
This will result in opening multiple files from the shell in tabs, without having to invoke :tab ball from within vim afterwards.
To open 2 or more files with vim type: vim -p file1 file2
After that command to go threw that files you can use CTRL+Shift+↑ or ↓ , it will change your files in vim.
If u want to add one more file vim and work on it use: :tabnew file3
Also u can use which will not create a new tab and will open file on screen slicing your screen: :new file3
If u want to use a plugin that will help u work with directories
and files i suggest u NERDTree.
To download it u need to have vim-plug so to download other plugins also NERDTree to type this commands in your ~/.vimrc.
let data_dir = has('nvim') ? stdpath('data') . '/site' : '~/.vim'
if empty(glob(data_dir . '/autoload/plug.vim'))
silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif
call plug#begin('~/.vim/plugged')
Plug 'scrooloose/nerdtree'
call plug#end()
Then save .vimrc via command :wq , get back to it and type: :PlugInstall
After that the plugins will be installed and u could use your NERDTree with other plugins.

Resources