summaryrefslogtreecommitdiff
path: root/.vim/available_plugins/minibufexpl/plugin/minibufexpl.vim
diff options
context:
space:
mode:
Diffstat (limited to '.vim/available_plugins/minibufexpl/plugin/minibufexpl.vim')
-rwxr-xr-x.vim/available_plugins/minibufexpl/plugin/minibufexpl.vim2467
1 files changed, 2467 insertions, 0 deletions
diff --git a/.vim/available_plugins/minibufexpl/plugin/minibufexpl.vim b/.vim/available_plugins/minibufexpl/plugin/minibufexpl.vim
new file mode 100755
index 0000000..e2b3348
--- /dev/null
+++ b/.vim/available_plugins/minibufexpl/plugin/minibufexpl.vim
@@ -0,0 +1,2467 @@
+" Mini Buffer Explorer <minibufexpl.vim>
+"
+" HINT: Type zR if you don't know how to use folds
+"
+" Script Info and Documentation {{{
+"=============================================================================
+" Copyright: Copyright (C) 2002 & 2003 Bindu Wavell
+" Copyright (C) 2010 Oliver Uvman
+" Copyright (C) 2010 Danielle Church
+" Copyright (C) 2010 Stephan Sokolow
+" Copyright (C) 2010 & 2011 Federico Holgado
+" Permission is hereby granted to use and distribute this code,
+" with or without modifications, provided that this copyright
+" notice is copied with it. Like anything else that's free,
+" minibufexpl.vim is provided *as is* and comes with no
+" warranty of any kind, either expressed or implied. In no
+" event will the copyright holder be liable for any damamges
+" resulting from the use of this software.
+"
+" Name Of File: minibufexpl.vim
+" Description: Mini Buffer Explorer Vim Plugin
+" Documentation: See minibufexpl.txt
+"
+"=============================================================================
+" }}}
+"
+" Startup Check
+"
+" Has this plugin already been loaded? {{{
+"
+if exists('loaded_minibufexplorer')
+ finish
+endif
+let loaded_minibufexplorer = 1
+
+" }}}
+"
+" Mappings and Commands
+"
+" MBE commands {{{
+"
+if !exists(':MiniBufExplorer')
+ command! MiniBufExplorer echoe 'MiniBufExplorer is depreciated, please use MBEOpen instead.'
+endif
+if !exists(':CMiniBufExplorer')
+ command! CMiniBufExplorer echoe 'CMiniBufExplorer is depreciated, please use MBEClose instead.'
+endif
+if !exists(':TMiniBufExplorer')
+ command! TMiniBufExplorer echoe 'TMiniBufExplorer is depreciated, please use MBEToggle instead.'
+endif
+if !exists(':MBEFocus')
+ command! MBEFocus call <SID>FocusExplorer()
+endif
+if !exists(':MBEFocusAll')
+ command! MBEFocusAll tabdo call <SID>FocusExplorer()
+endif
+if !exists(':MBEOpen')
+ command! -bang MBEOpen let t:skipEligibleBuffersCheck = 1 | if '<bang>' == '!' | call <SID>StopExplorer(0) | endif | call <SID>StartExplorer(bufnr("%"))
+endif
+if !exists(':MBEOpenAll')
+ command! -bang MBEOpenAll tabdo let t:skipEligibleBuffersCheck = 1 | if '<bang>' == '!' | call <SID>StopExplorer(0) | endif | call <SID>StartExplorer(bufnr("%")) | let s:TabsMBEState = 1
+endif
+if !exists(':MBEClose')
+ command! -bang MBEClose let t:skipEligibleBuffersCheck = 0 | call <SID>StopExplorer('<bang>' == '!')
+endif
+if !exists(':MBECloseAll')
+ command! -bang MBECloseAll tabdo let t:skipEligibleBuffersCheck = 0 | call <SID>StopExplorer('<bang>' == '!') | let s:TabsMBEState = 0
+endif
+if !exists(':MBEToggle')
+ command! -bang MBEToggle call <SID>ToggleExplorer(0,'<bang>'=='!')
+endif
+if !exists(':MBEToggleAll')
+ command! -bang MBEToggleAll call <SID>ToggleExplorer(1,'<bang>'=='!')
+endif
+if !exists(':MBEToggleMRU')
+ command! -bang MBEToggleMRU call <SID>ToggleMRU()
+endif
+if !exists(':MBEToggleMRUAll')
+ command! -bang MBEToggleMRUAll tabdo call <SID>ToggleMRU()
+endif
+if !exists(':MBEbn')
+ command! MBEbn call <SID>CycleBuffer(1)
+endif
+if !exists(':MBEbp')
+ command! MBEbp call <SID>CycleBuffer(0)
+endif
+if !exists(':MBEbf')
+ command! MBEbf call <SID>CycleBuffer(1,1)
+endif
+if !exists(':MBEbb')
+ command! MBEbb call <SID>CycleBuffer(0,1)
+endif
+if !exists(':MBEbd')
+ command! -bang -nargs=* MBEbd call <SID>DeleteBuffer(0,'<bang>'=='!',<f-args>)
+endif
+if !exists(':MBEbw')
+ command! -bang -nargs=* MBEbw call <SID>DeleteBuffer(1,'<bang>'=='!',<f-args>)
+endif
+if !exists(':MBEbun')
+ command! -bang -nargs=* MBEbun call <SID>DeleteBuffer(2,'<bang>'=='!',<f-args>)
+endif
+
+" }}}
+"
+" Global Configuration Variables - Depreciated
+"
+" {{{
+if exists('g:miniBufExplSplitBelow')
+ let g:miniBufExplBRSplit = g:miniBufExplSplitBelow
+endif
+
+if exists('g:miniBufExplMaxHeight')
+ let g:miniBufExplMaxSize = g:miniBufExplMaxHeight
+endif
+
+if exists('g:miniBufExplMinHeight')
+ let g:miniBufExplMinSize = g:miniBufExplMinHeight
+endif
+
+if exists('g:miniBufExplorerMoreThanOne')
+ let g:miniBufExplBuffersNeeded = g:miniBufExplorerMoreThanOne
+endif
+
+if exists('g:miniBufExplorerAutoStart')
+ let g:miniBufExplAutoStart = g:miniBufExplorerAutoStart
+endif
+
+if exists('g:miniBufExplorerDebugMode')
+ let g:miniBufExplDebugMode = g:miniBufExplorerDebugMode
+endif
+
+if exists('g:miniBufExplorerDebugLevel')
+ let g:miniBufExplDebugLevel = g:miniBufExplorerDebugLevel
+endif
+
+if exists('g:miniBufExplorerDebugOutput')
+ let g:miniBufExplDebugOutput = g:miniBufExplorerDebugOutput
+endif
+
+if exists('g:miniBufExplorerHideWhenDiff')
+ let g:miniBufExplHideWhenDiff = g:miniBufExplorerHideWhenDiff
+endif
+
+" }}}
+"
+" Global Configuration Variables
+"
+" Start MBE automatically ? {{{
+"
+if !exists('g:miniBufExplAutoStart')
+ let g:miniBufExplAutoStart = 1
+endif
+
+" }}}
+" Debug Mode {{{
+"
+" 0 = debug to a window
+" 1 = use vim's echo facility
+" 2 = write to a file named MiniBufExplorer.DBG
+" in the directory where vim was started
+" THIS IS VERY SLOW
+" 3 = Write into g:miniBufExplDebugOutput
+" global variable [This is the default]
+if !exists('g:miniBufExplDebugMode')
+ let g:miniBufExplDebugMode = 3
+endif
+
+" }}}
+" Debug Level {{{
+"
+" 0 = no logging
+" 1=5 = errors ; 1 is the most important
+" 5-9 = info ; 5 is the most important
+" 10 = Entry/Exit
+if !exists('g:miniBufExplDebugLevel')
+ let g:miniBufExplDebugLevel = 1
+endif
+
+" }}}
+" Stop auto starting MBE in diff mode? {{{
+if !exists('g:miniBufExplHideWhenDiff')
+ let g:miniBufExplHideWhenDiff = 0
+endif
+
+" }}}
+" MoreThanOne? {{{
+" Display Mini Buf Explorer when there are 'More Than One' eligible buffers
+"
+if !exists('g:miniBufExplBuffersNeeded')
+ let g:miniBufExplBuffersNeeded = 2
+endif
+
+" }}}
+" Set the updatetime? {{{
+if !exists('g:miniBufExplSetUT')
+ let g:miniBufExplSetUT = 1
+endif
+
+" }}}
+" Horizontal or Vertical explorer? {{{
+" For folks that like vertical explorers, I'm caving in and providing for
+" veritcal splits. If this is set to 0 then the current horizontal
+" splitting logic will be run. If however you want a vertical split,
+" assign the width (in characters) you wish to assign to the MBE window.
+"
+if !exists('g:miniBufExplVSplit')
+ let g:miniBufExplVSplit = 0
+endif
+
+" }}}
+" Split below/above/left/right? {{{
+" When opening a new -MiniBufExplorer- window, split the new windows below or
+" above the current window? 1 = below, 0 = above.
+"
+if !exists('g:miniBufExplBRSplit')
+ let g:miniBufExplBRSplit = g:miniBufExplVSplit ? &splitright : &splitbelow
+endif
+
+" }}}
+" Split to edge? {{{
+" When opening a new -MiniBufExplorer- window, split the new windows to the
+" full edge? 1 = yes, 0 = no.
+"
+if !exists('g:miniBufExplSplitToEdge')
+ let g:miniBufExplSplitToEdge = 1
+endif
+
+" }}}
+" MaxSize {{{
+" Same as MaxHeight but also works for vertical splits if specified with a
+" vertical split then vertical resizing will be performed. If left at 0
+" then the number of columns in g:miniBufExplVSplit will be used as a
+" static window width.
+if !exists('g:miniBufExplMaxSize')
+ let g:miniBufExplMaxSize = 0
+endif
+
+" }}}
+" MinSize {{{
+" Same as MinHeight but also works for vertical splits. For vertical splits,
+" this is ignored unless g:miniBufExplMax(Size|Height) are specified.
+if !exists('g:miniBufExplMinSize')
+ let g:miniBufExplMinSize = 1
+endif
+
+" }}}
+" TabWrap? {{{
+" By default line wrap is used (possibly breaking a tab name between two
+" lines.) Turning this option on (setting it to 1) can take more screen
+" space, but will make sure that each tab is on one and only one line.
+"
+if !exists('g:miniBufExplTabWrap')
+ let g:miniBufExplTabWrap = 0
+endif
+
+" }}}
+" ShowBufNumber? {{{
+" By default buffers' numbers are shown in MiniBufExplorer. You can turn it off
+" by setting this option to 0.
+"
+if !exists('g:miniBufExplShowBufNumbers')
+ let g:miniBufExplShowBufNumbers = 1
+endif
+
+" }}}
+" Single/Double Click? {{{
+" flag that can be set to 1 in a users .vimrc to allow
+" single click switching of tabs. By default we use
+" double click for tab selection.
+"
+if !exists('g:miniBufExplUseSingleClick')
+ let g:miniBufExplUseSingleClick = 0
+endif
+
+" }}}
+" Close on Select? {{{
+" Flag that can be set to 1 in a users .vimrc to hide
+" the explorer when a user selects a buffer.
+"
+if !exists('g:miniBufExplCloseOnSelect')
+ let g:miniBufExplCloseOnSelect = 0
+endif
+
+" }}}
+" Status Line Text for MBE window {{{
+"
+if !exists('g:miniBufExplStatusLineText')
+ let g:miniBufExplStatusLineText = "-MiniBufExplorer-"
+endif
+
+" }}}
+" How to sort the buffers in MBE window {{{
+"
+if !exists('g:miniBufExplSortBy')
+ let g:miniBufExplSortBy = "number"
+endif
+
+" }}}
+" Should buffer be cycled arround if hits the begining or the end while {{{
+" using MBE's buffer movement commands.
+"
+if !exists('g:miniBufExplCycleArround')
+ let g:miniBufExplCycleArround = 0
+endif
+
+" }}}
+"
+" Variables used internally
+"
+" Script/Global variables {{{
+" In debug mode 3 this variable will hold the debug output
+let g:miniBufExplDebugOutput = ''
+
+" check to see what platform we are in
+if (has('unix'))
+ let s:PathSeparator = '/'
+else
+ let s:PathSeparator = '\'
+endif
+
+" Variable used to count debug output lines
+let s:debugIndex = 0
+
+" Variable used to pass maxTabWidth info between functions
+let s:maxTabWidth = 0
+
+" Variable used as a mutex to indicate the current state of MBEToggleAll
+let s:TabsMBEState = 0
+
+" List for all eligible buffers
+let s:BufList = []
+
+" List for tracking order of the buffer entering
+let s:MRUList = []
+
+" Whether MRU List should be updated.
+let s:MRUEnable = 1
+
+" Dictionary used to keep track of the modification state of buffers
+let s:bufStateDict = {}
+
+" Global used to store the buffer list so that we don't update the MBE
+" unless the list has changed.
+let s:miniBufExplBufList = ''
+
+" Variable used as a mutex so that AutoUpdates would not get nested.
+let s:miniBufExplInAutoUpdate = 0
+
+" Dictionary used to keep track of the names we have seen.
+let s:bufNameDict = {}
+
+" Dictionary used to map buffer numbers to names when the buffer
+" names are not unique.
+let s:bufUniqNameDict = {}
+
+" Dictionary used to hold the path parts for each buffer
+let s:bufPathDict = {}
+
+" Dictionary used to hold the path signature index for each buffer
+let s:bufPathSignDict = {}
+
+" We start out with this off for startup, but once vim is running we
+" turn this on. This prevent any BufEnter event from being triggered
+" before VimEnter event.
+let t:miniBufExplAutoUpdate = 0
+
+" If MBE was opened manually, then we should skip eligible buffers checking,
+" open MBE window no matter what value 'g:miniBufExplBuffersNeeded' is set.
+let t:skipEligibleBuffersCheck = 0
+
+" The order of buffer listing in MBE window is tab dependently.
+let t:miniBufExplSortBy = g:miniBufExplSortBy
+
+" }}}
+"
+" Auto Commands
+"
+" Setup an autocommand group and some autocommands {{{
+" that keep our explorer updated automatically.
+"
+
+" Set a lower value to 'updatetime' for the CursorHold/CursorHoldI event, so
+" that the MBE could be updated in time. It can not be set too low, otherwise
+" might breaks many things, 1500ms should be a reasonable value.
+" We only change it if we are allowed to and it has not been changed yet.
+if g:miniBufExplSetUT && &ut == 4000
+ set updatetime=1500
+endif
+
+augroup MiniBufExpl
+ autocmd!
+ autocmd VimEnter * nested call <SID>VimEnterHandler()
+ autocmd TabEnter * nested call <SID>TabEnterHandler()
+ autocmd BufAdd * call <SID>BufAddHandler()
+ autocmd BufEnter * nested call <SID>BufEnterHandler()
+ autocmd BufDelete * call <SID>BufDeleteHandler()
+ autocmd CursorHold,CursorHoldI,BufWritePost *
+ \ call <SID>DEBUG('Entering UpdateBufferStateDict AutoCmd', 10) |
+ \ call <SID>UpdateBufferStateDict(bufnr("%"),0) |
+ \ call <SID>DEBUG('Leaving UpdateBufferStateDict AutoCmd', 10)
+if exists('##QuitPre')
+ autocmd QuitPre *
+ \ if <SID>NextNormalWindow() == -1 | call <SID>StopExplorer(0) | endif
+else
+ autocmd BufEnter * nested call <SID>QuitIfLastOpen()
+endif
+ autocmd FileType minibufexpl call <SID>RenderSyntax()
+augroup END
+
+function! <SID>VimEnterHandler()
+ call <SID>DEBUG('Entering VimEnter Handler', 10)
+
+ " Build initial MRUList.
+ " This makes sure all the files specified on the command
+ " line are picked up correctly.
+ let s:BufList = range(1, bufnr('$'))
+ let s:MRUList = range(1, bufnr('$'))
+
+ for l:i in s:BufList
+ if <SID>IsBufferIgnored(l:i)
+ call <SID>ListPop(s:BufList,l:i)
+ endif
+ endfor
+
+ for l:i in s:MRUList
+ if <SID>IsBufferIgnored(l:i)
+ call <SID>ListPop(s:MRUList,l:i)
+ endif
+ endfor
+
+ if g:miniBufExplHideWhenDiff!=1 || !&diff
+ let t:miniBufExplAutoUpdate = 1
+ endif
+
+ if g:miniBufExplAutoStart && t:miniBufExplAutoUpdate == 1
+ \ && (t:skipEligibleBuffersCheck == 1 || <SID>HasEligibleBuffers() == 1)
+ call <SID>StartExplorer(bufnr("%"))
+
+ " Let the MBE open in the new tab
+ let s:TabsMBEState = 1
+ endif
+
+ call <SID>DEBUG('Leaving VimEnter Handler', 10)
+endfunction
+
+function! <SID>TabEnterHandler()
+ call <SID>DEBUG('Entering TabEnter Handler', 10)
+
+ if !exists('t:miniBufExplSortBy')
+ let t:miniBufExplSortBy = g:miniBufExplSortBy
+ endif
+
+ if !exists('t:miniBufExplAutoUpdate')
+ let t:miniBufExplAutoUpdate = s:TabsMBEState
+ endif
+
+ if !exists('t:skipEligibleBuffersCheck')
+ let t:skipEligibleBuffersCheck = 0
+ endif
+
+ if g:miniBufExplAutoStart && t:miniBufExplAutoUpdate == 1
+ \ && (t:skipEligibleBuffersCheck == 1 || <SID>HasEligibleBuffers() == 1)
+ call <SID>StartExplorer(bufnr("%"))
+ endif
+
+ call <SID>DEBUG('Leaving TabEnter Handler', 10)
+endfunction
+
+function! <SID>BufAddHandler()
+ call <SID>DEBUG('Entering BufAdd Handler', 10)
+
+ call <SID>ListAdd(s:BufList,str2nr(expand("<abuf>")))
+ call <SID>ListAdd(s:MRUList,str2nr(expand("<abuf>")))
+
+ call <SID>UpdateAllBufferDicts(expand("<abuf>"),0)
+
+ call <SID>AutoUpdate(bufnr("%"),0)
+
+ call <SID>DEBUG('Leaving BufAdd Handler', 10)
+endfunction
+
+function! <SID>BufEnterHandler() abort
+ call <SID>DEBUG('Entering BufEnter Handler', 10)
+
+ for l:i in s:BufList
+ if <SID>IsBufferIgnored(l:i)
+ call <SID>ListPop(s:BufList,l:i)
+ endif
+ endfor
+
+ for l:i in s:MRUList
+ if <SID>IsBufferIgnored(l:i)
+ call <SID>ListPop(s:MRUList,l:i)
+ endif
+ endfor
+
+ call <SID>AutoUpdate(bufnr("%"),0)
+
+ call <SID>DEBUG('Leaving BufEnter Handler', 10)
+endfunction
+
+function! <SID>BufDeleteHandler()
+ call <SID>DEBUG('Entering BufDelete Handler', 10)
+
+ call <SID>ListPop(s:BufList,str2nr(expand("<abuf>")))
+ call <SID>ListPop(s:MRUList,str2nr(expand("<abuf>")))
+
+ call <SID>UpdateAllBufferDicts(expand("<abuf>"),1)
+
+ " Handle ':bd' command correctly
+ if (bufname('%') == '-MiniBufExplorer-' && <SID>NextNormalWindow() == -1 && len(s:BufList) > 0)
+ if(tabpagenr('$') == 1)
+ setlocal modifiable
+ resize
+ exec 'noautocmd sb'.s:BufList[0]
+ call <SID>StopExplorer(0)
+ call <SID>StartExplorer(bufnr("%"))
+ else
+ close
+ endif
+ endif
+
+ call <SID>AutoUpdate(bufnr("%"),1)
+
+ call <SID>DEBUG('Leaving BufDelete Handler', 10)
+endfunction
+" }}}
+"
+" Functions
+"
+" RenderSyntax {{{
+"
+function! <SID>RenderSyntax()
+ if has("syntax")
+ syn clear
+ syn match MBENormal '\[[^\]]*\]'
+ syn match MBEChanged '\[[^\]]*\]+'
+ syn match MBEVisibleNormal '\[[^\]]*\]\*'
+ syn match MBEVisibleChanged '\[[^\]]*\]\*+'
+ syn match MBEVisibleActiveNormal '\[[^\]]*\]\*!'
+ syn match MBEVisibleActiveChanged '\[[^\]]*\]\*+!'
+
+ "MiniBufExpl Color Examples
+ " hi MBENormal guifg=#808080 guibg=fg
+ " hi MBEChanged guifg=#CD5907 guibg=fg
+ " hi MBEVisibleNormal guifg=#5DC2D6 guibg=fg
+ " hi MBEVisibleChanged guifg=#F1266F guibg=fg
+ " hi MBEVisibleActiveNormal guifg=#A6DB29 guibg=fg
+ " hi MBEVisibleActiveChanged guifg=#F1266F guibg=fg
+
+ if !exists("g:did_minibufexplorer_syntax_inits")
+ let g:did_minibufexplorer_syntax_inits = 1
+ hi def link MBENormal Comment
+ hi def link MBEChanged String
+ hi def link MBEVisibleNormal Special
+ hi def link MBEVisibleChanged Special
+ hi def link MBEVisibleActiveNormal Underlined
+ hi def link MBEVisibleActiveChanged Error
+ endif
+
+ let b:current_syntax = "minibufexpl"
+ endif
+endfunction
+
+" }}}
+" StartExplorer - Sets up our explorer and causes it to be displayed {{{
+"
+function! <SID>StartExplorer(curBufNum)
+ call <SID>DEBUG('Entering StartExplorer('.a:curBufNum.')',10)
+
+ call <SID>DEBUG('Current state: '.winnr().' : '.bufnr('%').' : '.bufname('%'),10)
+
+ call <SID>BuildAllBufferDicts()
+
+ let t:miniBufExplAutoUpdate = 1
+
+ let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if l:winNum != -1
+ call <SID>DEBUG('There is already a MBE window, aborting...',1)
+ call <SID>DEBUG('Leaving StartExplorer()',10)
+ return
+ endif
+
+ call <SID>CreateWindow('-MiniBufExplorer-', g:miniBufExplVSplit, g:miniBufExplBRSplit, g:miniBufExplSplitToEdge, 1, 1)
+
+ let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if l:winNum == -1
+ call <SID>DEBUG('Failed to create the MBE window, aborting...',1)
+ call <SID>DEBUG('Leaving StartExplorer()',10)
+ return
+ endif
+
+ " Save current window number and switch to previous
+ " window before entering MBE window so that the later
+ " `wincmd p` command will get into this window, then
+ " we can preserve a one level window movement history.
+ let l:currWin = winnr()
+ call s:SwitchWindow('p',1)
+
+ " Switch into MBE allowing autocmd to run will
+ " make the syntax highlight in MBE window working
+ call s:SwitchWindow('w',0,l:winNum)
+
+ " Make sure we are in our window
+ if bufname('%') != '-MiniBufExplorer-'
+ call <SID>DEBUG('StartExplorer called in invalid window',1)
+ call <SID>DEBUG('Leaving StartExplorer()',10)
+ return
+ endif
+
+ " Set filetype for MBE buffer
+ set filetype=minibufexpl
+
+ " !!! We may want to make the following optional -- Bindu
+ " New windows don't cause all windows to be resized to equal sizes
+ set noequalalways
+
+ " !!! We may want to make the following optional -- Bindu
+ " We don't want the mouse to change focus without a click
+ set nomousefocus
+
+ if g:miniBufExplVSplit == 0
+ setlocal wrap
+ else
+ setlocal nowrap
+ exec 'setlocal winwidth='.g:miniBufExplMinSize
+ endif
+
+ " If folks turn numbering and columns on by default we will turn
+ " them off for the MBE window
+ setlocal foldcolumn=0
+ setlocal nonumber
+ if exists("&norelativenumber")
+ " relativenumber was introduced in Vim 7.3 - this provides compatibility
+ " for older versions of Vim
+ setlocal norelativenumber
+ endif
+ "don't highlight matching parentheses, etc.
+ setlocal matchpairs=
+ "Depending on what type of split, make sure the MBE buffer is not
+ "automatically rezised by CTRL + W =, etc...
+ setlocal winfixheight
+ setlocal winfixwidth
+
+ " Set the text of the statusline for the MBE buffer. See help:stl for
+ " many options
+ exec 'setlocal statusline='.g:miniBufExplStatusLineText
+
+ " No spell check
+ setlocal nospell
+
+ " Restore colorcolumn for VIM >= 7.3
+ if exists("+colorcolumn")
+ setlocal colorcolumn&
+ end
+
+ " If you press return, o or e in the -MiniBufExplorer- then try
+ " to open the selected buffer in the previous window.
+ nnoremap <buffer> o :call <SID>MBESelectBuffer(0)<CR>:<BS>
+ nnoremap <buffer> e :call <SID>MBESelectBuffer(0)<CR>:<BS>
+ nnoremap <buffer> <CR> :call <SID>MBESelectBuffer(0)<CR>:<BS>
+ " If you press s in the -MiniBufExplorer- then try
+ " to open the selected buffer in a split in the previous window.
+ nnoremap <buffer> s :call <SID>MBESelectBuffer(1)<CR>:<BS>
+ " If you press j in the -MiniBufExplorer- then try
+ " to open the selected buffer in a vertical split in the previous window.
+ nnoremap <buffer> v :call <SID>MBESelectBuffer(2)<CR>:<BS>
+ " If you press d in the -MiniBufExplorer- then try to
+ " delete the selected buffer.
+ nnoremap <buffer> d :call <SID>MBEDeleteBuffer()<CR>:<BS>
+ " The following allow us to use regular movement keys to
+ " scroll in a wrapped single line buffer
+ nnoremap <buffer> k gk
+ nnoremap <buffer> j gj
+ nnoremap <buffer> <up> gk
+ nnoremap <buffer> <down> gj
+ " The following allows for quicker moving between buffer
+ " names in the [MBE] window it also saves the last-pattern
+ " and restores it.
+ if !g:miniBufExplShowBufNumbers
+ nnoremap <buffer> l :call search('\[[^\]]*\]')<CR>:<BS>
+ nnoremap <buffer> h :call search('\[[^\]]*\]','b')<CR>:<BS>
+ nnoremap <buffer> <right> :call search('\[[^\]]*\]')<CR>:<BS>
+ nnoremap <buffer> <left> :call search('\[[^\]]*\]','b')<CR>:<BS>
+ else
+ nnoremap <buffer> l :call search('\[[0-9]*:[^\]]*\]')<CR>:<BS>
+ nnoremap <buffer> h :call search('\[[0-9]*:[^\]]*\]','b')<CR>:<BS>
+ nnoremap <buffer> <right> :call search('\[[0-9]*:[^\]]*\]')<CR>:<BS>
+ nnoremap <buffer> <left> :call search('\[[0-9]*:[^\]]*\]','b')<CR>:<BS>
+ endif
+
+ " Attempt to perform single click mapping
+ " It would be much nicer if we could 'nnoremap <buffer> ...', however
+ " vim does not fire the '<buffer> <leftmouse>' when you use the mouse
+ " to enter a buffer.
+ if g:miniBufExplUseSingleClick == 1
+ let l:mapcmd = ':nnoremap <silent> <LEFTMOUSE> <LEFTMOUSE>'
+ let l:clickcmd = ':if bufname("%") == "-MiniBufExplorer-" <bar> call <SID>MBESelectBuffer(0) <bar> endif <CR>'
+ " no mapping for leftmouse
+ if maparg('<LEFTMOUSE>', 'n') == ''
+ exec l:mapcmd . l:clickcmd
+ " we have a mapping
+ else
+ let l:mapcmd = l:mapcmd . substitute(substitute(maparg('<LEFTMOUSE>', 'n'), '|', '<bar>', 'g'), '\c^<LEFTMOUSE>', '', '')
+ let l:mapcmd = l:mapcmd . l:clickcmd
+ exec l:mapcmd
+ endif
+ " If you DoubleClick in the MBE window then try to open the selected
+ " buffer in the previous window.
+ else
+ nnoremap <buffer> <2-LEFTMOUSE> :call <SID>MBESelectBuffer(0)<CR>:<BS>
+ endif
+
+ call <SID>BuildBufferList(a:curBufNum)
+
+ call <SID>DisplayBuffers(a:curBufNum)
+
+ " Switch away from MBE allowing autocmd to run which will
+ " trigger PowerLine's BufLeave event handler
+ call s:SwitchWindow('p',0)
+
+ " Now we are in the previous window, let's enter
+ " the window current window, this will preserve
+ " one-level backwards window movement history.
+ call s:SwitchWindow('w',1,l:currWin)
+
+ call <SID>DEBUG('Leaving StartExplorer()',10)
+endfunction
+
+" }}}
+" StopExplorer - Looks for our explorer and closes the window if it is open {{{
+"
+function! <SID>StopExplorer(force)
+ call <SID>DEBUG('Entering StopExplorer()',10)
+
+ if a:force || <SID>HasEligibleBuffers()
+ let t:miniBufExplAutoUpdate = 0
+ endif
+
+ let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if l:winNum == -1
+ call <SID>DEBUG('There is no MBE window, aborting...',1)
+ call <SID>DEBUG('Leaving StopExplorer()',10)
+ return
+ endif
+
+ call s:SwitchWindow('w',1,l:winNum)
+ silent! close
+ call s:SwitchWindow('p',1)
+
+ " Work around a redraw bug in gVim (Confirmed present in 7.3.50)
+ if has('gui_gtk') && has('gui_running')
+ redraw!
+ endif
+
+ call <SID>DEBUG('Leaving StopExplorer()',10)
+endfunction
+
+" }}}
+" FocusExplorer {{{
+"
+function! <SID>FocusExplorer()
+ call <SID>DEBUG('Entering FocusExplorer()',10)
+
+ let t:miniBufExplAutoUpdate = 1
+
+ let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if l:winNum == -1
+ call <SID>DEBUG('There is no MBE window, aborting...',1)
+ call <SID>DEBUG('Leaving FocusExplorer()',10)
+ return
+ endif
+
+ call s:SwitchWindow('w',0,l:winNum)
+
+ call <SID>DEBUG('Leaving FocusExplorer()',10)
+endfunction
+
+" }}}
+" ToggleMRU - Switch the order of buffer listing in MBE window {{{
+" between its default and most recently used.
+"
+function! <SID>ToggleMRU()
+ call <SID>DEBUG('Entering ToggleMRU()',10)
+
+ if t:miniBufExplSortBy == 'number'
+ let t:miniBufExplSortBy = 'mru'
+ else
+ let t:miniBufExplSortBy = 'number'
+ endif
+
+ let l:winnr = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if (l:winnr == -1)
+ call <SID>DEBUG('MiniBufExplorer was not running, starting...', 9)
+ call <SID>StartExplorer(bufnr('%'))
+ else
+ call <SID>DEBUG('Updating MiniBufExplorer...', 9)
+ call <SID>UpdateExplorer(bufnr('%'))
+ endif
+
+ call <SID>DEBUG('Leaving ToggleMRU()',10)
+endfunction
+
+" }}}
+" ToggleExplorer - Looks for our explorer and opens/closes the window {{{
+"
+" a:tabs, 0 no, 1 yes
+" toggle MBE in all tabs
+" a:force, 0 no, 1 yes
+" reopen MBE when it is already open
+" close MBE with auto-updating disabled
+"
+function! <SID>ToggleExplorer(tabs,force)
+ call <SID>DEBUG('Entering ToggleExplorer()',10)
+
+ if a:tabs
+ if s:TabsMBEState
+ tabdo let t:skipEligibleBuffersCheck = 0 | call <SID>StopExplorer(a:force)
+ else
+ tabdo let t:skipEligibleBuffersCheck = 1 | if a:force | call <SID>StopExplorer(0) | endif | call <SID>StartExplorer(bufnr("%"))
+ endif
+ let s:TabsMBEState = !s:TabsMBEState
+ else
+ let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if l:winNum != -1
+ let t:skipEligibleBuffersCheck = 0
+ call <SID>StopExplorer(a:force)
+ else
+ let t:skipEligibleBuffersCheck = 1
+ call <SID>StartExplorer(bufnr("%"))
+ endif
+ endif
+
+ call <SID>DEBUG('Leaving ToggleExplorer()',10)
+endfunction
+
+" }}}
+" UpdateExplorer {{{
+"
+function! <SID>UpdateExplorer(curBufNum)
+ call <SID>DEBUG('Entering UpdateExplorer('.a:curBufNum.')',10)
+
+ call <SID>DEBUG('Current state: '.winnr().' : '.bufnr('%').' : '.bufname('%'),10)
+
+ if !<SID>BuildBufferList(a:curBufNum)
+ call <SID>DEBUG('Buffer List have not changed, aborting...',10)
+ call <SID>DEBUG('Leaving UpdateExplorer()',10)
+ return
+ endif
+
+ let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if l:winNum == -1
+ call <SID>DEBUG('Found no MBE window, aborting...',1)
+ call <SID>DEBUG('Leaving UpdateExplorer()',10)
+ return
+ endif
+
+ if l:winNum != winnr()
+ let l:winChanged = 1
+
+ " Save current window number and switch to previous
+ " window before entering MBE window so that the later
+ " `wincmd p` command will get into this window, then
+ " we can preserve a one level window movement history.
+ let l:currWin = winnr()
+ call s:SwitchWindow('p',1)
+
+ " Switch into MBE allowing autocmd to run will
+ " make the syntax highlight in MBE window working
+ call s:SwitchWindow('w',0,l:winNum)
+ endif
+
+ call <SID>DisplayBuffers(a:curBufNum)
+
+ if exists('l:winChanged')
+ " Switch away from MBE allowing autocmd to run which will
+ " trigger PowerLine's BufLeave event handler
+ call s:SwitchWindow('p',0)
+
+ " Now we are in the previous window, let's enter
+ " the window current window, this will preserve
+ " one-level backwards window movement history.
+ call s:SwitchWindow('w',1,l:currWin)
+ endif
+
+ call <SID>DEBUG('Leaving UpdateExplorer()',10)
+endfunction
+
+" }}}
+" FindWindow - Return the window number of a named buffer {{{
+" If none is found then returns -1.
+"
+function! <SID>FindWindow(bufName, doDebug)
+ if a:doDebug
+ call <SID>DEBUG('Entering FindWindow('.a:bufName.','.a:doDebug.')',10)
+ endif
+
+ " Try to find an existing window that contains
+ " our buffer.
+ let l:winnr = bufwinnr(a:bufName)
+
+ if l:winnr != -1
+ if a:doDebug
+ call <SID>DEBUG('Found window '.l:winnr.' with buffer ('.winbufnr(l:winnr).' : '.bufname(winbufnr(l:winnr)).')',9)
+ endif
+ else
+ if a:doDebug
+ call <SID>DEBUG('Can not find window with buffer ('.a:bufName.')',9)
+ endif
+ endif
+
+ if a:doDebug
+ call <SID>DEBUG('Leaving FindWindow()',10)
+ endif
+
+ return l:winnr
+endfunction
+
+" }}}
+" CreateWindow {{{
+"
+" vSplit, 0 no, 1 yes
+" split vertically or horizontally
+" brSplit, 0 no, 1 yes
+" split the window below/right to current window
+" forceEdge, 0 no, 1 yes
+" split the window at the edege of the editor
+" isPluginWindow, 0 no, 1 yes
+" if it is a plugin window
+" doDebug, 0 no, 1 yes
+" show debugging message or not
+"
+function! <SID>CreateWindow(bufName, vSplit, brSplit, forceEdge, isPluginWindow, doDebug)
+ if a:doDebug
+ call <SID>DEBUG('Entering CreateWindow('.a:bufName.','.a:vSplit.','.a:brSplit.','.a:forceEdge.','.a:isPluginWindow.','.a:doDebug.')',10)
+ endif
+
+ " Window number will change after creating a new window,
+ " we need to save both current and previous window number
+ " so that we can canculate theire correct window number
+ " after the new window creating.
+ let l:currWin = winnr()
+ call s:SwitchWindow('p',1)
+ let l:prevWin = winnr()
+ call s:SwitchWindow('p',1)
+
+ " Save the user's split setting.
+ let l:saveSplitBelow = &splitbelow
+ let l:saveSplitRight = &splitright
+
+ " Set to our new values.
+ let &splitbelow = a:brSplit
+ let &splitright = a:brSplit
+
+ let l:bufNum = bufnr(a:bufName)
+
+ if l:bufNum == -1
+ let l:spCmd = 'sp'
+ else
+ let l:spCmd = 'sb'
+ endif
+
+ if a:forceEdge == 1
+ let l:edge = a:vSplit ? &splitright : &splitbelow
+
+ if l:edge
+ if a:vSplit == 0
+ silent exec 'noautocmd bo '.l:spCmd.' '.a:bufName
+ else
+ silent exec 'noautocmd bo vert '.l:spCmd.' '.a:bufName
+ endif
+ else
+ if a:vSplit == 0
+ silent exec 'noautocmd to '.l:spCmd.' '.a:bufName
+ else
+ silent exec 'noautocmd to vert '.l:spCmd.' '.a:bufName
+ endif
+ endif
+ else
+ if a:vSplit == 0
+ silent exec 'noautocmd '.l:spCmd.' '.a:bufName
+ else
+ silent exec 'noautocmd vert '.l:spCmd.' '.a:bufName
+ endif
+ endif
+
+ " Restore the user's split setting.
+ let &splitbelow = l:saveSplitBelow
+ let &splitright = l:saveSplitRight
+
+ " Turn off the swapfile, set the buftype and bufhidden option, so that it
+ " won't get written and will be deleted when it gets hidden.
+ if a:isPluginWindow
+ setlocal noswapfile
+ setlocal nobuflisted
+ setlocal buftype=nofile
+ setlocal bufhidden=delete
+ endif
+
+ " Canculate the correct window number, for those whose window
+ " number before the creating is greater than or equal to the
+ " number of the newly created window, their window number should
+ " increase by one.
+ let l:prevWin = l:prevWin >= winnr() ? l:prevWin + 1 : l:prevWin
+ let l:currWin = l:currWin >= winnr() ? l:currWin + 1 : l:currWin
+ " This will preserve one-level backwards window movement history.
+ call s:SwitchWindow('w',1,l:prevWin)
+ call s:SwitchWindow('w',1,l:currWin)
+
+ if a:doDebug
+ call <SID>DEBUG('Leaving CreateWindow()',10)
+ endif
+endfunction
+
+" }}}
+" FindCreateWindow - Attempts to find a window for a named buffer. {{{
+"
+" If it is found then moves there. Otherwise creates a new window and
+" configures it and moves there.
+"
+" vSplit, 0 no, 1 yes
+" split vertically or horizontally
+" brSplit, 0 no, 1 yes
+" split the window below/right to current window
+" forceEdge, 0 no, 1 yes
+" split the window at the edege of the editor
+" isPluginWindow, 0 no, 1 yes
+" if it is a plugin window
+" doDebug, 0 no, 1 yes
+" show debugging message or not
+"
+function! <SID>FindCreateWindow(bufName, vSplit, brSplit, forceEdge, isPluginWindow, doDebug)
+ if a:doDebug
+ call <SID>DEBUG('Entering FindCreateWindow('.a:bufName.','.a:vSplit.','.a:brSplit.','.a:forceEdge.','.a:isPluginWindow.','.a:doDebug.')',10)
+ endif
+
+ " Try to find an existing explorer window
+ let l:winNum = <SID>FindWindow(a:bufName, a:doDebug)
+
+ " If found goto the existing window, otherwise
+ " split open a new window.
+ if l:winNum == -1
+ if a:doDebug
+ call <SID>DEBUG('Creating a new window with buffer ('.a:bufName.')',9)
+ endif
+
+ call <SID>CreateWindow(a:bufName, a:vSplit, a:brSplit, a:forceEdge, a:isPluginWindow, a:doDebug)
+
+ " Try to find an existing explorer window
+ let l:winNum = <SID>FindWindow(a:bufName, 0)
+
+ if l:winNum != -1
+ if a:doDebug
+ call <SID>DEBUG('Created window '.l:winNum.' with buffer ('.a:bufName.')',9)
+ endif
+ else
+ if a:doDebug
+ call <SID>DEBUG('Failed to create window with buffer ('.a:bufName.').',1)
+ endif
+ endif
+ endif
+
+ if a:doDebug
+ call <SID>DEBUG('Leaving FindCreateWindow()',10)
+ endif
+
+ return l:winNum
+endfunction
+
+" }}}
+" DisplayBuffers - Wrapper for getting MBE window shown {{{
+"
+" Makes sure we are in our explorer, then erases the current buffer and turns
+" it into a mini buffer explorer window.
+"
+function! <SID>DisplayBuffers(curBufNum)
+ call <SID>DEBUG('Entering DisplayExplorer('.a:curBufNum.')',10)
+
+ " Make sure we are in our window
+ if bufname('%') != '-MiniBufExplorer-'
+ call <SID>DEBUG('DisplayBuffers called in invalid window',1)
+ return
+ endif
+
+ call <SID>ShowBuffers()
+ call <SID>ResizeWindow()
+
+ " Place cursor at current buffer in MBE
+ if !<SID>IsBufferIgnored(a:curBufNum)
+ if !g:miniBufExplShowBufNumbers
+ call search('\V['.s:bufUniqNameDict[a:curBufNum].']', 'w')
+ else
+ call search('\V['.a:curBufNum.':'.s:bufUniqNameDict[a:curBufNum].']', 'w')
+ endif
+ endif
+
+ call <SID>DEBUG('Leaving DisplayExplorer()',10)
+endfunction
+
+" }}}
+" Resize Window - Set width/height of MBE window {{{
+"
+" Makes sure we are in our explorer, then sets the height/width for our explorer
+" window so that we can fit all of our information without taking extra lines.
+"
+function! <SID>ResizeWindow()
+ call <SID>DEBUG('Entering ResizeWindow()',10)
+
+ " Make sure we are in our window
+ if bufname('%') != '-MiniBufExplorer-'
+ call <SID>DEBUG('ResizeWindow called in invalid window',1)
+ call <SID>DEBUG('Leaving ResizeWindow()',10)
+ return
+ endif
+
+ " Prevent a report of our actions from showing up.
+ let l:save_rep = &report
+ let l:save_sc = &showcmd
+ let &report = 10000
+ set noshowcmd
+
+ let l:width = winwidth('.')
+
+ " Horizontal Resize
+ if g:miniBufExplVSplit == 0
+
+ if g:miniBufExplTabWrap == 0
+ let l:length = strlen(getline('.'))
+ let l:height = 0
+ if (l:width == 0)
+ let l:height = winheight('.')
+ else
+ let l:height = (l:length / l:width)
+ " handle truncation from div
+ if (l:length % l:width) != 0
+ let l:height = l:height + 1
+ endif
+ endif
+ else
+ " We need to be able to modify the buffer
+ setlocal modifiable
+
+ exec "setlocal textwidth=".l:width
+ normal gg
+ normal gq}
+ normal G
+ let l:height = line('.')
+ normal gg
+
+ " Prevent the buffer from being modified.
+ setlocal nomodifiable
+ endif
+
+ " enforce max window height
+ if g:miniBufExplMaxSize != 0
+ if g:miniBufExplMaxSize < l:height
+ let l:height = g:miniBufExplMaxSize
+ endif
+ endif
+
+ " enfore min window height
+ if l:height < g:miniBufExplMinSize || l:height == 0
+ let l:height = g:miniBufExplMinSize
+ endif
+
+ call <SID>DEBUG('ResizeWindow to '.l:height.' lines',9)
+
+ if &winminheight > l:height
+ let l:saved_winminheight = &winminheight
+ let &winminheight = 1
+ exec 'resize '.l:height
+ let &winminheight = l:saved_winminheight
+ else
+ exec 'resize '.l:height
+ endif
+
+ let saved_ead = &ead
+ let &ead = 'ver'
+ set equalalways
+ let &ead = saved_ead
+ set noequalalways
+
+ " Vertical Resize
+ else
+
+ if g:miniBufExplMaxSize != 0
+ let l:newWidth = s:maxTabWidth
+ if l:newWidth > g:miniBufExplMaxSize
+ let l:newWidth = g:miniBufExplMaxSize
+ endif
+ if l:newWidth < g:miniBufExplMinSize
+ let l:newWidth = g:miniBufExplMinSize
+ endif
+ else
+ let l:newWidth = g:miniBufExplVSplit
+ endif
+
+ if l:width != l:newWidth
+ call <SID>DEBUG('ResizeWindow to '.l:newWidth.' columns',9)
+ exec 'vertical resize '.l:newWidth
+ endif
+
+ let saved_ead = &ead
+ let &ead = 'hor'
+ set equalalways
+ let &ead = saved_ead
+ set noequalalways
+
+ endif
+
+ normal! zz
+
+ let &report = l:save_rep
+ let &showcmd = l:save_sc
+
+ call <SID>DEBUG('Leaving ResizeWindow()',10)
+endfunction
+
+" }}}
+" ShowBuffers - Clear current buffer and put the MBE text into it {{{
+"
+" Makes sure we are in our explorer, then adds a list of all modifiable
+" buffers to the current buffer. Special marks are added for buffers that
+" are in one or more windows (*) and buffers that have been modified (+)
+"
+function! <SID>ShowBuffers()
+ call <SID>DEBUG('Entering ShowExplorer()',10)
+
+ " Make sure we are in our window
+ if bufname('%') != '-MiniBufExplorer-'
+ call <SID>DEBUG('ShowBuffers called in invalid window',1)
+ call <SID>DEBUG('Leaving ShowBuffers()',10)
+ return
+ endif
+
+ let l:save_rep = &report
+ let l:save_sc = &showcmd
+ let &report = 10000
+ set noshowcmd
+
+ " We need to be able to modify the buffer
+ setlocal modifiable
+
+ " Delete all lines in buffer.
+ silent 1,$d _
+
+ " Goto the end of the buffer put the buffer list
+ " and then delete the extra trailing blank line
+ $
+ put! =s:miniBufExplBufList
+ silent $ d _
+
+ " Prevent the buffer from being modified.
+ setlocal nomodifiable
+
+ let &report = l:save_rep
+ let &showcmd = l:save_sc
+
+ call <SID>DEBUG('Leaving ShowBuffers()',10)
+endfunction
+
+" }}}
+" CycleBuffer - Cycle Through Buffers {{{
+"
+" Move to next or previous buffer in the current window. If there
+" are no more modifiable buffers then stay on the current buffer.
+" can be called with no parameters in which case the buffers are
+" cycled forward. Otherwise a single argument is accepted, if
+" it's 0 then the buffers are cycled backwards, otherwise they
+" are cycled forward.
+"
+function! <SID>CycleBuffer(forward,...)
+ if <SID>IsBufferIgnored(bufnr('%')) == 1
+ return
+ endif
+
+ let curBufNum = bufnr('%')
+
+ if exists('a:1') && a:1 == 1
+ call <SID>DEBUG('MRUList is '.string(s:MRUList),1)
+ let curBufIndex = index(s:MRUList, l:curBufNum)
+ call <SID>DEBUG('curBufIndex is '.l:curBufIndex,1)
+ let forBufIndex = l:curBufIndex - 1 < 0 ? len(s:MRUList) - 1 : l:curBufIndex - 1
+ call <SID>DEBUG('forBufIndex is '.l:forBufIndex,1)
+ let bacBufIndex = l:curBufIndex + 1 >= len(s:MRUList) ? 0 : l:curBufIndex + 1
+ call <SID>DEBUG('bacBufIndex is '.l:bacBufIndex,1)
+
+ if a:forward
+ if !g:miniBufExplCycleArround && l:curBufIndex < l:forBufIndex
+ echo "You have reached the most recent buffer!"
+ return
+ endif
+ let l:moveCmd = 'b! '.s:MRUList[l:forBufIndex]
+ else
+ if !g:miniBufExplCycleArround && l:curBufIndex > l:bacBufIndex
+ echo "You have reached the least recent buffer!"
+ return
+ endif
+ let l:moveCmd = 'b! '.s:MRUList[l:bacBufIndex]
+ endif
+
+ let s:MRUEnable = 0
+ else
+ call <SID>DEBUG('BufList is '.string(s:BufList),1)
+ let curBufIndex = index(s:BufList, l:curBufNum)
+ call <SID>DEBUG('curBufIndex is '.l:curBufIndex,1)
+ let forBufIndex = l:curBufIndex + 1 >= len(s:BufList) ? 0 : l:curBufIndex + 1
+ call <SID>DEBUG('forBufIndex is '.l:forBufIndex,1)
+ let bacBufIndex = l:curBufIndex - 1 < 0 ? len(s:BufList) - 1 : l:curBufIndex - 1
+ call <SID>DEBUG('bacBufIndex is '.l:bacBufIndex,1)
+
+ if a:forward
+ if !g:miniBufExplCycleArround && l:curBufIndex > l:forBufIndex
+ echo "You have reached the last buffer!"
+ return
+ endif
+ let l:moveCmd = 'b! '.s:BufList[l:forBufIndex]
+ else
+ if !g:miniBufExplCycleArround && l:curBufIndex < l:bacBufIndex
+ echo "You have reached the first buffer!"
+ return
+ endif
+ let l:moveCmd = 'b! '.s:BufList[l:bacBufIndex]
+ endif
+
+ let s:MRUEnable = 1
+ endif
+
+ call <SID>DEBUG('===============move cmd is '.l:moveCmd,1)
+
+ " Change buffer (keeping track of before and after buffers)
+ exec l:moveCmd
+
+ let s:MRUEnable = 1
+endfunction
+
+" }}}
+" DeleteBuffer {{{
+"
+" Delete/Unload/Wipeout a buffer but preserve the window it was in
+"
+" a:action 0 bd, 1 bw, 2 bun
+" delete/wipeout/unload a buffer
+" a:bufNum
+" number of the buffer to be deleted
+"
+function! <SID>DeleteBuffer(action,bang,...)
+ call <SID>DEBUG('Entering DeleteBuffer('.a:action.','.a:bang.')',10)
+
+ if a:0 == 0
+ call <SID>DEBUG('No buffer is given, use current buffer',5)
+ let l:bufNums = [ bufnr('%') ]
+ else
+ call <SID>DEBUG('Given buffers are '.string(a:000),5)
+ let l:bufNums = map(copy(a:000),'v:val =~ ''\d\+'' ? bufnr(v:val + 0) : bufnr(v:val)')
+ endif
+
+ call <SID>DEBUG('Buffers to be deleted are '.string(l:bufNums),5)
+
+ for l:bufNum in l:bufNums
+ if <SID>IsBufferIgnored(l:bufNum)
+ call <SID>DEBUG('Buffer '.l:bufNum.'is not a normal buffer, skip it',5)
+ continue
+ endif
+
+ let l:bufName = bufname(l:bufNum)
+ call <SID>DEBUG('Buffer to be deleted is <'.l:bufName.'>['.l:bufNum.']',5)
+
+ " Don't want auto updates while we are processing a delete
+ " request.
+ let l:saveAutoUpdate = t:miniBufExplAutoUpdate
+ let t:miniBufExplAutoUpdate = 0
+
+ " Get the currently active buffer, so we can update the MBE
+ " correctly. If that is the buffer to be deleted, then get
+ " the window for that buffer, so we can find which buffer
+ " is in that window after the detaching.
+ let l:actBuf = <SID>GetActiveBuffer()
+ if l:actBuf == l:bufNum
+ let l:actBufWin = bufwinnr(l:actBuf)
+ endif
+
+ " Detach the buffer from all the windows that holding it
+ " in every tab page.
+ tabdo call <SID>DetachBuffer(l:bufNum)
+
+ " Find which buffer is in the active window now
+ if l:actBuf == l:bufNum
+ let l:actBuf = winbufnr(l:actBufWin)
+ endif
+
+ " Delete the buffer selected.
+ call <SID>DEBUG('About to delete buffer: '.l:bufNum,5)
+
+ if a:action == 2
+ let l:cmd = 'bun'
+ elseif a:action == 1
+ let l:cmd = 'bw'
+ else
+ let l:cmd = 'bd'
+ endif
+
+ if a:bang
+ let l:cmd = l:cmd.'!'
+ endif
+
+ let l:cmd = 'silent! '.l:cmd.' '.l:bufNum
+ call <SID>DEBUG('About to execute the command "'.l:cmd.'"',5)
+
+ exec l:cmd
+
+ let t:miniBufExplAutoUpdate = l:saveAutoUpdate
+
+ call <SID>UpdateExplorer(l:actBuf)
+ endfor
+
+ call <SID>DEBUG('Leaving DeleteBuffer()',10)
+endfunction
+
+" }}}
+" DetachBuffer {{{
+"
+" Detach a buffer from all the windows in which it is displayed.
+"
+function! <SID>DetachBuffer(bufNum)
+ call <SID>DEBUG('Entering DetachBuffer('.a:bufNum.')',10)
+
+ call <SID>DEBUG('We are currently in tab page '.tabpagenr(),10)
+
+ let l:bufNum = a:bufNum + 0
+
+ let l:winNum = bufwinnr(l:bufNum)
+ " while we have windows that contain our buffer
+ while l:winNum != -1
+ call <SID>DEBUG('Buffer '.l:bufNum.' is being displayed in window: '.l:winNum,5)
+
+ " move to window that contains our selected buffer
+ call s:SwitchWindow('w',1,l:winNum)
+
+ call <SID>DEBUG('We are now in window: '.winnr(),5)
+
+ call <SID>DEBUG('Window contains buffer: '.bufnr('%').' which should be: '.l:bufNum,5)
+ let l:origBuf = bufnr('%')
+ call <SID>CycleBuffer(0,1)
+ let l:currBuf = bufnr('%')
+ call <SID>DEBUG('Window now contains buffer: '.bufnr('%').' which should not be: '.l:bufNum,5)
+
+ if l:origBuf == l:currBuf
+ " we wrapped so we are going to have to delete a buffer
+ " that is in an open window.
+ let l:winNum = -1
+ else
+ " see if we have anymore windows with our selected buffer
+ let l:winNum = bufwinnr(l:bufNum)
+ endif
+ endwhile
+
+ call <SID>DEBUG('Leaving DetachBuffer()',10)
+endfunction
+
+" }}}
+" IsBufferIgnored - check to see if buffer should be ignored {{{
+"
+" Returns 0 if this buffer should be displayed in the list, 1 otherwise.
+"
+function! <SID>IsBufferIgnored(buf)
+ call <SID>DEBUG('Entering IsBufferIgnored('.a:buf.')',10)
+
+ " Skip unlisted buffers.
+ if buflisted(a:buf) == 0 || index(s:BufList,a:buf) == -1
+ call <SID>DEBUG('Buffer '.a:buf.' is unlisted, ignoring...',5)
+ call <SID>DEBUG('Leaving IsBufferIgnored()',10)
+ return 1
+ endif
+
+ " Skip non normal buffers.
+ if getbufvar(a:buf, "&buftype") != ''
+ call <SID>DEBUG('Buffer '.a:buf.' is not normal, ignoring...',5)
+ call <SID>DEBUG('Leaving IsBufferIgnored()',10)
+ return 1
+ endif
+
+ call <SID>DEBUG('Leaving IsBufferIgnored()',10)
+ return 0
+endfunction
+
+" }}}
+" BuildBufferList - Build the text for the MBE window {{{
+"
+" Creates the buffer list string and returns 1 if it is different than
+" last time this was called and 0 otherwise.
+"
+function! <SID>BuildBufferList(curBufNum)
+ call <SID>DEBUG('Entering BuildBufferList('.a:curBufNum.')',10)
+
+ let l:CurBufNum = a:curBufNum
+
+ " Get the number of the last buffer.
+ let l:NBuffers = bufnr('$')
+
+ let l:tabList = []
+ let l:maxTabWidth = 0
+
+ " Loop through every buffer less than the total number of buffers.
+ for l:i in s:BufList
+ let l:BufName = expand( "#" . l:i . ":p:t")
+
+ " Establish the tab's content, including the differentiating root
+ " dir if neccessary
+ let l:tab = '['
+ if g:miniBufExplShowBufNumbers == 1
+ let l:tab .= l:i.':'
+ endif
+ let l:tab .= s:bufUniqNameDict[l:i]
+ let l:tab .= ']'
+
+ " If the buffer is open in a window mark it
+ if bufwinnr(l:i) != -1
+ let l:tab .= '*'
+ endif
+
+ " If the buffer is modified then mark it
+ if(getbufvar(l:i, '&modified') == 1)
+ let l:tab .= '+'
+ endif
+
+ " If the buffer matches the)current buffer name, then mark it
+ call <SID>DEBUG('l:i is '.l:i.' and l:CurBufNum is '.l:CurBufNum,10)
+ if(l:i == l:CurBufNum)
+ let l:tab .= '!'
+ endif
+
+ let l:maxTabWidth = strlen(l:tab) > l:maxTabWidth ? strlen(l:tab) : l:maxTabWidth
+
+ call add(l:tabList, l:tab)
+ endfor
+
+ if t:miniBufExplSortBy == "name"
+ call sort(l:tabList, "<SID>NameCmp")
+ elseif t:miniBufExplSortBy == "mru"
+ call sort(l:tabList, "<SID>MRUCmp")
+ endif
+
+ let l:miniBufExplBufList = ''
+ for l:tab in l:tabList
+ let l:miniBufExplBufList = l:miniBufExplBufList.l:tab
+
+ " If horizontal and tab wrap is turned on we need to add spaces
+ if g:miniBufExplVSplit == 0
+ if g:miniBufExplTabWrap != 0
+ let l:miniBufExplBufList = l:miniBufExplBufList.' '
+ endif
+ " If not horizontal we need a newline
+ else
+ let l:miniBufExplBufList = l:miniBufExplBufList . "\n"
+ endif
+ endfor
+
+ if (s:miniBufExplBufList != l:miniBufExplBufList)
+ let s:maxTabWidth = l:maxTabWidth
+ let s:miniBufExplBufList = l:miniBufExplBufList
+ call <SID>DEBUG('Leaving BuildBufferList()',10)
+ return 1
+ else
+ call <SID>DEBUG('Leaving BuildBufferList()',10)
+ return 0
+ endif
+endfunction
+
+" }}}
+" CreateBufferUniqName {{{
+"
+" Construct a unique buffer name using the parts from the signature index of
+" the path.
+"
+function! <SID>CreateBufferUniqName(bufNum)
+ call <SID>DEBUG('Entering CreateBufferUniqName('.a:bufNum.')',10)
+
+ let l:bufNum = 0 + a:bufNum
+ let l:bufName = expand( "#" . l:bufNum . ":p:t")
+ " Remove []'s & ()'s, these chars are preserved for buffer name locating
+ let l:bufName = substitute(l:bufName, '[][()]', '', 'g')
+
+ " Create a unique name for unamed buffer
+ if empty(l:bufName)
+ call <SID>DEBUG('Leaving CreateBufferUniqName()',10)
+ return '--NO NAME--'.localtime()
+ endif
+
+ let l:bufPathPrefix = ""
+
+ if(!has_key(s:bufPathSignDict, l:bufNum))
+ call <SID>DEBUG(l:bufNum . ' is not in s:bufPathSignDict, aborting...',5)
+ call <SID>DEBUG('Leaving CreateBufferUniqName()',10)
+ return l:bufName
+ endif
+
+ let l:signs = s:bufPathSignDict[l:bufNum]
+ if(empty(l:signs))
+ call <SID>DEBUG('Signs for ' . l:bufNum . ' is empty, aborting...',5)
+ call <SID>DEBUG('Leaving CreateBufferUniqName()',10)
+ return l:bufName
+ endif
+
+ for l:sign in l:signs
+ call <SID>DEBUG('l:sign is ' . l:sign,5)
+ if empty(get(s:bufPathDict[l:bufNum],l:sign))
+ continue
+ endif
+ let l:bufPathSignPart = get(s:bufPathDict[l:bufNum],l:sign).'/'
+ " If the index is not right after the previous one and it is also not the
+ " last one, then put a '-' before it
+ if exists('l:last') && l:last + 1 != l:sign
+ let l:bufPathSignPart = '-/'.l:bufPathSignPart
+ endif
+ let l:bufPathPrefix = l:bufPathPrefix.l:bufPathSignPart
+ let l:last = l:sign
+ endfor
+ " If the last signature index is not the last index of the path, then put
+ " a '-' after it
+ if l:sign < len(s:bufPathDict[l:bufNum]) - 1
+ let l:bufPathPrefix = l:bufPathPrefix.'-/'
+ endif
+
+ call <SID>DEBUG('Uniq name for ' . l:bufNum . ' is ' . l:bufPathPrefix.l:bufName,5)
+
+ call <SID>DEBUG('Leaving CreateBufferUniqName()',10)
+
+ return l:bufPathPrefix.l:bufName
+endfunction
+
+" }}}
+" UpdateBufferNameDict {{{
+"
+function! <SID>UpdateBufferNameDict(bufNum,deleted)
+ call <SID>DEBUG('Entering UpdateBufferNameDict('.a:bufNum.','.a:deleted.')',10)
+
+ let l:bufNum = 0 + a:bufNum
+
+ let l:bufName = expand( "#" . l:bufNum . ":p:t")
+
+ " Identify buffers with no name
+ if empty(l:bufName)
+ let l:bufName = '--NO NAME--'
+ endif
+
+ " Remove a deleted buffer from the buffer name dictionary
+ if a:deleted
+ if has_key(s:bufNameDict, l:bufName)
+ call <SID>DEBUG('Found entry for deleted buffer '.l:bufNum,5)
+ let l:bufnrs = s:bufNameDict[l:bufName]
+ call filter(l:bufnrs, 'v:val != '.l:bufNum)
+ let s:bufNameDict[l:bufName] = l:bufnrs
+ call <SID>DEBUG('Delete entry for deleted buffer '.l:bufNum,5)
+ endif
+ call <SID>DEBUG('Leaving UpdateBufferNameDict()',10)
+ return
+ endif
+
+ if(!has_key(s:bufNameDict, l:bufName))
+ call <SID>DEBUG('Adding empty list for ' . l:bufName,5)
+ let s:bufNameDict[l:bufName] = []
+ endif
+
+ if index(s:bufNameDict[l:bufName],l:bufNum) == -1
+ call add(s:bufNameDict[l:bufName], l:bufNum)
+ endif
+
+ call <SID>DEBUG('Leaving UpdateBufferNameDict()',10)
+endfunction
+
+" }}}
+" UpdateBufferPathDict {{{
+"
+function! <SID>UpdateBufferPathDict(bufNum,deleted)
+ call <SID>DEBUG('Entering UpdateBufferPathDict('.a:bufNum.','.a:deleted.')',10)
+
+ let l:bufNum = 0 + a:bufNum
+ let l:bufPath = expand( "#" . l:bufNum . ":p:h")
+ let l:bufName = expand( "#" . l:bufNum . ":p:t")
+
+ " Identify buffers with no name
+ if empty(l:bufName)
+ let l:bufName = '--NO NAME--'
+ endif
+
+ " Remove a deleted buffer from the buffer path dictionary
+ if a:deleted
+ if has_key(s:bufNameDict, l:bufName)
+ call <SID>DEBUG('Found entry for deleted buffer '.l:bufNum,5)
+ let l:bufnrs = s:bufNameDict[l:bufName]
+ call filter(s:bufPathDict, 'v:key != '.l:bufNum)
+ call <SID>DEBUG('Delete entry for deleted buffer '.l:bufNum,5)
+ endif
+ call <SID>DEBUG('Leaving UpdateBufferPathDict()',10)
+ return
+ endif
+
+ let s:bufPathDict[l:bufNum] = split(l:bufPath,s:PathSeparator,0)
+
+ call <SID>DEBUG('Leaving UpdateBufferPathDict()',10)
+endfunction
+
+" }}}
+" BuildBufferPathSignDict {{{
+"
+" Compare the parts from the same index of all the buffer's paths, if there
+" are differences, it means this index is a signature index for all the
+" buffer's paths, mark it. At this point, the buffers are splited into several
+" subsets. Then, doing the same check for each subset on the next index. We
+" should finally get a set of signature locations which will uniquely identify
+" the path. We could then construct a string with these locaitons using as
+" less characters as possible.
+"
+function! <SID>BuildBufferPathSignDict(bufnrs, ...)
+ if a:0 == 0
+ let index = 0
+ else
+ let index = a:1
+ endif
+
+ call <SID>DEBUG('Entering BuildBufferPathSignDict('.string(a:bufnrs).','.index.')',10)
+
+ let bufnrs = a:bufnrs
+
+ " Temporary dictionary to see if there is any different part
+ let partDict = {}
+
+ " Marker to see if there are more avaliable parts
+ let moreParts = 0
+
+ " Group the buffers by this part of the buffer's path
+ for bufnr in bufnrs
+ " Make sure each buffer has an entry in 's:bufPathSignDict'
+ " If index is zero, we force re-initialize the entry
+ if index == 0 || !has_key(s:bufPathSignDict, bufnr)
+ let s:bufPathSignDict[bufnr] = []
+ endif
+
+ " If some buffers' path does not have this index, we skip it
+ if len(s:bufPathDict[bufnr]) < index
+ continue
+ endif
+
+ " Mark that there are still available paths
+ let moreParts = 1
+
+ " Get requested part of the path
+ let part = get(s:bufPathDict[bufnr],index)
+
+ if empty(part)
+ let part = '--EMPTY--'
+ endif
+
+ " Group the buffers using dictionary by this part
+ if(!has_key(partDict, part))
+ let partDict[part] = []
+ endif
+ call add(partDict[part],bufnr)
+ endfor
+
+ " All the paths have been walked to the end
+ if !moreParts
+ call <SID>DEBUG('Leaving BuildBufferPathSignDict() '.index,10)
+ return
+ endif
+
+ " We only need the buffer subsets from now on
+ let subsets = values(partDict)
+
+ " If the buffers have been splited into more than one subset, or all the
+ " remaining buffers are still in the same subset but some buffers' path
+ " have hit the end, then mark this index as signature index.
+ if len(partDict) > 1 || ( len(partDict) == 1 && len(subsets[0]) < len(bufnrs) )
+ " Store the signature index in the 's:bufPathSignDict' variable
+ for bufnr in bufnrs
+ call add(s:bufPathSignDict[bufnr],index)
+ endfor
+ " For all buffer subsets, increase the index by one, run again.
+ for subset in subsets
+ " If we only have one buffer left in the subset, it means there are
+ " already enough signature index sufficient to identify the buffer
+ if len(subset) <= 1
+ continue
+ endif
+ call <SID>BuildBufferPathSignDict(subset, index + 1)
+ endfor
+ " If all the buffers are in the same subset, then this index is not a
+ " signature index, increase the index by one, run again.
+ else
+ call <SID>BuildBufferPathSignDict(bufnrs, index + 1)
+ endif
+
+ call <SID>DEBUG('Leaving BuildBufferPathSignDict() '.index,10)
+endfunction
+
+" }}}
+" UpdateBufferPathSignDict {{{
+"
+function! <SID>UpdateBufferPathSignDict(bufNum,deleted)
+ call <SID>DEBUG('Entering UpdateBufferPathSignDict('.a:bufNum.','.a:deleted.')',10)
+
+ let l:bufNum = 0 + a:bufNum
+
+ " Remove a deleted buffer from the buffer path signature dictionary
+ if a:deleted
+ if has_key(s:bufPathSignDict, l:bufNum)
+ call <SID>DEBUG('Found entry for deleted buffer '.l:bufNum,5)
+ call filter(s:bufPathSignDict, 'v:key != '.l:bufNum)
+ call <SID>DEBUG('Delete entry for deleted buffer '.l:bufNum,5)
+ endif
+ call <SID>DEBUG('Leaving UpdateBufferPathSignDict()',10)
+ return
+ endif
+
+ call <SID>DEBUG('Leaving UpdateBufferPathSignDict()',10)
+endfunction
+
+" }}}
+" BuildBufferFinalDict {{{
+"
+function! <SID>BuildBufferFinalDict(arg,deleted)
+ call <SID>DEBUG('Entering BuildBufferFinalDict('.string(a:arg).','.a:deleted.')',10)
+
+ if type(a:arg) == 3
+ let l:bufnrs = a:arg
+ else
+ let l:bufNum = 0 + a:arg
+ let l:bufName = expand( "#" . l:bufNum . ":p:t")
+
+ " Identify buffers with no name
+ if empty(l:bufName)
+ let l:bufName = '--NO NAME--'
+ endif
+
+ if(!has_key(s:bufNameDict, l:bufName))
+ call <SID>DEBUG(l:bufName . ' is not in s:bufNameDict, aborting...',5)
+ call <SID>DEBUG('Leaving BuildBufferFinalDict()',10)
+ return
+ endif
+
+ let l:bufnrs = s:bufNameDict[l:bufName]
+
+ " Remove a deleted buffer from the buffer unique name dictionary
+ if a:deleted
+ call <SID>UpdateBufferPathSignDict(l:bufNum, a:deleted)
+ call <SID>UpdateBufferUniqNameDict(l:bufNum, a:deleted)
+ endif
+ endif
+
+ call <SID>BuildBufferPathSignDict(l:bufnrs)
+
+ call <SID>BuildBufferUniqNameDict(l:bufnrs)
+
+ call <SID>DEBUG('Leaving BuildBufferFinalDict()',10)
+endfunction
+
+" }}}
+" BuildBufferUniqNameDict {{{
+"
+function! <SID>BuildBufferUniqNameDict(bufnrs)
+ call <SID>DEBUG('Entering BuildBufferUniqNameDict('.string(a:bufnrs).')',10)
+
+ let l:bufnrs = a:bufnrs
+
+ for bufnr in l:bufnrs
+ call <SID>UpdateBufferUniqNameDict(bufnr,0)
+ endfor
+
+ call <SID>DEBUG('Leaving BuildBufferUniqNameDict()',10)
+endfunction
+
+" }}}
+" UpdateBufferUniqNameDict {{{
+"
+function! <SID>UpdateBufferUniqNameDict(bufNum,deleted)
+ call <SID>DEBUG('Entering UpdateBufferUniqNameDict('.a:bufNum.','.a:deleted.')',10)
+
+ let l:bufNum = 0 + a:bufNum
+
+ " Remove a deleted buffer from the buffer path dictionary
+ if a:deleted
+ if has_key(s:bufUniqNameDict, l:bufNum)
+ call <SID>DEBUG('Found entry for deleted buffer '.l:bufNum,5)
+ call filter(s:bufUniqNameDict, 'v:key != '.l:bufNum)
+ call <SID>DEBUG('Delete entry for deleted buffer '.l:bufNum,5)
+ endif
+ call <SID>DEBUG('Leaving UpdateBufferUniqNameDict()',10)
+ return
+ endif
+
+ call <SID>DEBUG('Creating buffer name for ' . l:bufNum,5)
+ let l:bufUniqName = <SID>CreateBufferUniqName(l:bufNum)
+
+ call <SID>DEBUG('Setting ' . l:bufNum . ' to ' . l:bufUniqName,5)
+ let s:bufUniqNameDict[l:bufNum] = l:bufUniqName
+
+ call <SID>DEBUG('Leaving UpdateBufferUniqNameDict()',10)
+endfunction
+
+" }}}
+" BuildAllBufferDicts {{{
+"
+function! <SID>BuildAllBufferDicts()
+ call <SID>DEBUG('Entering BuildAllBuffersDicts()',10)
+
+ " Get the number of the last buffer.
+ let l:NBuffers = bufnr('$')
+
+ " Loop through every buffer less than the total number of buffers.
+ let l:i = 0
+ while(l:i <= l:NBuffers)
+ if <SID>IsBufferIgnored(l:i)
+ let l:i = l:i + 1
+ continue
+ endif
+
+ call <SID>UpdateBufferNameDict(l:i,0)
+ call <SID>UpdateBufferPathDict(l:i,0)
+ call <SID>UpdateBufferStateDict(l:i,0)
+
+ let l:i = l:i + 1
+ endwhile
+
+ for bufnrs in values(s:bufNameDict)
+ call <SID>BuildBufferFinalDict(bufnrs,0)
+ endfor
+
+ call <SID>DEBUG('Leaving BuildAllBuffersDicts()',10)
+endfunction
+
+" }}}
+" UpdateAllBufferDicts {{{
+"
+function! <SID>UpdateAllBufferDicts(bufNum,deleted)
+ call <SID>DEBUG('Entering UpdateAllBuffersDicts('.a:bufNum.','.a:deleted.')',10)
+
+ call <SID>UpdateBufferNameDict(a:bufNum,a:deleted)
+ call <SID>UpdateBufferPathDict(a:bufNum,a:deleted)
+ call <SID>UpdateBufferStateDict(a:bufNum,a:deleted)
+
+ call <SID>BuildBufferFinalDict(a:bufNum,a:deleted)
+
+ call <SID>DEBUG('Leaving UpdateAllBuffersDicts()',10)
+endfunction
+
+" }}}
+" UpdateBufferStateDict {{{
+function! <SID>UpdateBufferStateDict(bufNum,deleted)
+ call <SID>DEBUG('Entering UpdateBufferStateDict('.a:bufNum.','.a:deleted.')',10)
+
+ let l:bufNum = 0 + a:bufNum
+
+ if a:deleted && has_key(s:bufStateDict, l:bufNum)
+ call filter(s:bufStateDict, 'v:key != '.l:bufNum)
+ call <SID>DEBUG('Leaving UpdateBufferStateDict()',10)
+ return
+ endif
+
+ if has_key(s:bufStateDict, l:bufNum)
+ if s:bufStateDict[l:bufNum] != getbufvar(a:bufNum, '&modified')
+ let s:bufStateDict[l:bufNum] = getbufvar(a:bufNum, '&modified')
+ call <SID>AutoUpdate(bufnr(a:bufNum),0)
+ endif
+ else
+ let s:bufStateDict[l:bufNum] = getbufvar(a:bufNum, '&modified')
+ endif
+
+ call <SID>DEBUG('Leaving UpdateBufferStateDict()',10)
+endfunction
+
+" }}}
+" NameCmp - compares tabs based on filename {{{
+"
+function! <SID>NameCmp(tab1, tab2)
+ let l:name1 = matchstr(a:tab1, ":.*")
+ let l:name2 = matchstr(a:tab2, ":.*")
+ if l:name1 < l:name2
+ return -1
+ elseif l:name1 > l:name2
+ return 1
+ else
+ return 0
+ endif
+endfunction
+
+" }}}
+" MRUCmp - compares tabs based on MRU order {{{
+"
+function! <SID>MRUCmp(tab1, tab2)
+ let l:buf1 = str2nr(matchstr(a:tab1, '[0-9]\+'))
+ let l:buf2 = str2nr(matchstr(a:tab2, '[0-9]\+'))
+ return index(s:MRUList, l:buf1) - index(s:MRUList, l:buf2)
+endfunction
+
+" }}}
+" HasEligibleBuffers - Are there enough MBE eligible buffers to open the MBE window? {{{
+"
+" Returns 1 if there are any buffers that can be displayed in a
+" mini buffer explorer. Otherwise returns 0.
+"
+function! <SID>HasEligibleBuffers()
+ call <SID>DEBUG('Entering HasEligibleBuffers()',10)
+
+ let l:found = len(s:BufList)
+ let l:needed = g:miniBufExplBuffersNeeded
+
+ call <SID>DEBUG('Eligible buffers are '.string(s:BufList),6)
+ call <SID>DEBUG('Found '.l:found.' eligible buffers of '.l:needed.' needed',6)
+
+ call <SID>DEBUG('Leaving HasEligibleBuffers()',10)
+ return (l:found >= l:needed)
+endfunction
+
+" }}}
+" Auto Update - Function called by auto commands for auto updating the MBE {{{
+"
+" IF auto update is turned on AND
+" we are in a real buffer AND
+" we have enough eligible buffers THEN
+" Update our explorer and get back to the current window
+"
+" If we get a buffer number for a buffer that
+" is being deleted, we need to make sure and
+" remove the buffer from the list of eligible
+" buffers in case we are down to one eligible
+" buffer, in which case we will want to close
+" the MBE window.
+"
+function! <SID>AutoUpdate(curBufNum,force)
+ call <SID>DEBUG('Entering AutoUpdate('.a:curBufNum.')',10)
+
+ call <SID>DEBUG('Current state: '.winnr().' : '.bufnr('%').' : '.bufname('%'),10)
+
+ if (s:miniBufExplInAutoUpdate == 1)
+ call <SID>DEBUG('AutoUpdate recursion stopped',9)
+ call <SID>DEBUG('Leaving AutoUpdate()',10)
+ return
+ else
+ let s:miniBufExplInAutoUpdate = 1
+ endif
+
+ " Skip windows holding ignored buffer
+ if !a:force && <SID>IsBufferIgnored(a:curBufNum) == 1
+ call <SID>DEBUG('Leaving AutoUpdate()',10)
+
+ let s:miniBufExplInAutoUpdate = 0
+ return
+ endif
+
+ if s:MRUEnable == 1
+ call <SID>ListPush(s:MRUList,a:curBufNum)
+ endif
+
+ " Only allow updates when the AutoUpdate flag is set
+ " this allows us to stop updates on startup.
+ if exists('t:miniBufExplAutoUpdate') && t:miniBufExplAutoUpdate == 1
+ " if we don't have a window then create one
+ let l:winnr = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+ if (exists('t:skipEligibleBuffersCheck') && t:skipEligibleBuffersCheck == 1) || <SID>HasEligibleBuffers() == 1
+ if (l:winnr == -1)
+ if g:miniBufExplAutoStart == 1
+ call <SID>DEBUG('MiniBufExplorer was not running, starting...', 9)
+ call <SID>StartExplorer(a:curBufNum)
+ else
+ call <SID>DEBUG('MiniBufExplorer was not running, aborting...', 9)
+ call <SID>DEBUG('Leaving AutoUpdate()',10)
+ let s:miniBufExplInAutoUpdate = 0
+ return
+ endif
+ else
+ call <SID>DEBUG('Updating MiniBufExplorer...', 9)
+ call <SID>UpdateExplorer(a:curBufNum)
+ endif
+ else
+ if (l:winnr == -1)
+ call <SID>DEBUG('MiniBufExplorer was not running, aborting...', 9)
+ call <SID>DEBUG('Leaving AutoUpdate()',10)
+ let s:miniBufExplInAutoUpdate = 0
+ return
+ else
+ call <SID>DEBUG('Failed in eligible check', 9)
+ call <SID>StopExplorer(0)
+ " we do not want to turn auto-updating off
+ let t:miniBufExplAutoUpdate = 1
+ endif
+ endif
+ else
+ call <SID>DEBUG('AutoUpdates are turned off, terminating',9)
+ endif
+
+ call <SID>DEBUG('Leaving AutoUpdate()',10)
+
+ let s:miniBufExplInAutoUpdate = 0
+endfunction
+
+" }}}
+" QuitIfLastOpen {{{
+"
+function! <SID>QuitIfLastOpen() abort
+ " Quit MBE if no more mormal window left
+ if (bufname('%') == '-MiniBufExplorer-') && (<SID>NextNormalWindow() == -1)
+ call <SID>DEBUG('MBE is the last open window, quit it', 9)
+ if tabpagenr('$') == 1
+ " Before quitting Vim, delete the MBE buffer so that
+ " the '0 mark is correctly set to the previous buffer.
+ " Also disable autocmd on this command to avoid unnecessary
+ " autocmd nesting.
+ if winnr('$') == 1
+ noautocmd bdelete
+ endif
+ quit
+ else
+ close
+ endif
+ endif
+endfunction
+
+" }}}
+" GetActiveBuffer {{{
+"
+function! <SID>GetActiveBuffer()
+ call <SID>DEBUG('Entering GetActiveBuffer()',10)
+ let l:bufNum = substitute(s:miniBufExplBufList,'\[\([0-9]*\):[^\]]*\][^\!]*!', '\1', '') + 0
+ call <SID>DEBUG('Currently active buffer is '.l:bufNum,10)
+ call <SID>DEBUG('Leaving GetActiveBuffer()',10)
+ return l:bufNum
+endfunction
+
+" }}}
+" GetSelectedBuffer - From the MBE window, return the bufnum for buf under cursor {{{
+"
+" If we are in our explorer window then return the buffer number
+" for the buffer under the cursor.
+"
+function! <SID>GetSelectedBuffer()
+ call <SID>DEBUG('Entering GetSelectedBuffer()',10)
+
+ " Make sure we are in our window
+ if bufname('%') != '-MiniBufExplorer-'
+ call <SID>DEBUG('GetSelectedBuffer called in invalid window',1)
+ call <SID>DEBUG('Leaving GetSelectedBuffer()',10)
+ return -1
+ endif
+
+ let l:save_rep = &report
+ let l:save_sc = &showcmd
+ let &report = 10000
+ set noshowcmd
+
+ let l:save_reg = @"
+ let @" = ""
+ normal ""yi[
+ if @" != ""
+ if !g:miniBufExplShowBufNumbers
+ " This is a bit ugly, but it works, unless we come up with a
+ " better way to get the key for a dictionary by its value.
+ let l:bufUniqNameDictKeys = keys(s:bufUniqNameDict)
+ let l:bufUniqNameDictValues = values(s:bufUniqNameDict)
+ let l:retv = l:bufUniqNameDictKeys[match(l:bufUniqNameDictValues,substitute(@",'[0-9]*:\(.*\)', '\1', ''))]
+ else
+ let l:retv = substitute(@",'\([0-9]*\):.*', '\1', '') + 0
+ endif
+ let @" = l:save_reg
+ call <SID>DEBUG('Leaving GetSelectedBuffer()',10)
+ return l:retv
+ else
+ let @" = l:save_reg
+ call <SID>DEBUG('Leaving GetSelectedBuffer()',10)
+ return -1
+ endif
+
+ let &report = l:save_rep
+ let &showcmd = l:save_sc
+endfunction
+
+" }}}
+" MBESelectBuffer - From the MBE window, open buffer under the cursor {{{
+"
+" If we are in our explorer, then we attempt to open the buffer under the
+" cursor in the previous window.
+"
+" Split indicates whether to open with split, 0 no split, 1 split horizontally
+"
+function! <SID>MBESelectBuffer(split)
+ call <SID>DEBUG('Entering MBESelectBuffer()',10)
+
+ " Make sure we are in our window
+ if bufname('%') != '-MiniBufExplorer-'
+ call <SID>DEBUG('MBESelectBuffer called in invalid window',1)
+ call <SID>DEBUG('Leaving MBESelectBuffer()',10)
+ return
+ endif
+
+ let l:bufnr = <SID>GetSelectedBuffer()
+
+ if(l:bufnr != -1) " If the buffer exists.
+ let l:saveAutoUpdate = t:miniBufExplAutoUpdate
+ let t:miniBufExplAutoUpdate = 0
+
+ call s:SwitchWindow('p',1)
+
+ if <SID>IsBufferIgnored(bufnr('%'))
+ let l:winNum = <SID>NextNormalWindow()
+ if l:winNum != -1
+ call s:SwitchWindow('w',1,l:winNum)
+ else
+ call <SID>DEBUG('No elegible window avaliable',1)
+ call <SID>DEBUG('Leaving MBESelectBuffer()',10)
+ return
+ endif
+ endif
+
+ if a:split == 0
+ exec 'b! '.l:bufnr
+ elseif a:split == 1
+ exec 'sb! '.l:bufnr
+ elseif a:split == 2
+ exec 'vertical sb! '.l:bufnr
+ endif
+
+ let t:miniBufExplAutoUpdate = l:saveAutoUpdate
+
+ call <SID>AutoUpdate(bufnr("%"),0)
+ endif
+
+ if g:miniBufExplCloseOnSelect == 1
+ call <SID>StopExplorer(0)
+ endif
+
+ call <SID>DEBUG('Leaving MBESelectBuffer()',10)
+endfunction
+
+" }}}
+" MBEDeleteBuffer - From the MBE window, delete selected buffer from list {{{
+"
+" After making sure that we are in our explorer, This will delete the buffer
+" under the cursor. If the buffer under the cursor is being displayed in a
+" window, this routine will attempt to get different buffers into the
+" windows that will be affected so that windows don't get removed.
+"
+function! <SID>MBEDeleteBuffer()
+ call <SID>DEBUG('Entering MBEDeleteBuffer()',10)
+
+ " Make sure we are in our window
+ if bufname('%') != '-MiniBufExplorer-'
+ call <SID>DEBUG('MBEDeleteBuffer called in invalid window',1)
+ call <SID>DEBUG('Leaving MBEDeleteBuffer()',10)
+ return
+ endif
+
+ let l:selBuf = <SID>GetSelectedBuffer()
+
+ if l:selBuf != -1
+ call <SID>DeleteBuffer(0,0,l:selBuf)
+ endif
+
+ call <SID>DEBUG('Leaving MBEDeleteBuffer()',10)
+endfunction
+
+" }}}
+" NextNormalWindow {{{
+"
+function! <SID>NextNormalWindow()
+ call <SID>DEBUG('Entering NextNormalWindow()',10)
+
+ let l:winSum = winnr('$')
+ call <SID>DEBUG('Total number of open windows are '.l:winSum,9)
+
+ let l:i = 1
+ while(l:i <= l:winSum)
+ call <SID>DEBUG('window: '.l:i.', buffer: ('.winbufnr(l:i).':'.bufname(winbufnr(l:i)).')',9)
+ if !<SID>IsBufferIgnored(winbufnr(l:i)) && l:i != winnr()
+ call <SID>DEBUG('Found window '.l:i,8)
+ call <SID>DEBUG('Leaving NextNormalWindow()',10)
+ return l:i
+ endif
+ let l:i = l:i + 1
+ endwhile
+
+ call <SID>DEBUG('Found no window',8)
+ call <SID>DEBUG('Leaving NextNormalWindow()',10)
+ return -1
+endfunction
+
+" }}}
+" ListAdd {{{
+"
+function! <SID>ListAdd(list,val)
+ call <SID>DEBUG('Entering ListAdd('.string(a:list).','.a:val.')',10)
+ call add(a:list, a:val)
+ call <SID>DEBUG('Leaving ListAdd()',10)
+endfunction
+
+" }}}
+" ListPop {{{
+"
+function! <SID>ListPop(list,val)
+ call <SID>DEBUG('Entering ListPop('.string(a:list).','.a:val.')',10)
+ call filter(a:list, 'v:val != '.a:val)
+ call <SID>DEBUG('Leaving ListPop()',10)
+endfunction
+
+" }}}
+" ListPush {{{
+"
+function! <SID>ListPush(list,val)
+ call <SID>DEBUG('Entering ListPush('.string(a:list).','.a:val.')',10)
+ " Remove the buffer number from the list if it already exists.
+ call <SID>ListPop(a:list,a:val)
+
+ " Add the buffer number to the head of the list.
+ call insert(a:list,a:val)
+ call <SID>DEBUG('Leaving ListPush()',10)
+endfunction
+
+" }}}
+" DEBUG - Display debug output when debugging is turned on {{{
+"
+" Thanks to Charles E. Campbell, Jr. PhD <cec@NgrOyphSon.gPsfAc.nMasa.gov>
+" for Decho.vim which was the inspiration for this enhanced debugging
+" capability.
+"
+let g:miniBufExplFuncCallDepth = 0
+function! <SID>DEBUG(msg, level)
+ if g:miniBufExplDebugLevel >= a:level
+
+ if a:level == 10 && a:msg =~ '^Entering'
+ let g:miniBufExplFuncCallDepth += 1
+ endif
+
+ if a:msg =~ '^Entering'
+ let l:msg = repeat('│ ',g:miniBufExplFuncCallDepth - 1).'┌ '.a:msg
+ elseif a:msg =~ '^Leaving'
+ let l:msg = repeat('│ ',g:miniBufExplFuncCallDepth - 1).'└ '.a:msg
+ else
+ let l:msg = repeat('│ ',g:miniBufExplFuncCallDepth).a:msg
+ endif
+
+ " Prevent a report of our actions from showing up.
+ let l:save_rep = &report
+ let l:save_sc = &showcmd
+ let &report = 10000
+ set noshowcmd
+
+ " Debug output to a buffer
+ if g:miniBufExplDebugMode == 0
+ if bufname('%') == 'MiniBufExplorer.DBG'
+ return
+ endif
+
+ " Get into the debug window or create it if needed
+ let l:winNum = <SID>FindCreateWindow('MiniBufExplorer.DBG', 0, 1, 1, 1, 0)
+
+ if l:winNum == -1
+ let g:miniBufExplDebugMode == 3
+ call <SID>DEBUG('Failed to get the MBE debugging window, reset debugging mode to 3.',1)
+ call <SID>DEBUG('Forwarding message...',1)
+ call <SID>DEBUG(a:msg,1)
+ call <SID>DEBUG('Forwarding message end.',1)
+ return
+ endif
+
+ " Save the current window number so we can come back here
+ let l:currWin = winnr()
+ call s:SwitchWindow('p',1)
+
+ " Change to debug window
+ call s:SwitchWindow('w',1,l:winNum)
+
+ " Make sure we really got to our window, if not we
+ " will display a confirm dialog and turn debugging
+ " off so that we won't break things even more.
+ if bufname('%') != 'MiniBufExplorer.DBG'
+ call confirm('Error in window debugging code. Dissabling MiniBufExplorer debugging.', 'OK')
+ let g:miniBufExplDebugLevel = 0
+ return
+ endif
+
+ set modified
+
+ " Write Message to DBG buffer
+ let res=append("$",s:debugIndex.':'.a:level.':'.a:msg)
+
+ set nomodified
+
+ norm G
+
+ " Return to original window
+ call s:SwitchWindow('p',1)
+ call s:SwitchWindow('w',1,l:currWin)
+ " Debug output using VIM's echo facility
+ elseif g:miniBufExplDebugMode == 1
+ echo s:debugIndex.':'.a:level.':'.a:msg
+ " Debug output to a file -- VERY SLOW!!!
+ " should be OK on UNIX and Win32 (not the 95/98 variants)
+ elseif g:miniBufExplDebugMode == 2
+ if has('system') || has('fork')
+ if has('win32') && !has('win95')
+ let l:result = system("cmd /c 'echo ".s:debugIndex.':'.a:level.':'.a:msg." >> MiniBufExplorer.DBG'")
+ endif
+ if has('unix')
+ let l:result = system("echo '".s:debugIndex.':'.a:level.':'.a:msg." >> MiniBufExplorer.DBG'")
+ endif
+ else
+ call confirm('Error in file writing version of the debugging code, vim not compiled with system or fork. Dissabling MiniBufExplorer debugging.', 'OK')
+ let g:miniBufExplDebugLevel = 0
+ endif
+ elseif g:miniBufExplDebugMode == 3
+ let g:miniBufExplDebugOutput = g:miniBufExplDebugOutput."\n".s:debugIndex."\t".':'.a:level."\t".':'.l:msg
+ endif
+
+ let s:debugIndex = s:debugIndex + 1
+
+ if a:level == 10 && a:msg =~ '^Leaving'
+ let g:miniBufExplFuncCallDepth -= 1
+ endif
+
+ let &report = l:save_rep
+ let &showcmd = l:save_sc
+ endif
+endfunc
+
+" }}}
+" SwitchWindow {{{
+"
+function! s:SwitchWindow(action, ...)
+ call <SID>DEBUG('Entering SwitchWindow('.a:action.','.string(a:000).')',10)
+
+ if a:action !~ '[hjkltbwWpP]'
+ call <SID>DEBUG('invalid window action : '.a:action,10)
+ call <SID>DEBUG('Leaving SwitchWindow()',10)
+ return
+ endif
+
+ if exists('a:1') && a:1 == 1
+ let l:aucmd = 'noautocmd '
+ else
+ let l:aucmd = ''
+ endif
+
+ if exists('a:2')
+ let l:winnr = a:2
+ else
+ let l:winnr = ''
+ endif
+
+ call <SID>DEBUG('previous window is: '.winnr(),10)
+ let l:wincmd = l:aucmd.l:winnr.'wincmd '.a:action
+ call <SID>DEBUG('window switching command is: '.l:wincmd,10)
+ exec l:wincmd
+ call <SID>DEBUG('current window is: '.winnr(),10)
+
+ call <SID>DEBUG('Leaving SwitchWindow()',10)
+endfunction
+
+" }}}
+
+" vim:ft=vim:fdm=marker:ff=unix:nowrap:tabstop=2:shiftwidth=2:softtabstop=2:smarttab:shiftround:expandtab