Rainbow
[my-vim-dotfolder.git] / plugin / minibufexplpp.vim
blob3a3fe851641c7e54cf2791e8b07f96710413c9b5
1 " Mini Buffer Explorer <minibufexpl.vim>
3 " HINT: Type zR if you don't know how to use folds
5 " Script Info and Documentation  {{{
6 "=============================================================================
7 "    Copyright: Copyright (C) 2002 & 2003 Bindu Wavell 
8 "               Copyright (C) 2010 Oliver Uvman
9 "               Permission is hereby granted to use and distribute this code,
10 "               with or without modifications, provided that this copyright
11 "               notice is copied with it. Like anything else that's free,
12 "               minibufexplpp.vim is provided *as is* and comes with no
13 "               warranty of any kind, either expressed or implied. In no
14 "               event will the copyright holder be liable for any damamges
15 "               resulting from the use of this software.
17 " Name Of File: minibufexplpp.vim
18 "  Description: Mini Buffer Explorer Vim Plugin Extended
19 "   Maintainer: Bindu Wavell <bindu@wavell.net>
20 "          URL: http://vim.sourceforge.net/scripts/script.php?script_id=159
21 "  Last Change: Thursday, August 5, 2010
22 "      Version: 6.3.3
23 "               Derived from Jeff Lanzarotta's bufexplorer.vim version 6.0.7
24 "               Jeff can be reached at (jefflanzarotta@yahoo.com) and the
25 "               original plugin can be found at:
26 "               http://lanzarotta.tripod.com/vim/plugin/6/bufexplorer.vim.zip
28 "        Usage: Normally, this file should reside in the plugins
29 "               directory and be automatically sourced. If not, you must
30 "               manually source this file using ':source minibufexplorer.vim'.
32 "               You may use the default keymappings of
34 "                 <Leader>mbe - Opens MiniBufExplorer
36 "               or you may want to add something like the following
37 "               key mapping to your _vimrc/.vimrc file.
39 "                 map <Leader>b :MiniBufExplorer<cr>
41 "               However, in most cases you won't need any key-bindings at all.
43 "               <Leader> is usually backslash so type "\mbe" (quickly) to open 
44 "               the -MiniBufExplorer- window.
46 "               Other keymappings include: <Leader>mbc to close the Explorer
47 "               window,  <Leader>mbu to force the Explorer to Update and
48 "               <Leader>mbt to toggle the Explorer window; it will open if
49 "               closed or close if open. Each of these key bindings can be
50 "               overridden (see the notes on <Leader>mbe above.)
51
52 "               You can map these additional commands as follows:
54 "                 map <Leader>c :CMiniBufExplorer<cr>
55 "                 map <Leader>u :UMiniBufExplorer<cr>
56 "                 map <Leader>t :TMiniBufExplorer<cr>
58 "               NOTE: you can change the key binding used in these mappings
59 "                     so that they fit with your configuration of vim.
61 "               You can also call each of these features by typing the
62 "               following in command mode:
64 "                 :MiniBufExplorer    " Open and/or goto Explorer
65 "                 :CMiniBufExplorer   " Close the Explorer if it's open
66 "                 :UMiniBufExplorer   " Update Explorer without navigating
67 "                 :TMiniBufExplorer   " Toggle the Explorer window open and 
68 "                                       closed.
70 "               To control where the new split window goes relative to the 
71 "               current window, use the setting:
73 "                 let g:miniBufExplSplitBelow=0  " Put new window above
74 "                                                " current or on the
75 "                                                " left for vertical split
76 "                 let g:miniBufExplSplitBelow=1  " Put new window below
77 "                                                " current or on the
78 "                                                " right for vertical split
80 "               The default for this is read from the &splitbelow VIM option.
82 "               By default we are now (as of 6.0.2) forcing the -MiniBufExplorer-
83 "               window to open up at the edge of the screen. You can turn this 
84 "               off by setting the following variable in your .vimrc:
86 "                 let g:miniBufExplSplitToEdge = 0
88 "               If you would like a vertical explorer you can assign the column
89 "               width (in characters) you want for your explorer window with the
90 "               following .vimrc variable (this was introduced in 6.3.0):
92 "                 let g:miniBufExplVSplit = 20   " column width in chars
94 "               IN HORIZONTAL MODE:
95 "               It is now (as of 6.1.1) possible to set a maximum height for
96 "               the -MiniBufExplorer- window. You can set the max height by
97 "               letting the following variable in your .vimrc:
99 "                 let g:miniBufExplMaxSize = <max lines: defualt 0>
100 "               
101 "               setting this to 0 will mean the window gets as big as
102 "               needed to fit all your buffers. 
104 "               NOTE: This was g:miniBufExplMaxHeight before 6.3.0; the old
105 "               setting is backwards compatible if you don't use MaxSize.
107 "               As of 6.2.2 it is possible to set a minimum height for the 
108 "               -MiniBufExplorer- window. You can set the min height by
109 "               letting the following variable in your .vimrc:
111 "                 let g:miniBufExplMinSize = <min height: default 1>
113 "               NOTE: This was g:miniBufExplMinHeight before 6.3.0; the old
114 "               setting is backwards compatible if you don't use MinSize.
116 "               IN VERTICAL MODE: (as of 6.3.0)
117 "               By default the vertical explorer has a fixed width. If you put:
119 "                 let g:miniBufExplMaxSize = <max width: default 0> 
121 "               into your .vimrc then MBE will attempt to set the width of the
122 "               MBE window to be as wide as your widest tab. The width will not
123 "               exceed MaxSize even if you have wider tabs. 
125 "               Accepting the default value of 0 for this will give you a fixed
126 "               width MBE window.
128 "               You can specify a MinSize for the vertical explorer window by
129 "               putting the following in your .vimrc:
131 "                 let g:miniBufExplMinSize = <min width: default 1>
133 "               This will have no effect unless you also specivy MaxSize.
135 "               By default we are now (as of 6.0.1) turning on the MoreThanOne
136 "               option. This stops the -MiniBufExplorer- from opening 
137 "               automatically until more than one eligible buffer is available.
138 "               You can turn this feature off by setting the following variable
139 "               in your .vimrc:
140 "                 
141 "                 let g:miniBufExplorerMoreThanOne=1
143 "               (The following enhancement is as of 6.2.2)
144 "               Setting this to 0 will cause the MBE window to be loaded even
145 "               if no buffers are available. Setting it to 1 causes the MBE
146 "               window to be loaded as soon as an eligible buffer is read. You
147 "               can also set it to larger numbers. So if you set it to 4 for
148 "               example the MBE window wouldn't auto-open until 4 eligibles
149 "               buffers had been loaded. This is nice for folks that don't 
150 "               want an MBE window unless they are editing more than two or
151 "               three buffers.
153 "               To enable the optional mapping of Control + Vim Direction Keys 
154 "               [hjkl] to window movement commands, you can put the following into 
155 "               your .vimrc:
157 "                 let g:miniBufExplMapWindowNavVim = 1
159 "               To enable the optional mapping of Control + Arrow Keys to window 
160 "               movement commands, you can put the following into your .vimrc:
162 "                 let g:miniBufExplMapWindowNavArrows = 1
164 "               To enable the optional mapping of <C-TAB> and <C-S-TAB> to a 
165 "               function that will bring up the next or previous buffer in the
166 "               current window, you can put the following into your .vimrc:
168 "                 let g:miniBufExplMapCTabSwitchBufs = 1
170 "               To enable the optional mapping of <C-TAB> and <C-S-TAB> to mappings
171 "               that will move to the next and previous (respectively) window, you
172 "               can put the following into your .vimrc:
174 "                 let g:miniBufExplMapCTabSwitchWindows = 1
177 "               NOTE: If you set the ...TabSwitchBufs AND ...TabSwitchWindows, 
178 "                     ...TabSwitchBufs will be enabled and ...TabSwitchWindows 
179 "                     will not.
180 "               
181 "               As of MBE 6.3.0, you can put the following into your .vimrc:
182 "               
183 "                 let g:miniBufExplUseSingleClick = 1
185 "               If you would like to single click on tabs rather than double
186 "               clicking on them to goto the selected buffer. 
188 "               NOTE: If you use the single click option in taglist.vim you may 
189 "                     need to get an updated version that includes a patch I 
190 "                     provided to allow both explorers to provide single click 
191 "                     buffer selection.
193 "               It is possible to customize the the highlighting for the tabs in 
194 "               the MBE by configuring the following highlighting groups:
196 "                 MBENormal         - for buffers that have NOT CHANGED and
197 "                                     are NOT VISIBLE.
198 "                 MBEChanged        - for buffers that HAVE CHANGED and are
199 "                                     NOT VISIBLE
200 "                 MBEVisibleNormal  - buffers that have NOT CHANGED and are
201 "                                     VISIBLE
202 "                 MBEVisibleChanged - buffers that have CHANGED and are VISIBLE
204 "               You can either link to an existing highlighting group by
205 "               adding a command like:
207 "                 hi link MBEVisibleChanged Error
209 "               to your .vimrc or you can specify exact foreground and background
210 "               colors using the following syntax:
212 "                 hi MBEChanged guibg=darkblue ctermbg=darkblue termbg=white
214 "               NOTE: If you set a colorscheme in your .vimrc you should do it
215 "                     BEFORE updating the MBE highlighting groups.
217 "               If you use other explorers like TagList you can (As of 6.2.8) put:
219 "                 let g:miniBufExplModSelTarget = 1
221 "               into your .vimrc in order to force MBE to try to place selected 
222 "               buffers into a window that does not have a nonmodifiable buffer.
223 "               The upshot of this should be that if you go into MBE and select
224 "               a buffer, the buffer should not show up in a window that is 
225 "               hosting an explorer.
227 "               There is a VIM bug that can cause buffers to show up without 
228 "               their highlighting. The following setting will cause MBE to
229 "               try and turn highlighting back on (introduced in 6.3.1):
231 "                 let g:miniBufExplForceSyntaxEnable = 1
233 "               MBE has had a basic debugging capability for quite some time.
234 "               However, it has not been very friendly in the past. As of 6.0.8, 
235 "               you can put one of each of the following into your .vimrc:
237 "                 let g:miniBufExplorerDebugLevel = 0  " MBE serious errors output
238 "                 let g:miniBufExplorerDebugLevel = 4  " MBE all errors output
239 "                 let g:miniBufExplorerDebugLevel = 10 " MBE reports everything
241 "               You can also set a DebugMode to cause output to be target as
242 "               follows (default is mode 3):
244 "                 let g:miniBufExplorerDebugMode  = 0  " Errors will show up in 
245 "                                                      " a vim window
246 "                 let g:miniBufExplorerDebugMode  = 1  " Uses VIM's echo function
247 "                                                      " to display on the screen
248 "                 let g:miniBufExplorerDebugMode  = 2  " Writes to a file
249 "                                                      " MiniBufExplorer.DBG
250 "                 let g:miniBufExplorerDebugMode  = 3  " Store output in global:
251 "                                                 " g:miniBufExplorerDebugOutput
253 "               Or if you are able to start VIM, you might just perform these
254 "               at a command prompt right before you do the operation that is
255 "               failing.
257 "      History: Moved to end of file
258 "      
259 " Known Issues: When debugging is turned on and set to output to a window, there
260 "               are some cases where the window is opened more than once, there
261 "               are other cases where an old debug window can be lost.
263 "               Several MBE commands can break the window history so <C-W>[pnw]
264 "               might not take you to the expected window.
266 "         Todo: Add the ability to specify a regexp for eligible buffers
267 "               allowing the ability to filter out certain buffers that 
268 "               you don't want to control from MBE
270 "=============================================================================
271 " }}}
273 " Startup Check
275 " Has this plugin already been loaded? {{{
277 if exists('loaded_minibufexplorer')
278   finish
279 endif
280 let loaded_minibufexplorer = 1
281 " }}}
283 " Mappings and Commands
285 " MBE Keyboard Mappings {{{
286 " If we don't already have keyboard mappings for MBE then create them 
288 if !hasmapto('<Plug>MiniBufExplorer')
289   map <unique> <Leader>mbe <Plug>MiniBufExplorer
290 endif
291 if !hasmapto('<Plug>CMiniBufExplorer')
292   map <unique> <Leader>mbc <Plug>CMiniBufExplorer
293 endif
294 if !hasmapto('<Plug>UMiniBufExplorer')
295   map <unique> <Leader>mbu <Plug>UMiniBufExplorer
296 endif
297 if !hasmapto('<Plug>TMiniBufExplorer')
298   map <unique> <Leader>mbt <Plug>TMiniBufExplorer
299 endif
301 " }}}
302 " MBE <Script> internal map {{{
304 noremap <unique> <script> <Plug>MiniBufExplorer  :call <SID>StartExplorer(1, -1)<CR>:<BS>
305 noremap <unique> <script> <Plug>CMiniBufExplorer :call <SID>StopExplorer(1)<CR>:<BS>
306 noremap <unique> <script> <Plug>UMiniBufExplorer :call <SID>AutoUpdate(-1)<CR>:<BS>
307 noremap <unique> <script> <Plug>TMiniBufExplorer :call <SID>ToggleExplorer()<CR>:<BS>
309 " }}}
310 " MBE commands {{{
312 if !exists(':MiniBufExplorer')
313   command! MiniBufExplorer  call <SID>StartExplorer(1, -1)
314 endif
315 if !exists(':CMiniBufExplorer')
316   command! CMiniBufExplorer  call <SID>StopExplorer(1)
317 endif
318 if !exists(':UMiniBufExplorer')
319   command! UMiniBufExplorer  call <SID>AutoUpdate(-1)
320 endif
321 if !exists(':TMiniBufExplorer')
322   command! TMiniBufExplorer  call <SID>ToggleExplorer()
323 endif
324 if !exists(':MBEbn')
325   command! MBEbn call <SID>CycleBuffer(1)
326 endif
327 if !exists(':MBEbp')
328   command! MBEbp call <SID>CycleBuffer(0)
329 endif " }}}
331 " Global Configuration Variables
333 " Debug Level {{{
335 " 0 = no logging
336 " 1=5 = errors ; 1 is the most important
337 " 5-9 = info ; 5 is the most important
338 " 10 = Entry/Exit
339 if !exists('g:miniBufExplorerDebugLevel')
340   let g:miniBufExplorerDebugLevel = 0 
341 endif
343 " }}}
344 " Debug Mode {{{
346 " 0 = debug to a window
347 " 1 = use vim's echo facility
348 " 2 = write to a file named MiniBufExplorer.DBG
349 "     in the directory where vim was started
350 "     THIS IS VERY SLOW
351 " 3 = Write into g:miniBufExplorerDebugOutput
352 "     global variable [This is the default]
353 if !exists('g:miniBufExplorerDebugMode')
354   let g:miniBufExplorerDebugMode = 3 
355 endif 
357 " }}}
358 " Allow auto update? {{{
360 " We start out with this off for startup, but once vim is running we 
361 " turn this on.
362 if !exists('g:miniBufExplorerAutoUpdate')
363   let g:miniBufExplorerAutoUpdate = 0
364 endif
366 " }}}
367 " MoreThanOne? {{{
368 " Display Mini Buf Explorer when there are 'More Than One' eligible buffers 
370 if !exists('g:miniBufExplorerMoreThanOne')
371   let g:miniBufExplorerMoreThanOne = 2
372 endif 
374 " }}}
375 " Split below/above/left/right? {{{
376 " When opening a new -MiniBufExplorer- window, split the new windows below or 
377 " above the current window?  1 = below, 0 = above.
379 if !exists('g:miniBufExplSplitBelow')
380   let g:miniBufExplSplitBelow = &splitbelow
381 endif 
383 " }}}
384 " Split to edge? {{{
385 " When opening a new -MiniBufExplorer- window, split the new windows to the
386 " full edge? 1 = yes, 0 = no.
388 if !exists('g:miniBufExplSplitToEdge')
389   let g:miniBufExplSplitToEdge = 1
390 endif 
392 " }}}
393 " MaxHeight (depreciated) {{{
394 " When sizing the -MiniBufExplorer- window, assign a maximum window height.
395 " 0 = size to fit all buffers, otherwise the value is number of lines for
396 " buffer. [Depreciated use g:miniBufExplMaxSize]
398 if !exists('g:miniBufExplMaxHeight')
399   let g:miniBufExplMaxHeight = 0
400 endif 
402 " }}}
403 " MaxSize {{{
404 " Same as MaxHeight but also works for vertical splits if specified with a
405 " vertical split then vertical resizing will be performed. If left at 0 
406 " then the number of columns in g:miniBufExplVSplit will be used as a
407 " static window width.
408 if !exists('g:miniBufExplMaxSize')
409   let g:miniBufExplMaxSize = g:miniBufExplMaxHeight
410 endif
412 " }}}
413 " MinHeight (depreciated) {{{
414 " When sizing the -MiniBufExplorer- window, assign a minumum window height.
415 " the value is minimum number of lines for buffer. Setting this to zero can
416 " cause strange height behavior. The default value is 1 [Depreciated use
417 " g:miniBufExplMinSize]
419 if !exists('g:miniBufExplMinHeight')
420   let g:miniBufExplMinHeight = 1
421 endif
423 " }}}
424 " MinSize {{{
425 " Same as MinHeight but also works for vertical splits. For vertical splits, 
426 " this is ignored unless g:miniBufExplMax(Size|Height) are specified.
427 if !exists('g:miniBufExplMinSize')
428   let g:miniBufExplMinSize = g:miniBufExplMinHeight
429 endif
431 " }}}
432 " Horizontal or Vertical explorer? {{{
433 " For folks that like vertical explorers, I'm caving in and providing for
434 " veritcal splits. If this is set to 0 then the current horizontal 
435 " splitting logic will be run. If however you want a vertical split,
436 " assign the width (in characters) you wish to assign to the MBE window.
438 if !exists('g:miniBufExplVSplit')
439   let g:miniBufExplVSplit = 0
440 endif
442 " }}}
443 " TabWrap? {{{
444 " By default line wrap is used (possibly breaking a tab name between two
445 " lines.) Turning this option on (setting it to 1) can take more screen
446 " space, but will make sure that each tab is on one and only one line.
448 if !exists('g:miniBufExplTabWrap')
449   let g:miniBufExplTabWrap = 0
450 endif
452 " }}}
453 " Extended window navigation commands? {{{
454 " Global flag to turn extended window navigation commands on or off
455 " enabled = 1, dissabled = 0
457 if !exists('g:miniBufExplMapWindowNav')
458   " This is for backwards compatibility and may be removed in a
459   " later release, please use the ...NavVim and/or ...NavArrows 
460   " settings.
461   let g:miniBufExplMapWindowNav = 0
462 endif
463 if !exists('g:miniBufExplMapWindowNavVim')
464   let g:miniBufExplMapWindowNavVim = 0
465 endif
466 if !exists('g:miniBufExplMapWindowNavArrows')
467   let g:miniBufExplMapWindowNavArrows = 0
468 endif
469 if !exists('g:miniBufExplMapCTabSwitchBufs')
470   let g:miniBufExplMapCTabSwitchBufs = 0
471 endif
472 " Notice: that if CTabSwitchBufs is turned on then
473 " we turn off CTabSwitchWindows.
474 if g:miniBufExplMapCTabSwitchBufs == 1 || !exists('g:miniBufExplMapCTabSwitchWindows')
475   let g:miniBufExplMapCTabSwitchWindows = 0
476 endif 
479 " If we have enabled control + vim direction key remapping
480 " then perform the remapping
482 " Notice: I left g:miniBufExplMapWindowNav in for backward
483 " compatibility. Eventually this mapping will be removed so
484 " please use the newer g:miniBufExplMapWindowNavVim setting.
485 if g:miniBufExplMapWindowNavVim || g:miniBufExplMapWindowNav
486   noremap <C-J> <C-W>j
487   noremap <C-K> <C-W>k
488   noremap <C-H> <C-W>h
489   noremap <C-L> <C-W>l
490 endif
493 " If we have enabled control + arrow key remapping
494 " then perform the remapping
496 if g:miniBufExplMapWindowNavArrows
497   noremap <C-Down>  <C-W>j
498   noremap <C-Up>    <C-W>k
499   noremap <C-Left>  <C-W>h
500   noremap <C-Right> <C-W>l
501 endif
503 " If we have enabled <C-TAB> and <C-S-TAB> to switch buffers
504 " in the current window then perform the remapping
506 if g:miniBufExplMapCTabSwitchBufs
507   noremap <C-TAB>   :call <SID>CycleBuffer(1)<CR>:<BS>
508   noremap <C-S-TAB> :call <SID>CycleBuffer(0)<CR>:<BS>
509 endif
512 " If we have enabled <C-TAB> and <C-S-TAB> to switch windows
513 " then perform the remapping
515 if g:miniBufExplMapCTabSwitchWindows
516   noremap <C-TAB>   <C-W>w
517   noremap <C-S-TAB> <C-W>W
518 endif
520 " }}}
521 " Modifiable Select Target {{{
523 if !exists('g:miniBufExplModSelTarget')
524   let g:miniBufExplModSelTarget = 0
525 endif
527 "}}}
528 " Force Syntax Enable {{{
530 if !exists('g:miniBufExplForceSyntaxEnable')
531   let g:miniBufExplForceSyntaxEnable = 0
532 endif
534 " }}}
535 " Single/Double Click? {{{
536 " flag that can be set to 1 in a users .vimrc to allow 
537 " single click switching of tabs. By default we use
538 " double click for tab selection.
540 if !exists('g:miniBufExplUseSingleClick')
541   let g:miniBufExplUseSingleClick = 0
542 endif 
545 " attempt to perform single click mapping, it would be much
546 " nicer if we could nnoremap <buffer> ... however vim does
547 " not fire the <buffer> <leftmouse> when you use the mouse
548 " to enter a buffer.
550 if g:miniBufExplUseSingleClick == 1
551   let s:clickmap = ':if bufname("%") == "-MiniBufExplorer-" <bar> call <SID>MBEClick() <bar> endif <CR>'
552   if maparg('<LEFTMOUSE>', 'n') == '' 
553     " no mapping for leftmouse
554     exec ':nnoremap <silent> <LEFTMOUSE> <LEFTMOUSE>' . s:clickmap
555   else
556     " we have a mapping
557     let  g:miniBufExplDoneClickSave = 1
558     let  s:m = ':nnoremap <silent> <LEFTMOUSE> <LEFTMOUSE>'
559     let  s:m = s:m . substitute(substitute(maparg('<LEFTMOUSE>', 'n'), '|', '<bar>', 'g'), '\c^<LEFTMOUSE>', '', '')
560     let  s:m = s:m . s:clickmap
561     exec s:m
562   endif
563 endif " }}}
565 " Variables used internally
567 " Script/Global variables {{{
568 " Global used to store the buffer list so we don't update the
569 " UI unless the list has changed.
570 if !exists('g:miniBufExplBufList')
571   let g:miniBufExplBufList = ''
572 endif
574 " Variable used as a mutex so that we don't do lots
575 " of AutoUpdates at the same time.
576 if !exists('g:miniBufExplInAutoUpdate')
577   let g:miniBufExplInAutoUpdate = 0
578 endif
580 " In debug mode 3 this variable will hold the debug output
581 if !exists('g:miniBufExplorerDebugOutput')
582   let g:miniBufExplorerDebugOutput = ''
583 endif
585 " In debug mode 3 this variable will hold the debug output
586 if !exists('g:miniBufExplForceDisplay')
587   let g:miniBufExplForceDisplay = 0
588 endif
590 " Variable used to pass maxTabWidth info between functions
591 let s:maxTabWidth = 0 
593 " Variable used to count debug output lines
594 let s:debugIndex = 0 
596   
597 " }}}
598 " Setup an autocommand group and some autocommands {{{
599 " that keep our explorer updated automatically.
601 augroup MiniBufExplorer
602 autocmd MiniBufExplorer BufDelete   * call <SID>DEBUG('-=> BufDelete AutoCmd', 10) |call <SID>AutoUpdate(expand('<abuf>'))
603 autocmd MiniBufExplorer BufEnter    * call <SID>DEBUG('-=> BufEnter  AutoCmd', 10) |call <SID>AutoUpdate(-1)
604 autocmd MiniBufExplorer VimEnter    * call <SID>DEBUG('-=> VimEnter  AutoCmd', 10) |let g:miniBufExplorerAutoUpdate = 1 |call <SID>AutoUpdate(-1)
605 augroup NONE
606 " }}}
608 " Functions
610 " StartExplorer - Sets up our explorer and causes it to be displayed {{{
612 function! <SID>StartExplorer(sticky, delBufNum)
613   call <SID>DEBUG('===========================',10)
614   call <SID>DEBUG('Entering StartExplorer()'   ,10)
615   call <SID>DEBUG('===========================',10)
617   if a:sticky == 1
618     let g:miniBufExplorerAutoUpdate = 1
619   endif
621   " Store the current buffer
622   let l:curBuf = bufnr('%')
624   " Prevent a report of our actions from showing up.
625   let l:save_rep = &report
626   let l:save_sc  = &showcmd
627   let &report    = 10000
628   set noshowcmd 
630   call <SID>FindCreateWindow('-MiniBufExplorer-', -1, 1, 1)
632   " Make sure we are in our window
633   if bufname('%') != '-MiniBufExplorer-'
634     call <SID>DEBUG('StartExplorer called in invalid window',1)
635     let &report  = l:save_rep
636     let &showcmd = l:save_sc
637     return
638   endif
640   " !!! We may want to make the following optional -- Bindu
641   " New windows don't cause all windows to be resized to equal sizes
642   set noequalalways
643   " !!! We may want to make the following optional -- Bindu
644   " We don't want the mouse to change focus without a click
645   set nomousefocus
647   " If folks turn numbering and columns on by default we will turn 
648   " them off for the MBE window
649   setlocal foldcolumn=0
650   setlocal nonumber
652   if has("syntax")
653     syn clear
654     syn match MBENormal             '\[[^\]]*\]'
655     syn match MBEChanged            '\[[^\]]*\]+'
656     syn match MBEVisibleNormal      '\[[^\]]*\]\*+\='
657     syn match MBEVisibleChanged     '\[[^\]]*\]\*+'
658     
659     if !exists("g:did_minibufexplorer_syntax_inits")
660       let g:did_minibufexplorer_syntax_inits = 1
661       hi def link MBENormal         Comment
662       hi def link MBEChanged        String
663       hi def link MBEVisibleNormal  Special
664       hi def link MBEVisibleChanged Special
665     endif
666   endif
668   " If you press return, o or e in the -MiniBufExplorer- then try
669   " to open the selected buffer in the previous window.
670   nnoremap <buffer> <CR> :call <SID>MBESelectBuffer(0)<CR>:<BS>
671   nnoremap <buffer> o :call <SID>MBESelectBuffer(0)<CR>:<BS>
672   nnoremap <buffer> e :call <SID>MBESelectBuffer(0)<CR>:<BS>
673   " If you press s in the -MiniBufExplorer- then try
674   " to open the selected buffer in a split in the previous window.
675   nnoremap <buffer> s :call <SID>MBESelectBuffer(1)<CR>:<BS>
676   " If you press j in the -MiniBufExplorer- then try
677   " to open the selected buffer in a vertical split in the previous window.
678   nnoremap <buffer> v :call <SID>MBESelectBuffer(2)<CR>:<BS>
679   " If you DoubleClick in the -MiniBufExplorer- then try
680   " to open the selected buffer in the previous window.
681   nnoremap <buffer> <2-LEFTMOUSE> :call <SID>MBEDoubleClick()<CR>:<BS>
682   " If you press d in the -MiniBufExplorer- then try to
683   " delete the selected buffer.
684   nnoremap <buffer> d :call <SID>MBEDeleteBuffer()<CR>:<BS>
685   " If you press w in the -MiniBufExplorer- then switch back
686   " to the previous window.
687   nnoremap <buffer> p :wincmd p<CR>:<BS>
688   " The following allow us to use regular movement keys to 
689   " scroll in a wrapped single line buffer
690   nnoremap <buffer> j gj
691   nnoremap <buffer> k gk
692   nnoremap <buffer> <down> gj
693   nnoremap <buffer> <up> gk
694   " The following allows for quicker moving between buffer
695   " names in the [MBE] window it also saves the last-pattern
696   " and restores it.
697   nnoremap <buffer> <TAB>   :call search('\[[0-9]*:[^\]]*\]')<CR>:<BS>
698   nnoremap <buffer> <S-TAB> :call search('\[[0-9]*:[^\]]*\]','b')<CR>:<BS>
699   nnoremap <buffer> l   :call search('\[[0-9]*:[^\]]*\]')<CR>:<BS>
700   nnoremap <buffer> h :call search('\[[0-9]*:[^\]]*\]','b')<CR>:<BS>
702   call <SID>DisplayBuffers(a:delBufNum)
704   if (l:curBuf != -1)
705     call search('\['.l:curBuf.':'.expand('#'.l:curBuf.':t').'\]')
706   else
707     call <SID>DEBUG('No current buffer to search for',9)
708   endif
710   let &report  = l:save_rep
711   let &showcmd = l:save_sc
713   call <SID>DEBUG('===========================',10)
714   call <SID>DEBUG('Completed StartExplorer()'  ,10)
715   call <SID>DEBUG('===========================',10)
717 endfunction 
719 " }}}
720 " StopExplorer - Looks for our explorer and closes the window if it is open {{{
722 function! <SID>StopExplorer(sticky)
723   call <SID>DEBUG('===========================',10)
724   call <SID>DEBUG('Entering StopExplorer()'    ,10)
725   call <SID>DEBUG('===========================',10)
727   if a:sticky == 1
728     let g:miniBufExplorerAutoUpdate = 0
729   endif
731   let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
733   if l:winNum != -1 
734     exec l:winNum.' wincmd w'
735     silent! close
736     wincmd p
737   endif
739   call <SID>DEBUG('===========================',10)
740   call <SID>DEBUG('Completed StopExplorer()'   ,10)
741   call <SID>DEBUG('===========================',10)
743 endfunction
745 " }}}
746 " ToggleExplorer - Looks for our explorer and opens/closes the window {{{
748 function! <SID>ToggleExplorer()
749   call <SID>DEBUG('===========================',10)
750   call <SID>DEBUG('Entering ToggleExplorer()'  ,10)
751   call <SID>DEBUG('===========================',10)
753   let g:miniBufExplorerAutoUpdate = 0
755   let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
757   if l:winNum != -1 
758     call <SID>StopExplorer(1)
759   else
760     call <SID>StartExplorer(1, -1)
761     wincmd p
762   endif
764   call <SID>DEBUG('===========================',10)
765   call <SID>DEBUG('Completed ToggleExplorer()' ,10)
766   call <SID>DEBUG('===========================',10)
768 endfunction
770 " }}}
771 " FindWindow - Return the window number of a named buffer {{{
772 " If none is found then returns -1. 
774 function! <SID>FindWindow(bufName, doDebug)
775   if a:doDebug
776     call <SID>DEBUG('Entering FindWindow()',10)
777   endif
779   " Try to find an existing window that contains 
780   " our buffer.
781   let l:bufNum = bufnr(a:bufName)
782   if l:bufNum != -1
783     if a:doDebug
784       call <SID>DEBUG('Found buffer ('.a:bufName.'): '.l:bufNum,9)
785     endif
786     let l:winNum = bufwinnr(l:bufNum)
787   else
788     let l:winNum = -1
789   endif
791   return l:winNum
793 endfunction
795 " }}}
796 " FindCreateWindow - Attempts to find a window for a named buffer. {{{
798 " If it is found then moves there. Otherwise creates a new window and 
799 " configures it and moves there.
801 " forceEdge, -1 use defaults, 0 below, 1 above
802 " isExplorer, 0 no, 1 yes 
803 " doDebug, 0 no, 1 yes
805 function! <SID>FindCreateWindow(bufName, forceEdge, isExplorer, doDebug)
806   if a:doDebug
807     call <SID>DEBUG('Entering FindCreateWindow('.a:bufName.')',10)
808   endif
810   " Save the user's split setting.
811   let l:saveSplitBelow = &splitbelow
813   " Set to our new values.
814   let &splitbelow = g:miniBufExplSplitBelow
816   " Try to find an existing explorer window
817   let l:winNum = <SID>FindWindow(a:bufName, a:doDebug)
819   " If found goto the existing window, otherwise 
820   " split open a new window.
821   if l:winNum != -1
822     if a:doDebug
823       call <SID>DEBUG('Found window ('.a:bufName.'): '.l:winNum,9)
824     endif
825     exec l:winNum.' wincmd w'
826     let l:winFound = 1
827   else
829     if g:miniBufExplSplitToEdge == 1 || a:forceEdge >= 0
831         let l:edge = &splitbelow
832         if a:forceEdge >= 0
833             let l:edge = a:forceEdge
834         endif
836         if l:edge
837             if g:miniBufExplVSplit == 0
838               exec 'bo sp '.a:bufName
839             else
840               exec 'bo vsp '.a:bufName
841             endif
842         else
843             if g:miniBufExplVSplit == 0
844               exec 'to sp '.a:bufName
845             else
846               exec 'to vsp '.a:bufName
847             endif
848         endif
849     else
850         if g:miniBufExplVSplit == 0
851           exec 'sp '.a:bufName
852         else
853           " &splitbelow doesn't affect vertical splits
854           " so we have to do this explicitly.. ugh.
855           if &splitbelow
856             exec 'rightb vsp '.a:bufName
857           else
858             exec 'vsp '.a:bufName
859           endif
860         endif
861     endif
863     let g:miniBufExplForceDisplay = 1
865     " Try to find an existing explorer window
866     let l:winNum = <SID>FindWindow(a:bufName, a:doDebug)
867     if l:winNum != -1
868       if a:doDebug
869         call <SID>DEBUG('Created and then found window ('.a:bufName.'): '.l:winNum,9)
870       endif
871       exec l:winNum.' wincmd w'
872     else
873       if a:doDebug
874         call <SID>DEBUG('FindCreateWindow failed to create window ('.a:bufName.').',1)
875       endif
876       return
877     endif
879     if a:isExplorer
880       " Turn off the swapfile, set the buffer type so that it won't get written,
881       " and so that it will get deleted when it gets hidden and turn on word wrap.
882       setlocal noswapfile
883       setlocal buftype=nofile
884       setlocal bufhidden=delete
885       if g:miniBufExplVSplit == 0
886         setlocal wrap
887       else
888         setlocal nowrap
889         exec('setlocal winwidth='.g:miniBufExplMinSize)
890       endif
891     endif
893     if a:doDebug
894       call <SID>DEBUG('Window ('.a:bufName.') created: '.winnr(),9)
895     endif
897   endif
899   " Restore the user's split setting.
900   let &splitbelow = l:saveSplitBelow
902 endfunction
904 " }}}
905 " DisplayBuffers - Wrapper for getting MBE window shown {{{
907 " Makes sure we are in our explorer, then erases the current buffer and turns 
908 " it into a mini buffer explorer window.
910 function! <SID>DisplayBuffers(delBufNum)
911   call <SID>DEBUG('Entering DisplayBuffers()',10)
912   
913   " Make sure we are in our window
914   if bufname('%') != '-MiniBufExplorer-'
915     call <SID>DEBUG('DisplayBuffers called in invalid window',1)
916     return
917   endif
919   " We need to be able to modify the buffer
920   setlocal modifiable
922   call <SID>ShowBuffers(a:delBufNum)
923   call <SID>ResizeWindow()
924   
925   normal! zz
926   
927   " Prevent the buffer from being modified.
928   setlocal nomodifiable
929   set nobuflisted
931 endfunction
933 " }}}
934 " Resize Window - Set width/height of MBE window {{{
936 " Makes sure we are in our explorer, then sets the height/width for our explorer 
937 " window so that we can fit all of our information without taking extra lines.
939 function! <SID>ResizeWindow()
940   call <SID>DEBUG('Entering ResizeWindow()',10)
942   " Make sure we are in our window
943   if bufname('%') != '-MiniBufExplorer-'
944     call <SID>DEBUG('ResizeWindow called in invalid window',1)
945     return
946   endif
948   let l:width  = winwidth('.')
950   " Horizontal Resize
951   if g:miniBufExplVSplit == 0
953     if g:miniBufExplTabWrap == 0
954       let l:length = strlen(getline('.'))
955       let l:height = 0
956       if (l:width == 0)
957         let l:height = winheight('.')
958       else
959         let l:height = (l:length / l:width) 
960         " handle truncation from div
961         if (l:length % l:width) != 0
962           let l:height = l:height + 1
963         endif
964       endif
965     else
966       exec("setlocal textwidth=".l:width)
967       normal gg
968       normal gq}
969       normal G
970       let l:height = line('.')
971       normal gg
972     endif
973   
974     " enforce max window height
975     if g:miniBufExplMaxSize != 0
976       if g:miniBufExplMaxSize < l:height
977         let l:height = g:miniBufExplMaxSize
978       endif
979     endif
980   
981     " enfore min window height
982     if l:height < g:miniBufExplMinSize || l:height == 0
983       let l:height = g:miniBufExplMinSize
984     endif
985   
986     call <SID>DEBUG('ResizeWindow to '.l:height.' lines',9)
987   
988     exec('resize '.l:height)
989   
990   " Vertical Resize
991   else 
993     if g:miniBufExplMaxSize != 0
994       let l:newWidth = s:maxTabWidth
995       if l:newWidth > g:miniBufExplMaxSize 
996           let l:newWidth = g:miniBufExplMaxSize
997       endif
998       if l:newWidth < g:miniBufExplMinSize
999           let l:newWidth = g:miniBufExplMinSize
1000       endif
1001     else
1002       let l:newWidth = g:miniBufExplVSplit
1003     endif
1005     if l:width != l:newWidth
1006       call <SID>DEBUG('ResizeWindow to '.l:newWidth.' columns',9)
1007       exec('vertical resize '.l:newWidth)
1008     endif
1010   endif
1011   
1012 endfunction
1014 " }}}
1015 " ShowBuffers - Clear current buffer and put the MBE text into it {{{
1017 " Makes sure we are in our explorer, then adds a list of all modifiable 
1018 " buffers to the current buffer. Special marks are added for buffers that 
1019 " are in one or more windows (*) and buffers that have been modified (+)
1021 function! <SID>ShowBuffers(delBufNum)
1022   call <SID>DEBUG('Entering ShowBuffers()',10)
1024   let l:ListChanged = <SID>BuildBufferList(a:delBufNum, 1)
1026   if (l:ListChanged == 1 || g:miniBufExplForceDisplay)
1027     let l:save_rep = &report
1028     let l:save_sc = &showcmd
1029     let &report = 10000
1030     set noshowcmd 
1032     " Delete all lines in buffer.
1033     1,$d _
1034   
1035     " Goto the end of the buffer put the buffer list 
1036     " and then delete the extra trailing blank line
1037     $
1038     put! =g:miniBufExplBufList
1039     $ d _
1041     let g:miniBufExplForceDisplay = 0
1043     let &report  = l:save_rep
1044     let &showcmd = l:save_sc
1045   else
1046     call <SID>DEBUG('Buffer list not update since there was no change',9)
1047   endif
1048   
1049 endfunction
1051 " }}}
1052 " Max - Returns the max of two numbers {{{
1054 function! <SID>Max(argOne, argTwo)
1055   if a:argOne > a:argTwo
1056     return a:argOne
1057   else
1058     return a:argTwo
1059   endif
1060 endfunction
1062 " }}}
1063 " BuildBufferList - Build the text for the MBE window {{{
1065 " Creates the buffer list string and returns 1 if it is different than
1066 " last time this was called and 0 otherwise.
1068 function! <SID>BuildBufferList(delBufNum, updateBufList)
1069   call <SID>DEBUG('Entering BuildBufferList()',10)
1071   let l:NBuffers = bufnr('$')     " Get the number of the last buffer.
1072   let l:i = 0                     " Set the buffer index to zero.
1074   let l:fileNames = ''
1075   let l:maxTabWidth = 0
1077   " Loop through every buffer less than the total number of buffers.
1078   while(l:i <= l:NBuffers)
1079     let l:i = l:i + 1
1080    
1081     " If we have a delBufNum and it is the current
1082     " buffer then ignore the current buffer. 
1083     " Otherwise, continue.
1084     if (a:delBufNum == -1 || l:i != a:delBufNum)
1085       " Make sure the buffer in question is listed.
1086       if(getbufvar(l:i, '&buflisted') == 1)
1087         " Get the name of the buffer.
1088         let l:BufName = bufname(l:i)
1089         " Check to see if the buffer is a blank or not. If the buffer does have
1090         " a name, process it.
1091         if(strlen(l:BufName))
1092           " Only show modifiable buffers (The idea is that we don't 
1093           " want to show Explorers)
1094           if (getbufvar(l:i, '&modifiable') == 1 && BufName != '-MiniBufExplorer-')
1095             
1096             " Get filename & Remove []'s & ()'s
1097             let l:shortBufName = fnamemodify(l:BufName, ":t")                  
1098             let l:shortBufName = substitute(l:shortBufName, '[][()]', '', 'g') 
1099             let l:tab = '['.l:i.':'.l:shortBufName.']'
1101             " If the buffer is open in a window mark it
1102             if bufwinnr(l:i) != -1
1103               let l:tab = l:tab . '*'
1104             endif
1106             " If the buffer is modified then mark it
1107             if(getbufvar(l:i, '&modified') == 1)
1108               let l:tab = l:tab . '+'
1109             endif
1111             let l:maxTabWidth = <SID>Max(strlen(l:tab), l:maxTabWidth)
1112             let l:fileNames = l:fileNames.l:tab
1114             " If horizontal and tab wrap is turned on we need to add spaces
1115             if g:miniBufExplVSplit == 0
1116               if g:miniBufExplTabWrap != 0
1117                 let l:fileNames = l:fileNames.' '
1118               endif
1119             " If not horizontal we need a newline
1120             else
1121               let l:fileNames = l:fileNames . "\n"
1122             endif
1123           endif
1124         endif
1125       endif
1126     endif
1127   endwhile
1129   if (g:miniBufExplBufList != l:fileNames)
1130     if (a:updateBufList)
1131       let g:miniBufExplBufList = l:fileNames
1132       let s:maxTabWidth = l:maxTabWidth
1133     endif
1134     return 1
1135   else
1136     return 0
1137   endif
1139 endfunction
1141 " }}}
1142 " HasEligibleBuffers - Are there enough MBE eligible buffers to open the MBE window? {{{
1144 " Returns 1 if there are any buffers that can be displayed in a 
1145 " mini buffer explorer. Otherwise returns 0. If delBufNum is
1146 " any non -1 value then don't include that buffer in the list
1147 " of eligible buffers.
1149 function! <SID>HasEligibleBuffers(delBufNum)
1150   call <SID>DEBUG('Entering HasEligibleBuffers()',10)
1152   let l:save_rep = &report
1153   let l:save_sc = &showcmd
1154   let &report = 10000
1155   set noshowcmd 
1156   
1157   let l:NBuffers = bufnr('$')     " Get the number of the last buffer.
1158   let l:i        = 0              " Set the buffer index to zero.
1159   let l:found    = 0              " No buffer found
1161   if (g:miniBufExplorerMoreThanOne > 1)
1162     call <SID>DEBUG('More Than One mode turned on',6)
1163   endif
1164   let l:needed = g:miniBufExplorerMoreThanOne
1166   " Loop through every buffer less than the total number of buffers.
1167   while(l:i <= l:NBuffers && l:found < l:needed)
1168     let l:i = l:i + 1
1169    
1170     " If we have a delBufNum and it is the current
1171     " buffer then ignore the current buffer. 
1172     " Otherwise, continue.
1173     if (a:delBufNum == -1 || l:i != a:delBufNum)
1174       " Make sure the buffer in question is listed.
1175       if (getbufvar(l:i, '&buflisted') == 1)
1176         " Get the name of the buffer.
1177         let l:BufName = bufname(l:i)
1178         " Check to see if the buffer is a blank or not. If the buffer does have
1179         " a name, process it.
1180         if (strlen(l:BufName))
1181           " Only show modifiable buffers (The idea is that we don't 
1182           " want to show Explorers)
1183           if ((getbufvar(l:i, '&modifiable') == 1) && (BufName != '-MiniBufExplorer-'))
1184             
1185               let l:found = l:found + 1
1186   
1187           endif
1188         endif
1189       endif
1190     endif
1191   endwhile
1193   let &report  = l:save_rep
1194   let &showcmd = l:save_sc
1196   call <SID>DEBUG('HasEligibleBuffers found '.l:found.' eligible buffers of '.l:needed.' needed',6)
1198   return (l:found >= l:needed)
1199   
1200 endfunction
1202 " }}}
1203 " Auto Update - Function called by auto commands for auto updating the MBE {{{
1205 " IF auto update is turned on        AND
1206 "    we are in a real buffer         AND
1207 "    we have enough eligible buffers THEN
1208 " Update our explorer and get back to the current window
1210 " If we get a buffer number for a buffer that 
1211 " is being deleted, we need to make sure and 
1212 " remove the buffer from the list of eligible 
1213 " buffers in case we are down to one eligible
1214 " buffer, in which case we will want to close
1215 " the MBE window.
1217 function! <SID>AutoUpdate(delBufNum)
1218   call <SID>DEBUG('===========================',10)
1219   call <SID>DEBUG('Entering AutoUpdate('.a:delBufNum.') : '.bufnr('%').' : '.bufname('%'),10)
1220   call <SID>DEBUG('===========================',10)
1222   if (g:miniBufExplInAutoUpdate == 1)
1223     call <SID>DEBUG('AutoUpdate recursion stopped',9)
1224     call <SID>DEBUG('===========================',10)
1225     call <SID>DEBUG('Terminated AutoUpdate()'    ,10)
1226     call <SID>DEBUG('===========================',10)
1227     return
1228   else
1229     let g:miniBufExplInAutoUpdate = 1
1230   endif
1232   " Don't bother autoupdating the MBE window
1233   if (bufname('%') == '-MiniBufExplorer-')
1234     " If this is the only buffer left then toggle the buffer
1235     if (winbufnr(2) == -1)
1236         call <SID>CycleBuffer(1)
1237         call <SID>DEBUG('AutoUpdate does not run for cycled windows', 9)
1238     else
1239       call <SID>DEBUG('AutoUpdate does not run for the MBE window', 9)
1240     endif
1242     call <SID>DEBUG('===========================',10)
1243     call <SID>DEBUG('Terminated AutoUpdate()'    ,10)
1244     call <SID>DEBUG('===========================',10)
1246     let g:miniBufExplInAutoUpdate = 0
1247     return
1249   endif
1251   if (a:delBufNum != -1)
1252     call <SID>DEBUG('AutoUpdate will make sure that buffer '.a:delBufNum.' is not included in the buffer list.', 5)
1253   endif
1254   
1255   " Only allow updates when the AutoUpdate flag is set
1256   " this allows us to stop updates on startup.
1257   if g:miniBufExplorerAutoUpdate == 1
1258     " Only show MiniBufExplorer if we have a real buffer
1259     if ((g:miniBufExplorerMoreThanOne == 0) || (bufnr('%') != -1 && bufname('%') != ""))
1260       if <SID>HasEligibleBuffers(a:delBufNum) == 1
1261         " if we don't have a window then create one
1262         let l:bufnr = <SID>FindWindow('-MiniBufExplorer-', 0)
1263         if (l:bufnr == -1)
1264           call <SID>DEBUG('About to call StartExplorer (Create MBE)', 9)
1265           call <SID>StartExplorer(0, a:delBufNum)
1266         else
1267         " otherwise only update the window if the contents have
1268         " changed
1269           let l:ListChanged = <SID>BuildBufferList(a:delBufNum, 0)
1270           if (l:ListChanged)
1271             call <SID>DEBUG('About to call StartExplorer (Update MBE)', 9) 
1272             call <SID>StartExplorer(0, a:delBufNum)
1273           endif
1274         endif
1276         " go back to the working buffer
1277         if (bufname('%') == '-MiniBufExplorer-')
1278           wincmd p
1279         endif
1280       else
1281         call <SID>DEBUG('Failed in eligible check', 9)
1282         call <SID>StopExplorer(0)
1283       endif
1285           " VIM sometimes turns syntax highlighting off,
1286           " we can force it on, but this may cause weird
1287           " behavior so this is an optional hack to force
1288           " syntax back on when we enter a buffer
1289           if g:miniBufExplForceSyntaxEnable
1290                 call <SID>DEBUG('Enable Syntax', 9)
1291                 exec 'syntax enable'
1292           endif
1294     else
1295       call <SID>DEBUG('No buffers loaded...',9)
1296     endif
1297   else
1298     call <SID>DEBUG('AutoUpdates are turned off, terminating',9)
1299   endif
1301   call <SID>DEBUG('===========================',10)
1302   call <SID>DEBUG('Completed AutoUpdate()'     ,10)
1303   call <SID>DEBUG('===========================',10)
1305   let g:miniBufExplInAutoUpdate = 0
1307 endfunction
1309 " }}}
1310 " GetSelectedBuffer - From the MBE window, return the bufnum for buf under cursor {{{
1312 " If we are in our explorer window then return the buffer number
1313 " for the buffer under the cursor.
1315 function! <SID>GetSelectedBuffer()
1316   call <SID>DEBUG('Entering GetSelectedBuffer()',10)
1318   " Make sure we are in our window
1319   if bufname('%') != '-MiniBufExplorer-'
1320     call <SID>DEBUG('GetSelectedBuffer called in invalid window',1)
1321     return -1
1322   endif
1324   let l:save_reg = @"
1325   let @" = ""
1326   normal ""yi[
1327   if @" != ""
1328     let l:retv = substitute(@",'\([0-9]*\):.*', '\1', '') + 0
1329     let @" = l:save_reg
1330     return l:retv
1331   else
1332     let @" = l:save_reg
1333     return -1
1334   endif
1336 endfunction
1338 " }}}
1339 " MBESelectBuffer - From the MBE window, open buffer under the cursor {{{
1341 " If we are in our explorer, then we attempt to open the buffer under the
1342 " cursor in the previous window.
1344 " Split indicates whether to open with split, 0 no split, 1 split horizontally
1346 function! <SID>MBESelectBuffer(split)
1347   call <SID>DEBUG('===========================',10)
1348   call <SID>DEBUG('Entering MBESelectBuffer()' ,10)
1349   call <SID>DEBUG('===========================',10)
1351   " Make sure we are in our window
1352   if bufname('%') != '-MiniBufExplorer-'
1353     call <SID>DEBUG('MBESelectBuffer called in invalid window',1)
1354     return 
1355   endif
1357   let l:save_rep = &report
1358   let l:save_sc  = &showcmd
1359   let &report    = 10000
1360   set noshowcmd 
1361   
1362   let l:bufnr  = <SID>GetSelectedBuffer()
1363   let l:resize = 0
1365   if(l:bufnr != -1)             " If the buffer exists.
1367     let l:saveAutoUpdate = g:miniBufExplorerAutoUpdate
1368     let g:miniBufExplorerAutoUpdate = 0
1369     " Switch to the previous window
1370     wincmd p
1372     " If we are in the buffer explorer or in a nonmodifiable buffer with
1373     " g:miniBufExplModSelTarget set then try another window (a few times)
1374     if bufname('%') == '-MiniBufExplorer-' || (g:miniBufExplModSelTarget == 1 && getbufvar(bufnr('%'), '&modifiable') == 0)
1375       wincmd w
1376       if bufname('%') == '-MiniBufExplorer-' || (g:miniBufExplModSelTarget == 1 && getbufvar(bufnr('%'), '&modifiable') == 0)
1377         wincmd w
1378         if bufname('%') == '-MiniBufExplorer-' || (g:miniBufExplModSelTarget == 1 && getbufvar(bufnr('%'), '&modifiable') == 0)
1379           wincmd w
1380           " The following handles the case where -MiniBufExplorer-
1381           " is the only window left. We need to resize so we don't
1382           " end up with a 1 or two line buffer.
1383           if bufname('%') == '-MiniBufExplorer-'
1384             let l:resize = 1
1385           endif
1386         endif
1387       endif
1388     endif
1390     if a:split == 0
1391         exec('b! '.l:bufnr)
1392     elseif a:split == 1
1393         exec('sb! '.l:bufnr)
1394     elseif a:split == 2
1395         exec('vertical sb! '.l:bufnr)
1396     endif
1398     if (l:resize)
1399       resize
1400     endif
1401     let g:miniBufExplorerAutoUpdate = l:saveAutoUpdate
1402     call <SID>AutoUpdate(-1)
1404   endif
1406   let &report  = l:save_rep
1407   let &showcmd = l:save_sc
1409   call <SID>DEBUG('===========================',10)
1410   call <SID>DEBUG('Completed MBESelectBuffer()',10)
1411   call <SID>DEBUG('===========================',10)
1413 endfunction
1415 " }}}
1416 " MBEDeleteBuffer - From the MBE window, delete selected buffer from list {{{
1418 " After making sure that we are in our explorer, This will delete the buffer 
1419 " under the cursor. If the buffer under the cursor is being displayed in a
1420 " window, this routine will attempt to get different buffers into the 
1421 " windows that will be affected so that windows don't get removed.
1423 function! <SID>MBEDeleteBuffer()
1424   call <SID>DEBUG('===========================',10)
1425   call <SID>DEBUG('Entering MBEDeleteBuffer()' ,10)
1426   call <SID>DEBUG('===========================',10)
1428   " Make sure we are in our window
1429   if bufname('%') != '-MiniBufExplorer-'
1430     call <SID>DEBUG('MBEDeleteBuffer called in invalid window',1)
1431     return 
1432   endif
1434   let l:curLine    = line('.')
1435   let l:curCol     = virtcol('.')
1436   let l:selBuf     = <SID>GetSelectedBuffer()
1437   let l:selBufName = bufname(l:selBuf)
1439   if l:selBufName == 'MiniBufExplorer.DBG' && g:miniBufExplorerDebugLevel > 0
1440     call <SID>DEBUG('MBEDeleteBuffer will not delete the debug window, when debugging is turned on.',1)
1441     return
1442   endif
1444   let l:save_rep = &report
1445   let l:save_sc  = &showcmd
1446   let &report    = 10000
1447   set noshowcmd 
1448   
1449   
1450   if l:selBuf != -1 
1452     " Don't want auto updates while we are processing a delete
1453     " request.
1454     let l:saveAutoUpdate = g:miniBufExplorerAutoUpdate
1455     let g:miniBufExplorerAutoUpdate = 0
1457     " Save previous window so that if we show a buffer after
1458     " deleting. The show will come up in the correct window.
1459     wincmd p
1460     let l:prevWin    = winnr()
1461     let l:prevWinBuf = winbufnr(winnr())
1463     call <SID>DEBUG('Previous window: '.l:prevWin.' buffer in window: '.l:prevWinBuf,5)
1464     call <SID>DEBUG('Selected buffer is <'.l:selBufName.'>['.l:selBuf.']',5)
1466     " If buffer is being displayed in a window then 
1467     " move window to a different buffer before 
1468     " deleting this one. 
1469     let l:winNum = (bufwinnr(l:selBufName) + 0)
1470     " while we have windows that contain our buffer
1471     while l:winNum != -1 
1472         call <SID>DEBUG('Buffer '.l:selBuf.' is being displayed in window: '.l:winNum,5)
1474         " move to window that contains our selected buffer
1475         exec l:winNum.' wincmd w'
1477         call <SID>DEBUG('We are now in window: '.winnr().' which contains buffer: '.bufnr('%').' and should contain buffer: '.l:selBuf,5)
1479         let l:origBuf = bufnr('%')
1480         call <SID>CycleBuffer(1)
1481         let l:curBuf  = bufnr('%')
1483         call <SID>DEBUG('Window now contains buffer: '.bufnr('%').' which should not be: '.l:selBuf,5)
1485         if l:origBuf == l:curBuf
1486             " we wrapped so we are going to have to delete a buffer 
1487             " that is in an open window.
1488             let l:winNum = -1
1489         else
1490             " see if we have anymore windows with our selected buffer
1491             let l:winNum = (bufwinnr(l:selBufName) + 0)
1492         endif
1493     endwhile
1495     " Attempt to restore previous window
1496     call <SID>DEBUG('Restoring previous window to: '.l:prevWin,5)
1497     exec l:prevWin.' wincmd w'
1499     " Try to get back to the -MiniBufExplorer- window 
1500     let l:winNum = bufwinnr(bufnr('-MiniBufExplorer-'))
1501     if l:winNum != -1
1502         exec l:winNum.' wincmd w'
1503         call <SID>DEBUG('Got to -MiniBufExplorer- window: '.winnr(),5)
1504     else
1505         call <SID>DEBUG('Unable to get to -MiniBufExplorer- window',1)
1506     endif
1507   
1508     " Delete the buffer selected.
1509     call <SID>DEBUG('About to delete buffer: '.l:selBuf,5)
1510     exec('silent! bd '.l:selBuf)
1512     let g:miniBufExplorerAutoUpdate = l:saveAutoUpdate 
1513     call <SID>DisplayBuffers(-1)
1514     call cursor(l:curLine, l:curCol)
1516   endif
1518   let &report  = l:save_rep
1519   let &showcmd = l:save_sc
1521   call <SID>DEBUG('===========================',10)
1522   call <SID>DEBUG('Completed MBEDeleteBuffer()',10)
1523   call <SID>DEBUG('===========================',10)
1525 endfunction
1527 " }}}
1528 " MBEClick - Handle mouse double click {{{
1530 function! s:MBEClick()
1531   call <SID>DEBUG('Entering MBEClick()',10)
1532   call <SID>MBESelectBuffer(0)
1533 endfunction
1536 " MBEDoubleClick - Double click with the mouse.
1538 function! s:MBEDoubleClick()
1539   call <SID>DEBUG('Entering MBEDoubleClick()',10)
1540   call <SID>MBESelectBuffer(0)
1541 endfunction
1543 " }}}
1544 " CycleBuffer - Cycle Through Buffers {{{
1546 " Move to next or previous buffer in the current window. If there 
1547 " are no more modifiable buffers then stay on the current buffer.
1548 " can be called with no parameters in which case the buffers are
1549 " cycled forward. Otherwise a single argument is accepted, if 
1550 " it's 0 then the buffers are cycled backwards, otherwise they
1551 " are cycled forward.
1553 function! <SID>CycleBuffer(forward)
1555   " The following hack handles the case where we only have one
1556   " window open and it is too small
1557   let l:saveAutoUpdate = g:miniBufExplorerAutoUpdate
1558   if (winbufnr(2) == -1)
1559     resize
1560     let g:miniBufExplorerAutoUpdate = 0
1561   endif
1562   
1563   " Change buffer (keeping track of before and after buffers)
1564   let l:origBuf = bufnr('%')
1565   if (a:forward == 1)
1566     bn!
1567   else
1568     bp!
1569   endif
1570   let l:curBuf  = bufnr('%')
1572   " Skip any non-modifiable buffers, but don't cycle forever
1573   " This should stop us from stopping in any of the [Explorers]
1574   while getbufvar(l:curBuf, '&modifiable') == 0 && l:origBuf != l:curBuf
1575     if (a:forward == 1)
1576         bn!
1577     else
1578         bp!
1579     endif
1580     let l:curBuf = bufnr('%')
1581   endwhile
1583   let g:miniBufExplorerAutoUpdate = l:saveAutoUpdate
1584   if (l:saveAutoUpdate == 1)
1585     call <SID>AutoUpdate(-1)
1586   endif
1588 endfunction
1590 " }}}
1591 " DEBUG - Display debug output when debugging is turned on {{{
1593 " Thanks to Charles E. Campbell, Jr. PhD <cec@NgrOyphSon.gPsfAc.nMasa.gov> 
1594 " for Decho.vim which was the inspiration for this enhanced debugging 
1595 " capability.
1597 function! <SID>DEBUG(msg, level)
1599   if g:miniBufExplorerDebugLevel >= a:level
1601     " Prevent a report of our actions from showing up.
1602     let l:save_rep    = &report
1603     let l:save_sc     = &showcmd
1604     let &report       = 10000
1605     set noshowcmd 
1607     " Debug output to a buffer
1608     if g:miniBufExplorerDebugMode == 0
1609         " Save the current window number so we can come back here
1610         let l:prevWin     = winnr()
1611         wincmd p
1612         let l:prevPrevWin = winnr()
1613         wincmd p
1615         " Get into the debug window or create it if needed
1616         call <SID>FindCreateWindow('MiniBufExplorer.DBG', 1, 0, 0)
1617     
1618         " Make sure we really got to our window, if not we 
1619         " will display a confirm dialog and turn debugging
1620         " off so that we won't break things even more.
1621         if bufname('%') != 'MiniBufExplorer.DBG'
1622             call confirm('Error in window debugging code. Dissabling MiniBufExplorer debugging.', 'OK')
1623             let g:miniBufExplorerDebugLevel = 0
1624         endif
1626         " Write Message to DBG buffer
1627         let res=append("$",s:debugIndex.':'.a:level.':'.a:msg)
1628         norm G
1629         "set nomodified
1631         " Return to original window
1632         exec l:prevPrevWin.' wincmd w'
1633         exec l:prevWin.' wincmd w'
1634     " Debug output using VIM's echo facility
1635     elseif g:miniBufExplorerDebugMode == 1
1636       echo s:debugIndex.':'.a:level.':'.a:msg
1637     " Debug output to a file -- VERY SLOW!!!
1638     " should be OK on UNIX and Win32 (not the 95/98 variants)
1639     elseif g:miniBufExplorerDebugMode == 2
1640         if has('system') || has('fork')
1641             if has('win32') && !has('win95')
1642                 let l:result = system("cmd /c 'echo ".s:debugIndex.':'.a:level.':'.a:msg." >> MiniBufExplorer.DBG'")
1643             endif
1644             if has('unix')
1645                 let l:result = system("echo '".s:debugIndex.':'.a:level.':'.a:msg." >> MiniBufExplorer.DBG'")
1646             endif
1647         else
1648             call confirm('Error in file writing version of the debugging code, vim not compiled with system or fork. Dissabling MiniBufExplorer debugging.', 'OK')
1649             let g:miniBufExplorerDebugLevel = 0
1650         endif
1651     elseif g:miniBufExplorerDebugMode == 3
1652         let g:miniBufExplorerDebugOutput = g:miniBufExplorerDebugOutput."\n".s:debugIndex.':'.a:level.':'.a:msg
1653     endif
1654     let s:debugIndex = s:debugIndex + 1
1656     let &report  = l:save_rep
1657     let &showcmd = l:save_sc
1659   endif
1661 endfunc " }}}
1663 " MBE Script History {{{
1664 "=============================================================================
1666 "      History: 6.3.3 o Added additional keybindings. In addition to <TAB> and
1667 "                       <S-TAB>, l and h can now be used. In addition to <CR>,
1668 "                       o and e can now be used.
1669 "                     o You can open the selected buffer in a new split window 
1670 "                       by pressing s while in the minibufexplorer window.
1671 "                       You can open the selected buffer in a new vertically
1672 "                       split window while pressing v while in the
1673 "                       minibufexplorer window. Patched by Oliver Uvman.
1674 "               6.3.2 o For some reason there was still a call to StopExplorer
1675 "                       with 2 params. Very old bug. I know I fixed before, 
1676 "                       any way many thanks to Jason Mills for reporting this!
1677 "               6.3.1 o Include folds in source so that it's easier to 
1678 "                       navigate.
1679 "                     o Added g:miniBufExplForceSyntaxEnable setting for folks
1680 "                       that want a :syntax enable to be called when we enter 
1681 "                       buffers. This can resolve issues caused by a vim bug
1682 "                       where buffers show up without highlighting when another 
1683 "                       buffer has been closed, quit, wiped or deleted.
1684 "               6.3.0 o Added an option to allow single click (rather than
1685 "                       the default double click) to select buffers in the
1686 "                       MBE window. This feature was requested by AW Law
1687 "                       and was inspired by taglist.vim. Note that you will 
1688 "                       need the latest version of taglist.vim if you want to 
1689 "                       use MBE and taglist both with singleclick turned on.
1690 "                       Also thanks to AW Law for pointing out that you can
1691 "                       make an Explorer not be listed in a standard :ls.
1692 "                     o Added the ability to have your tabs show up in a
1693 "                       vertical window rather than the standard horizontal
1694 "                       one. Just let g:miniBufExplVSplit = <width> in your
1695 "                       .vimrc and your will get this functionality.
1696 "                     o If you use the vertical explorer and you want it to
1697 "                       autosize then let g:miniBufExplMaxSize = <max width>
1698 "                       in your .vimrc. You may use the MinSize letting in
1699 "                       addition to the MaxLetting if you don't want a super
1700 "                       thin window.
1701 "                     o g:miniBufExplMaxHeight was renamed g:miniBufExplMaxSize
1702 "                       g:miniBufExplMinHeight was renamed g:miniBufExplMinSize
1703 "                       the old settings are backwards compatible if you don't
1704 "                       use the new settings, but they are depreciated.
1705 "               6.2.8 o Add an option to stop MBE from targeting non-modifiable
1706 "                       buffers when switching buffers. Thanks to AW Law for
1707 "                       the inspiration for this. This may not work if a user
1708 "                       has lots of explorer/help windows open.
1709 "               6.2.7 o Very minor bug fix for people who want to set
1710 "                       loaded_minibufexplorer in their .vimrc in order to
1711 "                       stop MBE from loading. 99.99% of users do not need
1712 "                       this update.
1713 "               6.2.6 o Moved history to end of source file
1714 "                     o Updated highlighting documentation
1715 "                     o Created global commands MBEbn and MBEbp that can be 
1716 "                       used in mappings if folks want to cycle buffers while 
1717 "                       skipping non-eligible buffers.
1718 "               6.2.5 o Added <Leader>mbt key mapping which will toggle
1719 "                       the MBE window. I map this to F3 in my .vimrc
1720 "                       with "map <F3> :TMiniBufExplorer<CR>" which 
1721 "                       means I can easily close the MBE window when I'm 
1722 "                       not using it and get it back when I want it.
1723 "                     o Changed default debug mode to 3 (write to global
1724 "                       g:miniBufExplorerDebugOutput)
1725 "                     o Made a pass through the documentation to clarify 
1726 "                       serveral issues and provide more complete docs
1727 "                       for mappings and commands.
1728 "               6.2.4 o Because of the autocommand switch (see 6.2.0) it 
1729 "                       was possible to remove the restriction on the
1730 "                       :set hidden option. It is now possible to use
1731 "                       this option with MBE.
1732 "               6.2.3 o Added miniBufExplTabWrap option. It is turned 
1733 "                       off by default. When turned on spaces are added
1734 "                       between tabs and gq} is issued to perform line
1735 "                       formatting. This won't work very well if filenames
1736 "                       contain spaces. It would be pretty easy to write
1737 "                       my own formatter, but I'm too lazy, so if someone
1738 "                       really needs that feature I'll add it :)
1739 "               6.2.2 o Changed the way the g:miniBufExplorerMoreThanOne
1740 "                       global is handled. You can set this to the number
1741 "                       of eligible buffers you want to be loaded before
1742 "                       the MBE window is loaded. Setting it to 0 causes
1743 "                       the MBE window to be opened even if there are no
1744 "                       buffers. Setting it to 4 causes the window to stay
1745 "                       closed until the 4th eligible buffer is loaded.
1746 "                     o Added a MinHeight option. This is nice if you want
1747 "                       the MBE window to always take the same amount of
1748 "                       space. For example set MaxSize and MinSize to 2
1749 "                       and set MoreThanOne to 0 and you will always have
1750 "                       a 2 row (plus the ruler :) MBE window.
1751 "                       NOTE: in 6.3.0 we started using MinSize instead of
1752 "                       Minheight. This will still work if MinSize is not
1753 "                       specified, but it is depreciated. Use MinSize instead.
1754 "                     o I now setlocal foldcomun=0 and nonumber in the MBE 
1755 "                       window. This is for those of you that like to have
1756 "                       these options turned on locally. I'm assuming noone
1757 "                       outthere wants foldcolumns and line numbers in the
1758 "                       MBE window? :)
1759 "                     o Fixed a bug where an empty MBE window was taking half
1760 "                       of the screen (partly why the MinHeight option was 
1761 "                       added.)
1762 "               6.2.1 o If MBE is the only window (because of :bd for example)
1763 "                       and there are still eligible buffers then one of them
1764 "                       will be displayed.
1765 "                     o The <Leader>mbe mapping now highlights the buffer from
1766 "                       the current window.
1767 "                     o The delete ('d') binding in the MBE window now restors
1768 "                       the cursor position, which can help if you want to 
1769 "                       delete several buffers in a row that are not at the
1770 "                       beginning of the buffer list.
1771 "                     o Added a new key binding ('p') in the MBE window to 
1772 "                       switch to the previous window (last edit window)
1773 "               6.2.0 o Major overhaul of autocommand and list updating code,
1774 "                       we now have much better handling of :bd (which is the 
1775 "                       most requested feature.) As well as resolving other
1776 "                       issues where the buffer list would not be updated
1777 "                       automatically. The old version tried to trap specific
1778 "                       events, this one just updates frequently, but it keeps
1779 "                       track and only changes the screen if there has been
1780 "                       a change.
1781 "                     o Added g:miniBufExplMaxHeight variable so you can keep
1782 "                       the -MiniBufExplorer- window small when you have lots
1783 "                       of buffers (or buffers with long names :)
1784 "                       NOTE: in 6.3.0 we started using MaxSize instead of
1785 "                       MaxHeight. This will still work if MaxSize is not
1786 "                       specified, but it is depreciated. Use MaxSize instead.
1787 "                     o Improvement to internal syntax highlighting code
1788 "                       I renamed the syntax group names. Anyone who has 
1789 "                       figured out how to use them already shouldn't have
1790 "                       any trouble with the new Nameing :)
1791 "                     o Added debug mode 3 which writes to a global variable
1792 "                       this is fast and doesn't mess with the buffer/window
1793 "                       lists.
1794 "               6.1.0 o <Leader>mbc was failing because I was calling one of
1795 "                       my own functions with the wrong number of args. :(
1796 "                       Thanks to Gerry Patterson for finding this!
1797 "                       This code is very stable (although it has some
1798 "                       idiocyncracies.)
1799 "               6.0.9 o Double clicking tabs was overwriting the cliboard 
1800 "                       register on MS Windows.  Thanks to Shoeb Bhinderwala 
1801 "                       for reporting this issue.
1802 "               6.0.8 o Apparently some VIM builds are having a hard time with
1803 "                       line continuation in scripts so the few that were here
1804 "                       have been removed.
1805 "                     o Generalized FindExplorer and FindCreateExplorer so
1806 "                       that they can be used for the debug window. Renaming
1807 "                       to FindWindow and FindCreateWindow.
1808 "                     o Updated debugging code so that debug output is put into
1809 "                       a buffer which can then be written to disk or emailed
1810 "                       to me when someone is having a major issue. Can also
1811 "                       write directly to a file (VERY SLOWLY) on UNIX or Win32
1812 "                       (not 95 or 98 at the moment) or use VIM's echo function 
1813 "                       to display the output to the screen.
1814 "                     o Several people have had issues when the hidden option 
1815 "                       is turned on. So I have put in several checks to make
1816 "                       sure folks know this if they try to use MBE with this
1817 "                       option set.
1818 "               6.0.7 o Handling BufDelete autocmd so that the UI updates 
1819 "                       properly when using :bd (rather than going through 
1820 "                       the MBE UI.)
1821 "                     o The AutoUpdate code will now close the MBE window when 
1822 "                       there is a single eligible buffer available.
1823 "                       This has the usefull side effect of stopping the MBE
1824 "                       window from blocking the VIM session open when you close 
1825 "                       the last buffer.
1826 "                     o Added functions, commands and maps to close & update
1827 "                       the MBE window (<leader>mbc and <leader>mbu.)
1828 "                     o Made MBE open/close state be sticky if set through
1829 "                       StartExplorer(1) or StopExplorer(1), which are 
1830 "                       called from the standard mappings. So if you close
1831 "                       the mbe window with \mbc it won't be automatically 
1832 "                       opened again unless you do a \mbe (or restart VIM).
1833 "                     o Removed spaces between "tabs" (even more mini :)
1834 "                     o Simplified MBE tab processing 
1835 "               6.0.6 o Fixed register overwrite bug found by Sébastien Pierre
1836 "               6.0.5 o Fixed an issue with window sizing when we run out of 
1837 "                       buffers.  
1838 "                     o Fixed some weird commenting bugs.  
1839 "                     o Added more optional fancy window/buffer navigation:
1840 "                     o You can turn on the capability to use control and the 
1841 "                       arrow keys to move between windows.
1842 "                     o You can turn on the ability to use <C-TAB> and 
1843 "                       <C-S-TAB> to open the next and previous (respectively) 
1844 "                       buffer in the current window.
1845 "                     o You can turn on the ability to use <C-TAB> and 
1846 "                       <C-S-TAB> to switch windows (forward and backwards 
1847 "                       respectively.)
1848 "               6.0.4 o Added optional fancy window navigation: 
1849 "                     o Holding down control and pressing a vim direction 
1850 "                       [hjkl] will switch windows in the indicated direction.
1851 "               6.0.3 o Changed buffer name to -MiniBufExplorer- to resolve
1852 "                       Issue in filename pattern matching on Windows.
1853 "               6.0.2 o 2 Changes requested by Suresh Govindachar:
1854 "                     o Added SplitToEdge option and set it on by default
1855 "                     o Added tab and shift-tab mappings in [MBE] window
1856 "               6.0.1 o Added MoreThanOne option and set it on by default
1857 "                       MiniBufExplorer will not automatically open until
1858 "                       more than one eligible buffers are opened. This
1859 "                       reduces cluter when you are only working on a
1860 "                       single file. 
1861 "                       NOTE: See change log for 6.2.2 for more details about 
1862 "                             this feature
1863 "               6.0.0 o Initial Release on November 20, 2001
1865 "=============================================================================
1866 " }}}
1867 " vim:ft=vim:fdm=marker:ff=unix:nowrap:tabstop=4:shiftwidth=4:softtabstop=4:smarttab:shiftround:expandtab