Clarification: A "window-local buffer" in this context just means a buffer once loaded into a specific window, any other buffer not ever loaded into that window is not a "window-local buffer".
I had some ruminations on ways managing buffers earlier and I think having a "window-local" buffer list would provide an extra way managing buffers. By saying that, I'm not interested in ways managing buffers already provided by Vim.
And it seems the solution is straightforward by recording "window-local" buffers manually like autocmd BufWinEnter * call add(w:buffers, expand('%')) and providing corresponding interfaces to the "window-local" buffer list w:buffers.
Do you find this useful? And any suggestion would be appreciated.
To list all open buffers use this:
:buffers
To open buffer #5 use this:
:buffer 5
You can use the following mapping to combine the two commands:
:nnoremap <F5> :buffers<CR>:buffer<Space>
How to use this convenient mapping:
press F5
enter a buffer number
press <Enter>
More reading here. (search for "switching by number")
The buffer list is global. You can have a window-local argument list (with :arglocal), and then use commands like :next to navigate through them.
Related
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.
When I am using vim buffers, I like to look at the status bar instead of using :ls to see which number is associated with the vim buffer.
This becomes problematic when there are multiple files of the same name. Then, the status bar for vim-airline will show:
4: handler.py 10: handler.py 22: handler.py
Is there a way to show some part of the filepath when there are files of the same name?
Surprisingly, I thought this would be a common issue but could not find a solution online.
Thanks
You are basically using airline to create some kind lookup table. This means you have to not only find your file on the status bar but remember a buffer number and buffer numbers are lame.
The many ways to switching buffers
:sb and :b both can take partial names and globs. e.g. :sb foo*
:b/:sb use tab completion when used with partial names
Use :sb to switch and split to a buffer you already opened.
Use :ls and :b together in a mapping: nnoremap <leader>b :ls<cr>:b<space>
<c-6> will go the the previous buffer (can also take an optional buffer number)
Map :bnext and :bprev example [b and ]b are Unimpaired.vim mappings
set hidden make switching buffers easier. Don't worry vim will let you know if you have unwritten buffer before exiting
Use capital letter marks to jump back to buffers where you know you will jump back to.
Use tags to jump to definitions.
Possibly use cscope along with tags
Look into fuzzy finder plugsin like CtrlP, Command-T, and Unite to switch buffers
I usually like to use buffer numbers to go to buffers quickly. Unfortunately, after many searches, opening some files, etc., the buffer numbers get crazy:
Is there anyway to assign buffer numbers manually?
Is there anyway to restart buffer numbering?
Thanks.
"the buffer numbers get crazy" Tell me about it! By the end of the day I'm easy over 100 buffers. But luckily, as you can see in this animation, you have tab completion for buffer names.
So, even though you can't renumber the buffers, you can still jump around easily.
It's also worth noting that it is doing *str* matching so I didn't have to search on "se" to go straight to that file. Typing :b uptab would have also taken me straight there. If there are more than one match, subsequent tabs will cycle over the matches (circularly). So, in this session I could cycle over my "test" files or my "py" files if I wished. This is BETTER than renumbering once you learn it!
It is not possible to assign buffer numbers manually, or reassign them for that matter. The only way to restart buffer numbering is to restart vim. You might be interested in the SelectBuf script.
I think I figured out a way to do this. Use mksession: {session_filename}, close out your session, open {session_filename}, Look for the lines with badd {filename}, add/edit/delete/arrange these lines, then open it again with vim -S {session_filename}. The buffers will be in the new order. Be careful with deleting if it was a current or active file. I will be referenced in other places.
Try bufferexplorer plugin for vim. It's also usefull to map some keys to Fx keys,here's an example:
"Bufexplorer mapings
nmap <F5> <Esc>:BufExplorer<cr>
vmap <F5> <esc>:BufExplorer<cr>
imap <F5> <esc>:BufExplorer<cr>
" F6 - previous buffer
nmap <F6> :bp<cr>
vmap <F6> <esc>:bp<cr>i
imap <F6> <esc>:bp<cr>i
" F7 - next buffer
nmap <F7> :bn<cr>
vmap <F7> <esc>:bn<cr>i
imap <F7> <esc>:bn<cr>i
You could try this buffer-enancment plugin.
It is a small layer over native buffer switching that lets you assign buffers numbers and recall them by that number like such:
assign current buffer to the number 1
1<leader><C-6>
when you want to load that buffer switch to it like you would normally switch to buffer 1
1<C-6>
It works by saving a dictionary of the buffers you assign loading them instead of the regular buffer if one is present. If the key is not present it will simply try to load the buffer with that number.
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!
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.