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