Faster Buffer Switches in Vim
I've tried several times in the past to use various buffer management plugins like the very popular minibufexplorer and bufexplorer only to find myself not using them or forgetting to use them after a few days. It seems that the normal "switch by name or number" method is faster and more convenient for me for some unknown reason. I can see how these plugins could be useful if your current number of open buffers gets huge, but until then I think they just take up valuable screen real estate (I'm pretty stingy about my screen space).
Buffers inherit their names from their file names. You can switch buffers
by entering :b {name}
or by :b {N}
where {name}
is either the
full or partial buffer name that you desire (filename), and {N}
is
the buffer number. This by default has a number of issues.
- Buffer numbers are difficult to remember unless you are a robot. Especially if the number of buffers is large.
- If you have two buffers named
file1
andfile2
and you attempt to switch buffers with a command like:b file
you will get an error message stating that there is more than one buffer matching that pattern. - If you have a buffer named
Foo
and you attempt to switch to it with a command like:b foo
it will not work. Switching buffers by name is case sensitive.
:ls
list because
they have been closed with the :bdelete
command. I figure if I delete
the buffer then I don't want to use it anymore. I only want to select a
buffer from the listed ones.
Finally, I added a global variable called g:BufSel_Case_Sensitive
that
controls whether the match is case sensitive or not. It defaults to false,
but can be changed anywhere (like your ~/.vimrc
for example). This
makes it much easier to swap if your edited file names contain a mix of
upper and lower case characters.
The final product looks like this:
function! BufSel(pattern) let buflist = [] let bufcount = bufnr("$") let currbufnr = 1 while currbufnr <= bufcount if(buflisted(currbufnr)) let currbufname = bufname(currbufnr) if (exists("g:BufSel_Case_Sensitive") == 0 || g:BufSel_Case_Sensitive == 0) let curmatch = tolower(currbufname) let patmatch = tolower(a:pattern) else let curmatch = currbufname let patmatch = a:pattern endif if(match(curmatch, patmatch) > -1) call add(buflist, currbufnr) endif endif let currbufnr = currbufnr + 1 endwhile if(len(buflist) > 1) for bufnum in buflist echo bufnum . ": ". bufname(bufnum) endfor let desiredbufnr = input("Enter buffer number: ") if(strlen(desiredbufnr) != 0) exe ":bu ". desiredbufnr endif elseif (len(buflist) == 1) exe ":bu " . get(buflist,0) else echo "No matching buffers" endif endfunction command! -nargs=1 -complete=buffer Bs :call BufSel("<args>")It's not a real complicated function, but it does add a lot of flexibility when switching buffers via the command line. I added the following line in my
~/.vimrc
to replace the already existing command when typed:
cabbr b BsSo now when I type
:b
(notice the space) it is replaced by :Bs
automatically and the function is run instead of the built-in buffer
command. This suggestion was also taken from the comments in the tip page
above, and it works quite well.
exactly what i needed! Thanks!
ReplyDeletewas looking for a script for partial buffer search, rather than using the expensive Find because I had to type in the entire file path when using :b. thanks!
ReplyDeleteOne thing nice about :b is if you press afterwards you get a list of buffers.. If you use the override :Bs, this functionality is lost. Anyway to have the completion still work?
ReplyDelete