Blame | Last modification | View Log | RSS feed
"=== VIM BUFFER LIST SCRIPT 1.2 ================================================"= Copyright(c) 2005, Robert Lillack <rob@lillack.de> ="= Redistribution in any form with or without modification permitted. ="= ="= INFORMATION ================================================================="= Upon keypress this script display a nice list of buffers on the left, which ="= can be selected with mouse or keyboard. As soon as a buffer is selected ="= (Return, double click) the list disappears. ="= The selection can be cancelled with the same key that is configured to open ="= the list or by pressing 'q'. Movement key and mouse (wheel) should work as ="= one expects. ="= Buffers that are visible (in any window) are marked with '*', ones that are ="= Modified are marked with '+' ="= ="= USAGE ======================================================================="= Put this file into you ~/.vim/plugin directory and set up up like this in ="= your ~/.vimrc: ="= ="= NEEDED: ="= map <silent> <F3> :call BufferList()<CR> ="= OPTIONAL: ="= let g:BufferListWidth = 25 ="= let g:BufferListMaxWidth = 50 ="= hi BufferSelected term=reverse ctermfg=white ctermbg=red cterm=bold ="= hi BufferNormal term=NONE ctermfg=black ctermbg=darkcyan cterm=NONE ="===============================================================================if exists('g:BufferListLoaded')finishendiflet g:BufferListLoaded = 1if !exists('g:BufferListWidth')let g:BufferListWidth = 20endifif !exists('g:BufferListMaxWidth')let g:BufferListMaxWidth = 40endif" toggled the buffer list on/offfunction! BufferList()" if we get called and the list is open --> close itif bufexists(bufnr("__BUFFERLIST__"))exec ':' . bufnr("__BUFFERLIST__") . 'bwipeout'returnendiflet l:bufcount = bufnr('$')let l:displayedbufs = 0let l:activebuf = bufnr('')let l:activebufline = 0let l:buflist = ''let l:bufnumbers = ''let l:width = g:BufferListWidth" iterate through the bufferslet l:i = 0 | while l:i <= l:bufcount | let l:i = l:i + 1let l:bufname = bufname(l:i)if strlen(l:bufname)\&& getbufvar(l:i, '&modifiable')\&& getbufvar(l:i, '&buflisted')" adapt width and/or buffer nameif l:width < (strlen(l:bufname) + 5)if strlen(l:bufname) + 5 < g:BufferListMaxWidthlet l:width = strlen(l:bufname) + 5elselet l:width = g:BufferListMaxWidthlet l:bufname = '...' . strpart(l:bufname, strlen(l:bufname) - g:BufferListMaxWidth + 8)endifendifif bufwinnr(l:i) != -1let l:bufname = l:bufname . '*'endifif getbufvar(l:i, '&modified')let l:bufname = l:bufname . '+'endif" count displayed bufferslet l:displayedbufs = l:displayedbufs + 1" remember buffer numberslet l:bufnumbers = l:bufnumbers . l:i . ':'" remember the buffer that was active BEFORE showing the listif l:activebuf == l:ilet l:activebufline = l:displayedbufsendif" fill the name with spaces --> gives a nice selection bar" use MAX width here, because the width may change inside of this 'for' loopwhile strlen(l:bufname) < g:BufferListMaxWidthlet l:bufname = l:bufname . ' 'endwhile" add the name to the listlet l:buflist = l:buflist . ' ' .l:bufname . "\n"endifendwhile" generate a variable to fill the buffer afterwards" (we need this for "full window" color :)let l:fill = "\n"let l:i = 0 | while l:i < l:width | let l:i = l:i + 1let l:fill = ' ' . l:fillendwhile" now, create the buffer & set it upexec 'silent! ' . l:width . 'vne __BUFFERLIST__'setlocal noshowcmdsetlocal noswapfilesetlocal buftype=nofilesetlocal bufhidden=deletesetlocal nobuflistedsetlocal nomodifiablesetlocal nowrapsetlocal nonumber" set up syntax highlightingif has("syntax")syn clearsyn match BufferNormal / .*/syn match BufferSelected /> .*/hs=s+1hi def BufferNormal ctermfg=black ctermbg=whitehi def BufferSelected ctermfg=white ctermbg=blackendifsetlocal modifiableif l:displayedbufs > 0" input the buffer list, delete the trailing newline, & fill with blank linesput! =l:buflist" is there any way to NOT delete into a register? bummer..."norm Gdd$norm GkJwhile winheight(0) > line(".")put =l:fillendwhileelselet l:i = 0 | while l:i < winheight(0) | let l:i = l:i + 1put! =l:fillendwhilenorm 0endifsetlocal nomodifiable" set up the keymapnoremap <silent> <buffer> <CR> :call LoadBuffer()<CR>map <silent> <buffer> q :bwipeout<CR>map <silent> <buffer> j :call BufferListMove("down")<CR>map <silent> <buffer> k :call BufferListMove("up")<CR>map <silent> <buffer> <MouseDown> :call BufferListMove("up")<CR>map <silent> <buffer> <MouseUp> :call BufferListMove("down")<CR>map <silent> <buffer> <LeftDrag> <Nop>map <silent> <buffer> <LeftRelease> :call BufferListMove("mouse")<CR>map <silent> <buffer> <2-LeftMouse> :call BufferListMove("mouse")<CR>\:call LoadBuffer()<CR>map <silent> <buffer> <Down> jmap <silent> <buffer> <Up> kmap <buffer> h <Nop>map <buffer> l <Nop>map <buffer> <Left> <Nop>map <buffer> <Right> <Nop>map <buffer> i <Nop>map <buffer> a <Nop>map <buffer> I <Nop>map <buffer> A <Nop>map <buffer> o <Nop>map <buffer> O <Nop>map <silent> <buffer> <Home> :call BufferListMove(1)<CR>map <silent> <buffer> <End> :call BufferListMove(line("$"))<CR>" make the buffer count & the buffer numbers available" for our other functionslet b:bufnumbers = l:bufnumberslet b:bufcount = l:displayedbufs" go to the correct linecall BufferListMove(l:activebufline)endfunction" move the selection bar of the list:" where can be "up"/"down"/"mouse" or" a line numberfunction! BufferListMove(where)if b:bufcount < 1returnendiflet l:newpos = 0if !exists('b:lastline')let b:lastline = 0endifsetlocal modifiable" the mouse was pressed: remember which line" and go back to the original location for nowif a:where == "mouse"let l:newpos = line(".")call BufferListGoto(b:lastline)endif" exchange the first char (>) with a spacecall setline(line("."), " ".strpart(getline(line(".")), 1))" go where the user want's us to goif a:where == "up"call BufferListGoto(line(".")-1)elseif a:where == "down"call BufferListGoto(line(".")+1)elseif a:where == "mouse"call BufferListGoto(l:newpos)elsecall BufferListGoto(a:where)endif" and mark this line with a >call setline(line("."), ">".strpart(getline(line(".")), 1))" remember this line, in case the mouse is clicked" (which automatically moves the cursor there)let b:lastline = line(".")setlocal nomodifiableendfunction" tries to set the cursor to a line of the buffer listfunction! BufferListGoto(line)if b:bufcount < 1 | return | endifif a:line < 1call cursor(1, 1)elseif a:line > b:bufcountcall cursor(b:bufcount, 1)elsecall cursor(a:line, 1)endifendfunction" loads the selected bufferfunction! LoadBuffer()" this is our string containing the buffer numbers in" the order of the list (separated by ':')let l:str = b:bufnumbers" remove all numbers BEFORE the one we wantlet l:i = 1 | while l:i < line(".") | let l:i = l:i + 1let l:str = strpart(l:str, stridx(l:str, ':') + 1)endwhile" and everything AFTERlet l:str = strpart(l:str, 0, stridx(l:str, ':'))" kill the buffer listbwipeout" ...and switch to the buffer numberexec ":b " . l:strendfunction