Latest bufexplorer plugin.
authorIain Patterson <me@iain.cx>
Wed, 5 Oct 2011 13:03:00 +0000 (14:03 +0100)
committerIain Patterson <me@iain.cx>
Wed, 5 Oct 2011 16:30:07 +0000 (17:30 +0100)
Recent versions of vim were printing annoying warnings about
the ActivateBuffer() function.

.vim/doc/bufexplorer.txt
.vim/plugin/bufexplorer.vim

index 9af0682..06e9223 100644 (file)
@@ -1,12 +1,13 @@
-*bufexplorer.txt*              Buffer Explorer       Last Change: 19 Nov 2008
+*bufexplorer.txt*              Buffer Explorer       Last Change: 22 Oct 2010
 
 Buffer Explorer                                *buffer-explorer* *bufexplorer*
-                                Version 7.2.2
+                                Version 7.2.8
 
 Plugin for easily exploring (or browsing) Vim |:buffers|.
 
-|bufexplorer-usage|          Usage
 |bufexplorer-installation|   Installation
+|bufexplorer-usage|          Usage
+|bufexplorer-windowlayout|   Window Layout
 |bufexplorer-customization|  Customization
 |bufexplorer-changelog|      Change Log
 |bufexplorer-todo|           Todo
@@ -27,7 +28,7 @@ To install:
   - Start Vim or goto an existing instance of Vim.
   - Execute the following command:
 >
-      :helptag <your runtime directory/doc
+      :helptag <your runtime directory>/doc
 <
     This will generate all the help tags for any file located in the doc
     directory.
@@ -36,11 +37,11 @@ To install:
 USAGE                                                      *bufexplorer-usage*
 
 To start exploring in the current window, use: >
- \be   OR  :BufExplorer
+ \be   or   :BufExplorer
 To start exploring in a newly split horizontal window, use: >
- \bs  or  :HSBufExplorer
+ \bs   or   :BufExplorerHorizontalSplit
 To start exploring in a newly split vertical window, use: >
- \bv  or  :VSBufExplorer
+ \bv   or   :BufExplorerVerticalSplit
 
 If you would like to use something other than '\', you may simply change the
 leader (see |mapleader|).
@@ -51,24 +52,27 @@ Note: If the current buffer is modified when bufexplorer started, the current
 
 Commands to use once exploring:
 
+ <F1>          Toggle help information.
  <enter>       Opens the buffer that is under the cursor into the current
                window.
- <F1>          Toggle help information.
  <leftmouse>   Opens the buffer that is under the cursor into the current
                window.
  <shift-enter> Opens the buffer that is under the cursor in another tab.
- d             |:wipeout| the buffer under the cursor from the list.
-               When a buffers is wiped, it will not be shown when unlisted
-               buffer are displayed.
- D             |:delete| the buffer under the cursor from the list.
-               The buffer's 'buflisted' is cleared. This allows for the buffer
-               to be displayed again using the 'show unlisted' command.
+ d            |:delete|the buffer under the cursor from the list.  The
+               buffer's 'buflisted' is cleared. This allows for the buffer to
+               be displayed again using the 'show unlisted' command.
+ R             Toggles relative path/absolute path.
+ T             Toggles to show only buffers for this tab or not.
+ D            |:wipeout|the buffer under the cursor from the list.  When a
+               buffers is wiped, it will not be shown when unlisted buffer are
+               displayed.
  f             Toggles whether you are taken to the active window when
                selecting a buffer or not.
+ o             Opens the buffer that is under the cursor into the current
+               window.
  p             Toggles the showing of a split filename/pathname.
  q             Quit exploring.
  r             Reverses the order the buffers are listed in.
- R             Toggles relative path/absolute path.
  s             Selects the order the buffers are listed in. Either by buffer
                number, file name, file extension, most recently used (MRU), or
                full path.
@@ -82,9 +86,30 @@ wanting to act upon. Once you have selected the buffer you would like,
 you can then either open it, close it(delete), resort the list, reverse
 the sort, quit exploring and so on...
 
+===============================================================================
+WINDOW LAYOUT                                       *bufexplorer-windowlayout*
+
+-------------------------------------------------------------------------------
+" Press <F1> for Help
+" Sorted by mru | Locate buffer | Absolute Split path
+"=
+ 01 %a    bufexplorer.txt      C:\Vim\vimfiles\doc       line 87
+ 02 #     bufexplorer.vim      c:\Vim\vimfiles\plugin    line 1
+-------------------------------------------------------------------------------
+  | |     |                    |                         |
+  | |     |                    |                         +-- Current Line #.
+  | |     |                    +-- Relative/Full Path
+  | |     +-- Buffer Name.
+  | +-- Buffer Attributes. See|:buffers|for more information.
+  +-- Buffer Number. See|:buffers|for more information.
+
 ===============================================================================
 CUSTOMIZATION                                       *bufexplorer-customization*
 
+                                                          *g:bufExplorerChgWin*
+If set, bufexplorer will bring up the selected buffer in the window specified
+by g:bufExplorerChgWin.
+
                                                      *g:bufExplorerDefaultHelp*
 To control whether the default help is displayed or not, use: >
   let g:bufExplorerDefaultHelp=0       " Do not show default help.
@@ -104,6 +129,10 @@ use: >
   let g:bufExplorerFindActive=1        " Go to active window.
 The default is to be taken to the active window.
 
+                                                         *g:bufExplorerFuncRef*
+When a buffer is selected, the functions specified either singly or as a list
+will be called.
+
                                                      *g:bufExplorerReverseSort*
 To control whether to sort the buffer in reverse order or not, use: >
   let g:bufExplorerReverseSort=0       " Do not sort in reverse order.
@@ -124,6 +153,12 @@ directory, use: >
   let g:bufExplorerShowRelativePath=1  " Show relative paths.
 The default is to show absolute paths.
 
+                                                   *g:bufExplorerShowTabBuffer*
+To control weither or not to show buffers on for the specific tab or not, use: >
+  let g:bufExplorerShowTabBuffer=0        " No.
+  let g:bufExplorerShowTabBuffer=1        " Yes.
+The default is not to show.
+
                                                     *g:bufExplorerShowUnlisted*
 To control whether to show unlisted buffer or not, use: >
   let g:bufExplorerShowUnlisted=0      " Do not show unlisted buffers.
@@ -164,11 +199,48 @@ The default is to use the global &splitright.
 ===============================================================================
 CHANGE LOG                                              *bufexplorer-changelog*
 
-7.2.2  - Fix:
+7.2.8  - Enhancements:
+         * Thanks to Charles Campbell for integrating bufexplorer with GDBMGR.
+           http://mysite.verizon.net/astronaut/vim/index.html#GDBMGR
+7.2.7  - Fix:
+         * My 1st attempt to fix the "cache" issue where buffers information
+           has changed but the cache/display does not reflect those changes.
+           More work still needs to be done.
+7.2.6  - Fix:
+         * Thanks to Michael Henry for pointing out that I totally forgot to
+           update the inline help to reflect the previous change to the 'd'
+           and 'D' keys. Opps!
+7.2.5  - Fix:
+         * Philip Morant suggested switching the command (bwipe) associated
+           with the 'd' key with the command (bdelete) associated with the 'D'
+           key. This made sense since the 'd' key is more likely to be used
+           compared to the 'D' key.
+7.2.4  - Fix:
+         * I did not implement the patch provided by Godefroid Chapelle
+           correctly. I missed one line which happened to be the most
+           important one :)
+7.2.3  - Enhancements:
+         * Thanks to David Fishburn for helping me out with a much needed
+           code overhaul as well as some awesome performance enhancements.
+           He also reworked the handling of tabs.
+         * Thanks to Vladimir Dobriakov for making the suggestions on
+           enhancing the documentation to include a better explaination of
+           what is contained in the main bufexplorer window.
+         * Thanks to Yuriy Ershov for added code that when the bufexplorer
+           window is opened, the cursor is now positioned at the line with the
+           active buffer (useful in non-MRU sort modes).
+         * Yuriy also added the abiltiy to cycle through the sort fields in
+           reverse order.
+         Fixes:
+         * Thanks to Michael Henry for supplying a patch that allows
+           bufexplorer to be opened even when there is one buffer or less.
+         * Thanks to Godefroid Chapelle for supplying a patch that fixed
+           MRU sort order after loading a session.
+7.2.2  - Fixes:
          * Thanks to David L. Dight for spotting and fixing an issue when
            using ctrl^. bufexplorer would incorrectly handle the previous
            buffer so that when ctrl^ was pressed the incorrect file was opened.
-7.2.1  - Fix:
+7.2.1  - Fixes:
          * Thanks to Dimitar for spotting and fixing a feature that was
            inadvertently left out of the previous version. The feature was
            when bufexplorer was used together with WinManager, you could use
@@ -419,14 +491,13 @@ CHANGE LOG                                              *bufexplorer-changelog*
          *compliant*, adding default keymappings of <Leader>be and <Leader>bs
          as well as fixing the 'w:sortDirLabel not being defined' bug.
 6.0.3  - Added sorting capabilities. Sort taken from explorer.vim.
-6.0.2  - Can't remember.
+6.0.2  - Can't remember. (2001-07-25)
 6.0.1  - Initial release.
 
 ===============================================================================
 TODO                                                         *bufexplorer-todo*
 
-- The issuing of a ':bd' command does not always remove the buffer number from
-  the MRU list.
+- Nothing as of now, buf if you have any suggestions, drop me an email.
 
 ===============================================================================
 CREDITS                                                   *bufexplorer-credits*
index fc361da..0e8904a 100644 (file)
@@ -1,5 +1,5 @@
-"=============================================================================
-"    Copyright: Copyright (C) 2001-2008 Jeff Lanzarotta
+"==============================================================================
+"    Copyright: Copyright (C) 2001-2010 Jeff Lanzarotta
 "               Permission is hereby granted to use and distribute this code,
 "               with or without modifications, provided that this copyright
 "               notice is copied with it. Like anything else that's free,
 " Name Of File: bufexplorer.vim
 "  Description: Buffer Explorer Vim Plugin
 "   Maintainer: Jeff Lanzarotta (delux256-vim at yahoo dot com)
-" Last Changed: Wednesday, 19 Nov 2008
+" Last Changed: Friday, 22 October 2010
 "      Version: See g:bufexplorer_version for version number.
 "        Usage: This file should reside in the plugin directory and be
 "               automatically sourced.
 "
 "               You may use the default keymappings of
 "
-"                 <Leader>be  - Opens BufExplorer
-"                 <Leader>bs  - Opens horizontally split window BufExplorer
-"                 <Leader>bv  - Opens vertically split window BufExplorer
+"                 <Leader>be  - Opens BE.
+"                 <Leader>bs  - Opens horizontally window BE.
+"                 <Leader>bv  - Opens vertically window BE.
 "
 "               Or you can use
 "
-"                 ":BufExplorer" - Opens BufExplorer
-"                 ":HSBufExplorer" - Opens horizontally window BufExplorer
-"                 ":VSBufExplorer" - Opens vertically split window BufExplorer
+"                 ":BufExplorer"                - Opens BE.
+"                 ":BufExplorerHorizontalSplit" - Opens horizontally window BE.
+"                 ":BufExplorerVerticalSplit"   - Opens vertically window BE.
 "
 "               For more help see supplied documentation.
 "      History: See supplied documentation.
-"=============================================================================
+"==============================================================================
 
 " Exit quickly if already running or when 'compatible' is set. {{{1
 if exists("g:bufexplorer_version") || &cp
@@ -38,7 +38,7 @@ endif
 "1}}}
 
 " Version number
-let g:bufexplorer_version = "7.2.2"
+let g:bufexplorer_version = "7.2.8"
 
 " Check for Vim version 700 or greater {{{1
 if v:version < 700
@@ -47,17 +47,29 @@ if v:version < 700
 endif
 
 " Public Interface {{{1
-nmap <silent> <unique> <Leader>be :BufExplorer<CR>
-nmap <silent> <unique> <Leader>bs :HSBufExplorer<CR>
-nmap <silent> <unique> <Leader>bv :VSBufExplorer<CR>
+if maparg("<Leader>be") =~ 'BufExplorer'
+  nunmap <Leader>be
+endif
+
+if maparg("<Leader>bs") =~ 'BufExplorerHorizontalSplit'
+  nunmap <Leader>bs
+endif
+
+if maparg("<Leader>bv") =~ 'BufExplorerVerticalSplit'
+  nunmap <Leader>bv
+endif
+
+nmap <script> <silent> <unique> <Leader>be :BufExplorer<CR>
+nmap <script> <silent> <unique> <Leader>bs :BufExplorerHorizontalSplit<CR>
+nmap <script> <silent> <unique> <Leader>bv :BufExplorerVerticalSplit<CR>
 
 " Create commands {{{1
-command BufExplorer :call StartBufExplorer(has ("gui") ? "drop" : "hide edit")
-command HSBufExplorer :call HorizontalSplitBufExplorer()
-command VSBufExplorer :call VerticalSplitBufExplorer()
+command! BufExplorer :call StartBufExplorer(has ("gui") ? "drop" : "hide edit")
+command! BufExplorerHorizontalSplit :call BufExplorerHorizontalSplit()
+command! BufExplorerVerticalSplit :call BufExplorerVerticalSplit()
 
-" Set {{{1
-function s:Set(var, default)
+" BESet {{{1
+function! s:BESet(var, default)
   if !exists(a:var)
     if type(a:default)
       exec "let" a:var "=" string(a:default)
@@ -71,99 +83,177 @@ function s:Set(var, default)
   return 0
 endfunction
 
-" Default values {{{1
-call s:Set("g:bufExplorerDefaultHelp", 1)           " Show default help?
-call s:Set("g:bufExplorerDetailedHelp", 0)          " Show detailed help?
-call s:Set("g:bufExplorerFindActive", 1)            " When selecting an active buffer, take you to the window where it is active?
-call s:Set("g:bufExplorerReverseSort", 0)           " sort reverse?
-call s:Set("g:bufExplorerShowDirectories", 1)       " (Dir's are added by commands like ':e .')
-call s:Set("g:bufExplorerShowRelativePath", 0)      " Show listings with relative or absolute paths?
-call s:Set("g:bufExplorerShowUnlisted", 0)          " Show unlisted buffers?
-call s:Set("g:bufExplorerSortBy", "mru")            " Sorting methods are in s:sort_by:
-call s:Set("g:bufExplorerSplitOutPathName", 1)      " Split out path and file name?
-call s:Set("g:bufExplorerSplitRight", &splitright)  " Should vertical splits be on the right or left of current window?
-call s:Set("g:bufExplorerSplitBelow", &splitbelow)  " Should horizontal splits be below or above current window?
+" BEReset {{{1
+function! s:BEReset()
+  " Build initial MRUList. This makes sure all the files specified on the
+  " command line are picked up correctly.
+  let s:MRUList = range(1, bufnr('$'))
 
-" Global variables {{{1
-let s:MRUList = []
-let s:running = 0
-let s:sort_by = ["number", "name", "fullpath", "mru", "extension"]
-let s:tabSpace = []
-let s:types = {"fullname": ':p', "path": ':p:h', "relativename": ':~:.', "relativepath": ':~:.:h', "shortname": ':t'}
-let s:originBuffer = 0
-let s:splitMode = ""
+  " Initialize one tab space array, ignore zero-based tabpagenr
+  " since all tabpagenr's start at 1.
+  " -1 signifies this is the first time we are referencing this
+  " tabpagenr.
+  let s:tabSpace = [ [-1], [-1] ]
+endfunction
 
 " Setup the autocommands that handle the MRUList and other stuff. {{{1
-autocmd VimEnter * call s:Setup()
+" This is only done once when Vim starts up.
+augroup BufExplorerVimEnter
+  autocmd!
+  autocmd VimEnter * call s:BESetup()
+augroup END
+
+" BESetup {{{1
+function! s:BESetup()
+  call s:BEReset()
+
+  " Now that the MRUList is created, add the other autocmds.
+  augroup BufExplorer
+    " Deleting autocommands in case the script is reloaded
+    autocmd!
+    autocmd TabEnter * call s:BETabEnter()
+    autocmd BufNew * call s:BEAddBuffer()
+    autocmd BufEnter * call s:BEActivateBuffer()
+
+    autocmd BufWipeOut * call s:BEDeactivateBuffer(1)
+    autocmd BufDelete * call s:BEDeactivateBuffer(0)
+
+    autocmd BufWinEnter \[BufExplorer\] call s:BEInitialize()
+    autocmd BufWinLeave \[BufExplorer\] call s:BECleanup()
+    autocmd SessionLoadPost * call s:BEReset()
+  augroup END
+
+  " Remove the VimEnter event as it is no longer needed
+  augroup SelectBufVimEnter
+    autocmd!
+  augroup END
+endfunction
 
-" Setup {{{1
-function s:Setup()
-                                " Build initial MRUList.
-  let s:MRUList = range(1, bufnr('$'))
-  let s:tabSpace = []
-                                " Now that the MRUList is created, add the other autocmds.
-  autocmd BufEnter,BufNew * call s:ActivateBuffer()
-  autocmd BufWipeOut * call s:DeactivateBuffer(1)
-  autocmd BufDelete * call s:DeactivateBuffer(0)
+" BETabEnter {{{1
+function! s:BETabEnter()
+  " Make s:tabSpace 1-based
+  if empty(s:tabSpace) || len(s:tabSpace) < (tabpagenr() + 1)
+    call add(s:tabSpace, [-1])
+  endif
+endfunction
+
+" BEAddBuffer {{{1
+function! s:BEAddBuffer()
+  if !exists('s:raw_buffer_listing') || empty(s:raw_buffer_listing)
+    silent let s:raw_buffer_listing = s:BEGetBufferInfo(0)
+  else
+    " We cannot use :buffers! or :ls! to gather information 
+    " about this buffer since it was only just added.
+    " Any changes to the buffer (setlocal buftype, ...) 
+    " happens after this event fires.
+    "
+    " So we will indicate the :buffers! command must be re-run.
+    " This should help with the performance of the plugin.
+
+    " There are some checks which can be performed 
+    " before deciding to refresh the buffer list.
+    let bufnr = expand('<abuf>') + 0
+
+    if s:BEIgnoreBuffer(bufnr) == 1
+      return 
+    else
+      let s:refreshBufferList = 1
+    endif
+  endif
 
-  autocmd BufWinEnter \[BufExplorer\] call s:Initialize()
-  autocmd BufWinLeave \[BufExplorer\] call s:Cleanup()
+  call s:BEActivateBuffer()
 endfunction
 
 " ActivateBuffer {{{1
-function s:ActivateBuffer()
+function! s:BEActivateBuffer()
   let b = bufnr("%")
   let l = get(s:tabSpace, tabpagenr(), [])
 
-  if empty(l) || index(l, b) == -1
-    call add(l, b)
+  if s:BEIgnoreBuffer(b) == 1
+    return
+  endif
+
+  if !empty(l) && l[0] == '-1'
+    " The first time we add a tab Vim uses the current 
+    " buffer as it's starting page, even though we are about
+    " to edit a new page (BufEnter triggers after), so
+    " remove the -1 entry indicating we have covered this case.
+    let l = []
     let s:tabSpace[tabpagenr()] = l
+  elseif empty(l) || index(l, b) == -1
+    " Add new buffer to this tab buffer list
+    let l = add(l, b)
+    let s:tabSpace[tabpagenr()] = l
+
+    if g:bufExplorerOnlyOneTab == 1
+      " If a buffer can only be available in 1 tab page
+      " ensure this buffer is not present in any other tabs
+      let tabidx = 1
+      while tabidx < len(s:tabSpace)
+        if tabidx != tabpagenr()
+          let bufidx = index(s:tabSpace[tabidx], b)
+          if bufidx != -1
+            call remove(s:tabSpace[tabidx], bufidx)
+          endif
+        endif
+        let tabidx = tabidx + 1
+      endwhile
+    endif
   endif
 
-  call s:MRUPush(b)
+  call s:BEMRUPush(b)
+
+  if exists('s:raw_buffer_listing') && !empty(s:raw_buffer_listing)
+    " Check if the buffer exists, but was deleted previously
+    " Careful use of ' and " so we do not have to escape all the \'s
+    " Regex: ^\s*bu\>
+    "        ^ - Starting at the beginning of the string
+    "        \s* - optional whitespace
+    "        b - Vim's buffer number
+    "        u\> - the buffer must be unlisted
+    let shortlist = filter(copy(s:raw_buffer_listing), "v:val.attributes =~ '".'^\s*'.b.'u\>'."'")
+
+    if !empty(shortlist)
+      " If it is unlisted (ie deleted), but now we editing it again 
+      " rebuild the buffer list.
+      let s:refreshBufferList = 1
+    endif
+  endif
 endfunction
 
-" DeactivateBuffer {{{1
-function s:DeactivateBuffer(remove)
-  "echom "afile:" expand("<afile>")
-  "echom "bufnr, afile:" bufnr(expand("<afile>"))
-  "echom "buffers:" string(tabpagebuflist())
-  "echom "MRU before:" string(s:MRUList)
+" BEDeactivateBuffer {{{1
+function! s:BEDeactivateBuffer(remove)
+  let _bufnr = str2nr(expand("<abuf>"))
 
-  let _bufnr = bufnr(expand("<afile>"))
-  let _buftype = getbufvar(_bufnr, "&buftype")
-
-  if empty(_buftype) || _buftype == "nofile" || !buflisted(_bufnr) || empty(bufname(_bufnr)) || fnamemodify(bufname(_bufnr), ":t") == "[BufExplorer]"
-    return
-  end
+  call s:BEMRUPop(_bufnr)
 
   if a:remove
-    call s:MRUPop(bufnr(expand("<afile>")))
-  end
+    call s:BEDeleteBufferListing(_bufnr)
+  else
+    let s:refreshBufferList = 1
+  endif
 endfunction
 
-" MRUPop {{{1
-function s:MRUPop(buf)
+" BEMRUPop {{{1
+function! s:BEMRUPop(buf)
   call filter(s:MRUList, 'v:val != '.a:buf)
 endfunction
 
-" MRUPush {{{1
-function s:MRUPush(buf)
-                                " Skip temporary buffer with buftype set. Don't add the BufExplorer window to the
-                                " list.
-  if !empty(getbufvar(a:buf, "&buftype")) ||
-      \ !buflisted(a:buf) || empty(bufname(a:buf)) ||
-      \ fnamemodify(bufname(a:buf), ":t") == "[BufExplorer]"
+" BEMRUPush {{{1
+function! s:BEMRUPush(buf)
+  if s:BEIgnoreBuffer(a:buf) == 1
     return
-  end
-                                " Remove the buffer number from the list if it already exists.
-  call s:MRUPop(a:buf)
-                                " Add the buffer number to the head of the list.
+  endif
+
+  " Remove the buffer number from the list if it already exists.
+  call s:BEMRUPop(a:buf)
+
+  " Add the buffer number to the head of the list.
   call insert(s:MRUList,a:buf)
 endfunction
 
-" Initialize {{{1
-function s:Initialize()
+" BEInitialize {{{1
+function! s:BEInitialize()
   let s:_insertmode = &insertmode
   set noinsertmode
 
@@ -184,107 +274,149 @@ function s:Initialize()
   setlocal nofoldenable
   setlocal cursorline
   setlocal nospell
-
-  set nobuflisted
+  setlocal nobuflisted
 
   let s:running = 1
 endfunction
 
-" Cleanup {{{1
-function s:Cleanup()
-  let &insertmode = s:_insertmode
-  let &showcmd = s:_showcmd
-  let &cpo = s:_cpo
-  let &report = s:_report
-  let &list = s:_list
-  let s:running = 0
+" BEIgnoreBuffer 
+function! s:BEIgnoreBuffer(buf)
+  " Check to see if this buffer should be ignore by BufExplorer.
+
+  " Skip temporary buffers with buftype set.
+  if empty(getbufvar(a:buf, "&buftype") == 0)
+    return 1
+  endif
+
+  " Skip unlisted buffers.
+  if buflisted(a:buf) == 0
+    return 1
+  endif
+
+  " Skip buffers with no name.
+  if empty(bufname(a:buf)) == 1
+    return 1
+  endif
+
+  " Do not add the BufExplorer window to the list.
+  if fnamemodify(bufname(a:buf), ":t") == s:name
+    call s:BEError("The buffer name was [".s:name."] so it was skipped.")
+    return 1
+  endif
+
+  if index(s:MRU_Exclude_List, bufname(a:buf)) >= 0
+    return 1
+  end
+
+  return 0 
+endfunction
+
+" BECleanup {{{1
+function! s:BECleanup()
+  if exists("s:_insertmode")|let &insertmode = s:_insertmode|endif
+  if exists("s:_showcmd")   |let &showcmd    = s:_showcmd   |endif
+  if exists("s:_cpo")       |let &cpo        = s:_cpo       |endif
+  if exists("s:_report")    |let &report     = s:_report    |endif
+  if exists("s:_list")      |let &list       = s:_list      |endif
+  let s:running   = 0
   let s:splitMode = ""
 
   delmarks!
 endfunction
 
-" HorizontalSplitBufExplorer {{{1
-function HorizontalSplitBufExplorer()
+" BufExplorerHorizontalSplit {{{1
+function! BufExplorerHorizontalSplit()
   let s:splitMode = "sp"
   exec "BufExplorer"
 endfunction
 
-" VerticalSplitBufExplorer {{{1
-function VerticalSplitBufExplorer()
+" BufExplorerVerticalSplit {{{1
+function! BufExplorerVerticalSplit()
   let s:splitMode = "vsp"
   exec "BufExplorer"
 endfunction
 
 " StartBufExplorer {{{1
-function StartBufExplorer(open)
-  let name = '[BufExplorer]'
+function! StartBufExplorer(open)
+    let name = s:name
 
-  if !has("win32")
-                                " On non-Windows boxes, escape the name so that is shows up correctly.
-    let name = escape(name, "[]")
-  endif
-                                " Make sure there is only one explorer open at a time.
-  if s:running == 1
-                                " Go to the open buffer.
-    if has("gui")
-      exec "drop" name
+    if !has("win32")
+        " On non-Windows boxes, escape the name so that is shows up correctly.
+        let name = escape(name, "[]")
+        call s:BEError("Escaped")
     endif
 
-    return
-  endif
+    " Make sure there is only one explorer open at a time.
+    if s:running == 1
+        call s:BEError("WHAT THE 1")
+        " Go to the open buffer.
+        if has("gui")
+            call s:BEError("WHAT THE 2")
+            call s:BEError(name)
+            exec "drop" name
+        endif
 
-  let s:originBuffer = bufnr("%")
-  silent let s:raw_buffer_listing = s:GetBufferInfo()
+        return
+    endif
 
-  let copy = copy(s:raw_buffer_listing)
+    " Add zero to ensure the variable is treated as a Number.
+    let s:originBuffer = bufnr("%") + 0
 
-  if (g:bufExplorerShowUnlisted == 0)
-    call filter(copy, 'v:val.attributes !~ "u"')
-  endif
+    " Create or rebuild the raw buffer list if necessary.
+    if !exists('s:raw_buffer_listing') || 
+            \ empty(s:raw_buffer_listing) ||
+            \ s:refreshBufferList == 1
+        silent let s:raw_buffer_listing = s:BEGetBufferInfo(0)
+    endif
 
-  if (!empty(copy))
-    call filter(copy, 'v:val.shortname !~ "\\\[No Name\\\]"')
-  endif
+    let copy = copy(s:raw_buffer_listing)
 
-  if len(copy) <= 1
-    echo "\r"
-    call s:Warning("Sorry, there are no more buffers to explore")
+    if (g:bufExplorerShowUnlisted == 0)
+        call filter(copy, 'v:val.attributes !~ "u"')
+    endif
 
-    return
-  endif
-                                " We may have to split the current window.
+  " We may have to split the current window.
   if (s:splitMode != "")
-                                " Save off the original settings.
+    " Save off the original settings.
     let [_splitbelow, _splitright] = [&splitbelow, &splitright]
-                                " Set the setting to ours.
+
+    " Set the setting to ours.
     let [&splitbelow, &splitright] = [g:bufExplorerSplitBelow, g:bufExplorerSplitRight]
-                                " Do it.
-    exe s:splitMode
-                                " Restore the original settings.
+
+    " Do it.
+    exe 'keepalt '.s:splitMode
+
+    " Restore the original settings.
     let [&splitbelow, &splitright] = [_splitbelow, _splitright]
   endif
 
   if !exists("b:displayMode") || b:displayMode != "winmanager"
-                                " Do not use keepalt when opening bufexplorer to allow the buffer that we are
-                                " leaving to become the new alternate buffer
+    " Do not use keepalt when opening bufexplorer to allow the buffer that we are
+    " leaving to become the new alternate buffer
     exec "silent keepjumps ".a:open." ".name
   endif
 
-  call s:DisplayBufferList()
+  call s:BEDisplayBufferList()
 endfunction
 
-" DisplayBufferList {{{1
-function s:DisplayBufferList()
-  setlocal bufhidden=delete
+" BEDisplayBufferList {{{1
+function! s:BEDisplayBufferList()
+  " Do not set bufhidden since it wipes out 
+  " the data if we switch away from the buffer 
+  " using CTRL-^
   setlocal buftype=nofile
   setlocal modifiable
   setlocal noswapfile
   setlocal nowrap
 
-  call s:SetupSyntax()
-  call s:MapKeys()
-  call setline(1, s:CreateHelp())
-  call s:BuildBufferList()
+  " Delete all previous lines to the black hole register
+  call cursor(1,1)
+  exec 'silent! normal! "_dG'
+
+  call s:BESetupSyntax()
+  call s:BEMapKeys()
+  call setline(1, s:BECreateHelp())
+  call s:BEBuildBufferList()
   call cursor(s:firstBufferLine, 1)
 
   if !g:bufExplorerResize
@@ -294,54 +426,61 @@ function s:DisplayBufferList()
   setlocal nomodifiable
 endfunction
 
-" MapKeys {{{1
-function s:MapKeys()
+" BEMapKeys {{{1
+function! s:BEMapKeys()
   if exists("b:displayMode") && b:displayMode == "winmanager"
-    nnoremap <buffer> <silent> <tab> :call <SID>SelectBuffer("tab")<cr>
+    nnoremap <buffer> <silent> <tab> :call <SID>BESelectBuffer("tab")<cr>
   endif
 
-  nnoremap <buffer> <silent> <F1>          :call <SID>ToggleHelp()<cr>
-  nnoremap <buffer> <silent> <2-leftmouse> :call <SID>SelectBuffer()<cr>
-  nnoremap <buffer> <silent> <cr>          :call <SID>SelectBuffer()<cr>
-  nnoremap <buffer> <silent> t             :call <SID>SelectBuffer("tab")<cr>
-  nnoremap <buffer> <silent> <s-cr>        :call <SID>SelectBuffer("tab")<cr>
-  nnoremap <buffer> <silent> d             :call <SID>RemoveBuffer("wipe")<cr>
-  nnoremap <buffer> <silent> D             :call <SID>RemoveBuffer("delete")<cr>
-  nnoremap <buffer> <silent> m             :call <SID>MRUListShow()<cr>
-  nnoremap <buffer> <silent> p             :call <SID>ToggleSplitOutPathName()<cr>
-  nnoremap <buffer> <silent> q             :call <SID>Close()<cr>
-  nnoremap <buffer> <silent> r             :call <SID>SortReverse()<cr>
-  nnoremap <buffer> <silent> R             :call <SID>ToggleShowRelativePath()<cr>
-  nnoremap <buffer> <silent> s             :call <SID>SortSelect()<cr>
-  nnoremap <buffer> <silent> u             :call <SID>ToggleShowUnlisted()<cr>
-  nnoremap <buffer> <silent> f             :call <SID>ToggleFindActive()<cr>
+  nnoremap <buffer> <silent> <F1>          :call <SID>BEToggleHelp()<cr>
+  nnoremap <buffer> <silent> <2-leftmouse> :call <SID>BESelectBuffer()<cr>
+  nnoremap <buffer> <silent> <cr>          :call <SID>BESelectBuffer()<cr>
+  nnoremap <buffer> <silent> o             :call <SID>BESelectBuffer()<cr>
+  nnoremap <buffer> <silent> t             :call <SID>BESelectBuffer("tab")<cr>
+  nnoremap <buffer> <silent> <s-cr>        :call <SID>BESelectBuffer("tab")<cr>
+
+  nnoremap <buffer> <silent> d             :call <SID>BERemoveBuffer("delete", "n")<cr>
+  xnoremap <buffer> <silent> d             :call <SID>BERemoveBuffer("delete", "v")<cr>
+  nnoremap <buffer> <silent> D             :call <SID>BERemoveBuffer("wipe", "n")<cr>
+  xnoremap <buffer> <silent> D             :call <SID>BERemoveBuffer("wipe", "v")<cr>
+
+  nnoremap <buffer> <silent> m             :call <SID>BEMRUListShow()<cr>
+  nnoremap <buffer> <silent> p             :call <SID>BEToggleSplitOutPathName()<cr>
+  nnoremap <buffer> <silent> q             :call <SID>BEClose("quit")<cr>
+  nnoremap <buffer> <silent> r             :call <SID>BESortReverse()<cr>
+  nnoremap <buffer> <silent> R             :call <SID>BEToggleShowRelativePath()<cr>
+  nnoremap <buffer> <silent> s             :call <SID>BESortSelect()<cr>
+  nnoremap <buffer> <silent> S             :call <SID>BEReverseSortSelect()<cr>
+  nnoremap <buffer> <silent> u             :call <SID>BEToggleShowUnlisted()<cr>
+  nnoremap <buffer> <silent> f             :call <SID>BEToggleFindActive()<cr>
+  nnoremap <buffer> <silent> T             :call <SID>BEToggleShowTabBuffer()<cr>
+  nnoremap <buffer> <silent> B             :call <SID>BEToggleOnlyOneTab()<cr>
 
   for k in ["G", "n", "N", "L", "M", "H"]
     exec "nnoremap <buffer> <silent>" k ":keepjumps normal!" k."<cr>"
   endfor
 endfunction
 
-" SetupSyntax {{{1
-function s:SetupSyntax()
+" BESetupSyntax {{{1
+function! s:BESetupSyntax()
   if has("syntax")
-    syn match bufExplorerHelp     "^\".*" contains=bufExplorerSortBy,bufExplorerMapping,bufExplorerTitle,bufExplorerSortType,bufExplorerToggleSplit,bufExplorerToggleOpen
-    syn match bufExplorerOpenIn   "Open in \w\+ window" contained
-    syn match bufExplorerSplit    "\w\+ split" contained
-    syn match bufExplorerSortBy   "Sorted by .*" contained contains=bufExplorerOpenIn,bufExplorerSplit
-    syn match bufExplorerMapping  "\" \zs.\+\ze :" contained
-    syn match bufExplorerTitle    "Buffer Explorer.*" contained
-    syn match bufExplorerSortType "'\w\{-}'" contained
-    syn match bufExplorerBufNbr   /^\s*\d\+/
+    syn match bufExplorerHelp         "^\".*" contains=bufExplorerSortBy,bufExplorerMapping,bufExplorerTitle,bufExplorerSortType,bufExplorerToggleSplit,bufExplorerToggleOpen
+    syn match bufExplorerOpenIn       "Open in \w\+ window" contained
+    syn match bufExplorerSplit        "\w\+ split" contained
+    syn match bufExplorerSortBy       "Sorted by .*" contained contains=bufExplorerOpenIn,bufExplorerSplit
+    syn match bufExplorerMapping      "\" \zs.\+\ze :" contained
+    syn match bufExplorerTitle        "Buffer Explorer.*" contained
+    syn match bufExplorerSortType     "'\w\{-}'" contained
+    syn match bufExplorerBufNbr       /^\s*\d\+/
     syn match bufExplorerToggleSplit  "toggle split type" contained
     syn match bufExplorerToggleOpen   "toggle open mode" contained
-
-    syn match bufExplorerModBuf    /^\s*\d\+.\{4}+.*/
-    syn match bufExplorerLockedBuf /^\s*\d\+.\{3}[\-=].*/
-    syn match bufExplorerHidBuf    /^\s*\d\+.\{2}h.*/
-    syn match bufExplorerActBuf    /^\s*\d\+.\{2}a.*/
-    syn match bufExplorerCurBuf    /^\s*\d\+.%.*/
-    syn match bufExplorerAltBuf    /^\s*\d\+.#.*/
-    syn match bufExplorerUnlBuf    /^\s*\d\+u.*/
+    syn match bufExplorerModBuf       /^\s*\d\+.\{4}+.*/
+    syn match bufExplorerLockedBuf    /^\s*\d\+.\{3}[\-=].*/
+    syn match bufExplorerHidBuf       /^\s*\d\+.\{2}h.*/
+    syn match bufExplorerActBuf       /^\s*\d\+.\{2}a.*/
+    syn match bufExplorerCurBuf       /^\s*\d\+.%.*/
+    syn match bufExplorerAltBuf       /^\s*\d\+.#.*/
+    syn match bufExplorerUnlBuf       /^\s*\d\+u.*/
 
     hi def link bufExplorerBufNbr Number
     hi def link bufExplorerMapping NonText
@@ -364,19 +503,21 @@ function s:SetupSyntax()
   endif
 endfunction
 
-" ToggleHelp {{{1
-function s:ToggleHelp()
+" BEToggleHelp {{{1
+function! s:BEToggleHelp()
   let g:bufExplorerDetailedHelp = !g:bufExplorerDetailedHelp
 
   setlocal modifiable
-                                " Save position.
+
+  " Save position.
   normal! ma
-                                " Remove old header.
+
+  " Remove old header.
   if (s:firstBufferLine > 1)
     exec "keepjumps 1,".(s:firstBufferLine - 1) "d _"
   endif
 
-  call append(0, s:CreateHelp())
+  call append(0, s:BECreateHelp())
 
   silent! normal! g`a
   delmarks a
@@ -385,22 +526,24 @@ function s:ToggleHelp()
 
   if exists("b:displayMode") && b:displayMode == "winmanager"
     call WinManagerForceReSize("BufExplorer")
-  end
+  endif
 endfunction
 
-" GetHelpStatus {{{1
-function s:GetHelpStatus()
+" BEGetHelpStatus {{{1
+function! s:BEGetHelpStatus()
   let ret = '" Sorted by '.((g:bufExplorerReverseSort == 1) ? "reverse " : "").g:bufExplorerSortBy
   let ret .= ' | '.((g:bufExplorerFindActive == 0) ? "Don't " : "")."Locate buffer"
   let ret .= ((g:bufExplorerShowUnlisted == 0) ? "" : " | Show unlisted")
+  let ret .= ((g:bufExplorerShowTabBuffer == 0) ? "" : " | Show buffers/tab")
+  let ret .= ((g:bufExplorerOnlyOneTab == 1) ? "" : " | One tab / buffer")
   let ret .= ' | '.((g:bufExplorerShowRelativePath == 0) ? "Absolute" : "Relative")
   let ret .= ' '.((g:bufExplorerSplitOutPathName == 0) ? "Full" : "Split")." path"
 
   return ret
 endfunction
 
-" CreateHelp {{{1
-function s:CreateHelp()
+" BECreateHelp {{{1
+function! s:BECreateHelp()
   if g:bufExplorerDefaultHelp == 0 && g:bufExplorerDetailedHelp == 0
     let s:firstBufferLine = 1
     return []
@@ -412,35 +555,45 @@ function s:CreateHelp()
     call add(header, '" Buffer Explorer ('.g:bufexplorer_version.')')
     call add(header, '" --------------------------')
     call add(header, '" <F1> : toggle this help')
-    call add(header, '" <enter> or Mouse-Double-Click : open buffer under cursor')
+    call add(header, '" <enter> or o or Mouse-Double-Click : open buffer under cursor')
     call add(header, '" <shift-enter> or t : open buffer in another tab')
-    call add(header, '" d : wipe buffer')
-    call add(header, '" D : delete buffer')
+    call add(header, '" d : delete buffer')
+    call add(header, '" D : wipe buffer')
+    call add(header, '" f : toggle find active buffer')
     call add(header, '" p : toggle spliting of file and path name')
     call add(header, '" q : quit')
     call add(header, '" r : reverse sort')
     call add(header, '" R : toggle showing relative or full paths')
+    call add(header, '" s : cycle thru "sort by" fields '.string(s:sort_by).'')
+    call add(header, '" S : reverse cycle thru "sort by" fields')
+    call add(header, '" T : toggle if to show only buffers for this tab or not')
     call add(header, '" u : toggle showing unlisted buffers')
-    call add(header, '" s : select sort field '.string(s:sort_by).'')
-    call add(header, '" f : toggle find active buffer')
   else
     call add(header, '" Press <F1> for Help')
   endif
 
-  call add(header, s:GetHelpStatus())
-  call add(header, '"=')
+  if (!exists("b:displayMode") || b:displayMode != "winmanager") || (b:displayMode == "winmanager" && g:bufExplorerDetailedHelp == 1)
+    call add(header, s:BEGetHelpStatus())
+    call add(header, '"=')
+  endif
 
   let s:firstBufferLine = len(header) + 1
 
   return header
 endfunction
 
-" GetBufferInfo {{{1
-function s:GetBufferInfo()
+" BEGetBufferInfo {{{1
+function! s:BEGetBufferInfo(bufnr)
   redir => bufoutput
   buffers!
   redir END
 
+  if (a:bufnr > 0)
+    " Since we are only interested in this specified buffer 
+    " remove the other buffers listed
+    let bufoutput = substitute(bufoutput."\n", '^.*\n\(\s*'.a:bufnr.'\>.\{-}\)\n.*', '\1', '')
+  endif
+
   let [all, allwidths, listedwidths] = [[], {}, {}]
 
   for n in keys(s:types)
@@ -458,7 +611,7 @@ function s:GetBufferInfo()
 
     if getftype(b.fullname) == "dir" && g:bufExplorerShowDirectories == 1
       let b.shortname = "<DIRECTORY>"
-    end
+    endif
 
     call add(all, b)
 
@@ -478,54 +631,74 @@ function s:GetBufferInfo()
     let s:listedpads[n] = repeat(' ', max(listedwidths[n]))
   endfor
 
+  let s:refreshBufferList = 1
+
   return all
 endfunction
 
-" BuildBufferList {{{1
-function s:BuildBufferList()
-  let lines = []
-                                " Loop through every buffer.
-  for buf in s:raw_buffer_listing
-    if (!g:bufExplorerShowUnlisted && buf.attributes =~ "u")
-                                " Skip unlisted buffers if we are not to show them.
-      continue
-    endif
+" BEBuildBufferList {{{1
+function! s:BEBuildBufferList()
+    let lines = []
 
-    let line = buf.attributes." "
+    " Loop through every buffer.
+    for buf in s:raw_buffer_listing
+        " Skip unlisted buffers if we are not to show them.
+        if (!g:bufExplorerShowUnlisted && buf.attributes =~ "u")
+            continue
+        endif
 
-    if g:bufExplorerSplitOutPathName
-      let type = (g:bufExplorerShowRelativePath) ? "relativepath" : "path"
-      let path = buf[type]
-      let pad  = (g:bufExplorerShowUnlisted) ? s:allpads.shortname : s:listedpads.shortname
-      let line .= buf.shortname." ".strpart(pad.path, len(buf.shortname))
-    else
-      let type = (g:bufExplorerShowRelativePath) ? "relativename" : "fullname"
-      let path = buf[type]
-      let line .= path
-    endif
+        if (g:bufExplorerShowTabBuffer)
+            let show_buffer = 0
 
-    let pads = (g:bufExplorerShowUnlisted) ? s:allpads : s:listedpads
+            for bufnr in s:tabSpace[tabpagenr()]
+                if (buf.attributes =~ '^\s*'.bufnr.'\>')
+                    " Only buffers shown on the current tabpagenr
+                    let show_buffer = 1
+                    break
+                endif
+            endfor
 
-    if !empty(pads[type])
-      let line .= strpart(pads[type], len(path))." "
-    endif
+            if show_buffer == 0 
+                continue
+            endif
+        endif
 
-    let line .= buf.line
+        let line = buf.attributes." "
 
-    call add(lines, line)
-  endfor
+        if g:bufExplorerSplitOutPathName
+            let type = (g:bufExplorerShowRelativePath) ? "relativepath" : "path"
+            let path = buf[type]
+            let pad  = (g:bufExplorerShowUnlisted) ? s:allpads.shortname : s:listedpads.shortname
+            let line .= buf.shortname." ".strpart(pad.path, len(buf.shortname))
+        else
+            let type = (g:bufExplorerShowRelativePath) ? "relativename" : "fullname"
+            let path = buf[type]
+            let line .= path
+        endif
+
+        let pads = (g:bufExplorerShowUnlisted) ? s:allpads : s:listedpads
+
+        if !empty(pads[type])
+            let line .= strpart(pads[type], len(path))." "
+        endif
 
-  call setline(s:firstBufferLine, lines)
+        let line .= buf.line
 
-  call s:SortListing()
+        call add(lines, line)
+    endfor
+
+    call setline(s:firstBufferLine, lines)
+
+    call s:BESortListing()
 endfunction
 
-" SelectBuffer {{{1
-function s:SelectBuffer(...)
-                                " Sometimes messages are not cleared when we get here so it looks like an error has
-                                " occurred when it really has not.
+" BESelectBuffer {{{1
+function! s:BESelectBuffer(...)
+  " Sometimes messages are not cleared when we get here so it looks like an error has
+  " occurred when it really has not.
   echo ""
-                                " Are we on a line with a file name?
+
+  " Are we on a line with a file name?
   if line('.') < s:firstBufferLine
     exec "normal! \<cr>"
     return
@@ -533,6 +706,7 @@ function s:SelectBuffer(...)
 
   let _bufNbr = str2nr(getline('.'))
 
+  " Check and see if we are running BE via WinManager.
   if exists("b:displayMode") && b:displayMode == "winmanager"
     let bufname = expand("#"._bufNbr.":p")
 
@@ -543,215 +717,308 @@ function s:SelectBuffer(...)
     endif
  
     return
-  end
+  endif
 
   if bufexists(_bufNbr)
-    if bufnr("#") == _bufNbr
-      return s:Close()
+    if bufnr("#") == _bufNbr && !exists("g:bufExplorerChgWin")
+      return s:BEClose("")
     endif
 
+    " Are we suppose to open the selected buffer in a tab?
     if (a:0 == 1) && (a:1 == "tab")
-                                " Restore [BufExplorer] buffer.
+      " Yes, we are to open the selected buffer in a tab.
+
+      " Restore [BufExplorer] buffer.
       exec "keepjumps silent buffer!".s:originBuffer
 
-      let tabNbr = s:GetTabNbr(_bufNbr)
+      " Get the tab number where this buffer is located at.
+      let tabNbr = s:BEGetTabNbr(_bufNbr)
 
+      " Was the tab found?
       if tabNbr == 0
-                                " _bufNbr is not opened in any tabs. Open a new tab with the selected buffer in it.
+        " _bufNbr is not opened in any tabs. Open a new tab with the selected buffer in it.
         exec "999tab split +buffer" . _bufNbr
       else
-                                " The _bufNbr is already opened in tab(s), go to that tab.
+        " The _bufNbr is already opened in tab, go to that tab.
         exec tabNbr . "tabnext"
-                                " Focus window.
-        exec s:GetWinNbr(tabNbr, _bufNbr) . "wincmd w"
+
+        " Focus window.
+        exec s:BEGetWinNbr(tabNbr, _bufNbr) . "wincmd w"
       endif
     else
-      if bufloaded(_bufNbr) && g:bufExplorerFindActive
-        call s:Close()
+        "No, the use did not ask to open the selected buffer in a tab.
+
+        " Are we suppose to move to the tab where this active buffer is?
+        if exists("g:bufExplorerChgWin")
+               exe g:bufExplorerChgWin."wincmd w"
+           elseif bufloaded(_bufNbr) && g:bufExplorerFindActive
+            " Close the BE window.
+            call s:BEClose("")
 
-        let tabNbr = s:GetTabNbr(_bufNbr)
+        " Get the tab number where this buffer is located at.
+        let tabNbr = s:BEGetTabNbr(_bufNbr)
 
+        " Was the tab found?
         if tabNbr != 0
-                                " The buffer is located in a tab. Go to that tab number.
+          " The buffer is located in a tab. Go to that tab number.
           exec tabNbr . "tabnext"
         else
+          " Nope, the buffer is not in a tab, simple switch to that buffer.
           let bufname = expand("#"._bufNbr.":p")
           exec bufname ? "drop ".escape(bufname, " ") : "buffer "._bufNbr
         endif
       endif
-                                " Switch to the buffer.
+
+      " Switch to the buffer.
       exec "keepalt keepjumps silent b!" _bufNbr
     endif
-                                " Make the buffer 'listed' again.
+
+    " Make the buffer 'listed' again.
     call setbufvar(_bufNbr, "&buflisted", "1")
+       " call any associated function references
+       " g:bufExplorerFuncRef may be an individual function reference
+       "                or it may be a list containing function references.
+       " It will ignore anything that's not a function reference.
+       " See  :help FuncRef  for more on function references.
+       if exists("g:BufExplorerFuncRef")
+         if type(g:BufExplorerFuncRef) == 2
+           keepj call g:BufExplorerFuncRef()
+         elseif type(g:BufExplorerFuncRef) == 3
+           for FncRef in g:BufExplorerFuncRef
+             if type(FncRef) == 2
+                   keepj call FncRef()
+             endif
+           endfor
+         endif
+    endif
   else
-    call s:Error("Sorry, that buffer no longer exists, please select another")
-    call s:DeleteBuffer(_bufNbr, "wipe")
+    call s:BEError("Sorry, that buffer no longer exists, please select another")
+    call s:BEDeleteBuffer(_bufNbr, "wipe")
   endif
 endfunction
 
-" RemoveBuffer {{{1
-function s:RemoveBuffer(mode)
-                                " Are we on a line with a file name?
-  if line('.') < s:firstBufferLine
-    return
-  endif
-                                " Do not allow this buffer to be deleted if it is the last one.
-  if len(s:MRUList) == 1
-    call s:Error("Sorry, you are not allowed to delete the last buffer")
-    return
-  endif
-                                " These commands are to temporarily suspend the activity of winmanager.
-  if exists("b:displayMode") && b:displayMode == "winmanager"
-    call WinManagerSuspendAUs()
-  end
+" BEDeleteBufferListing {{{1
+function! s:BEDeleteBufferListing(buf)
+    if exists('s:raw_buffer_listing') && !empty(s:raw_buffer_listing)
+        " Delete the buffer from the raw buffer list.
+        " Careful use of ' and " so we do not have to escape all the \'s
+        " Regex: ^\s*\(10\|20\)\>
+        "        ^ - Starting at the beginning of the string
+        "        \s* - optional whitespace
+        "        \(10\|20\) - either a 10 or a 20
+        "        \> - end of word (so it can't make 100 or 201)
+        call filter(s:raw_buffer_listing, "v:val.attributes !~ '".'^\s*\('.substitute(a:buf, ' ', '\\|', 'g').'\)\>'."'")
+    endif
+endfunction
 
-  let _bufNbr = str2nr(getline('.'))
+" BERemoveBuffer {{{1
+function! s:BERemoveBuffer(type, mode) range
+    " Are we on a line with a file name?
+    if line('.') < s:firstBufferLine
+        return
+    endif
 
-  if getbufvar(_bufNbr, '&modified') == 1
-    call s:Error("Sorry, no write since last change for buffer "._bufNbr.", unable to delete")
-    return
-  else
-                                " Okay, everything is good, delete or wipe the buffer.
-    call s:DeleteBuffer(_bufNbr, a:mode)
-  endif
-                                " Reactivate winmanager autocommand activity.
-  if exists("b:displayMode") && b:displayMode == "winmanager"
-    call WinManagerForceReSize("BufExplorer")
-    call WinManagerResumeAUs()
-  end
+    " These commands are to temporarily suspend the activity of winmanager.
+    if exists("b:displayMode") && b:displayMode == "winmanager"
+        call WinManagerSuspendAUs()
+    endif
+
+    let _bufNbrs = ''
+
+    for lineNum in range(a:firstline, a:lastline)
+        let line = getline(lineNum)
+
+        if line =~ '^\s*\(\d\+\)'
+            " Regex: ^\s*\(10\|20\)\>
+            "        ^ - Starting at the beginning of the string
+            "        \s* - optional whitespace
+            "        \zs - start the match here
+            "        \d\+ - any digits
+            "        \> - end of word (so it can't make 100 or 201)
+            let bufNbr = matchstr(line, '^\s*\zs\d\+\>')
+
+            " Add 0 to bufNbr to ensure Vim treats it as a Number
+            " for use with the getbufvar() function
+            if bufNbr !~ '^\d\+$' || getbufvar(bufNbr+0, '&modified') != 0
+                call s:BEError("Sorry, no write since last change for buffer ".bufNbr.", unable to delete")
+            else
+                let _bufNbrs = _bufNbrs . (_bufNbrs==''?'':' '). bufNbr 
+            endif
+        endif
+    endfor
+
+    " Okay, everything is good, delete or wipe the buffers.
+    call s:BEDeleteBuffer(_bufNbrs, a:type)
+
+    " Reactivate winmanager autocommand activity.
+    if exists("b:displayMode") && b:displayMode == "winmanager"
+        call WinManagerForceReSize("BufExplorer")
+        call WinManagerResumeAUs()
+    endif
 endfunction
 
-" DeleteBuffer {{{1
-function s:DeleteBuffer(buf, mode)
-                                " This routine assumes that the buffer to be removed is on the current line.
-  try
-    if a:mode == "wipe"
-      exe "silent bw" a:buf
+" BEDeleteBuffer {{{1
+function! s:BEDeleteBuffer(bufNbr, mode)
+    " This routine assumes that the buffer to be removed is on the current line.
+    try
+        if a:mode == "wipe"
+            exe "bwipe" a:bufNbr
+        else
+            exe "bdelete" a:bufNbr
+        endif
+
+        setlocal modifiable
+
+        " Remove each of the lines beginning with the buffer numbers we are removing
+        " Regex: ^\s*\(10\|20\)\>
+        "        ^ - Starting at the beginning of the string
+        "        \s* - optional whitespace
+        "        \(10\|20\) - either a 10 or a 20
+        "        \> - end of word (so it can't make 100 or 201)
+        exec 'silent! g/^\s*\('.substitute(a:bufNbr, ' ', '\\|', 'g').'\)\>/d_'
+
+        setlocal nomodifiable
+
+        call s:BEDeleteBufferListing(a:bufNbr)
+    catch
+        call s:BEError(v:exception)
+    endtry
+endfunction
+
+" BEClose {{{1
+function! s:BEClose(mode)
+    " Get only the listed buffers.
+    let listed = filter(copy(s:MRUList), "buflisted(v:val)")
+
+    " If we needed to split the main window, close the split one.
+"  if (s:splitMode)
+"  if (s:splitMode != "")
+    if (s:splitMode != "" && a:mode == "quit")
+        exec "wincmd c"
+    endif
+
+    if len(listed) == 0
+        exe "enew"
     else
-      exe "silent bd" a:buf
-    end
+        for b in reverse(listed[0:1])
+            exec "keepjumps silent b ".b
+        endfor
+    endif
+endfunction
 
-    setlocal modifiable
-    normal! "_dd
-    setlocal nomodifiable
-                                " Delete the buffer from the raw buffer list.
-    call filter(s:raw_buffer_listing, 'v:val.attributes !~ " '.a:buf.' "')
-  catch
-    call s:Error(v:exception)
-  endtry
-endfunction
-
-" Close {{{1
-function s:Close()
-                                " Get only the listed buffers.
-  let listed = filter(copy(s:MRUList), "buflisted(v:val)")
-                                " If we needed to split the main window, close the split one.
-  if (s:splitMode != "")
-    exec "wincmd c"
-  end
+" BEToggleSplitOutPathName {{{1
+function! s:BEToggleSplitOutPathName()
+    let g:bufExplorerSplitOutPathName = !g:bufExplorerSplitOutPathName
+    call s:BERebuildBufferList()
+    call s:BEUpdateHelpStatus()
+endfunction
 
-  for b in reverse(listed[0:1])
-    exec "keepjumps silent b ".b
-  endfor
+" BEToggleShowRelativePath {{{1
+function! s:BEToggleShowRelativePath()
+    let g:bufExplorerShowRelativePath = !g:bufExplorerShowRelativePath
+    call s:BERebuildBufferList()
+    call s:BEUpdateHelpStatus()
 endfunction
 
-" ToggleSplitOutPathName {{{1
-function s:ToggleSplitOutPathName()
-  let g:bufExplorerSplitOutPathName = !g:bufExplorerSplitOutPathName
-  call s:RebuildBufferList()
-  call s:UpdateHelpStatus()
+" BEToggleShowUnlisted {{{1
+function! s:BEToggleShowUnlisted()
+    let g:bufExplorerShowUnlisted = !g:bufExplorerShowUnlisted
+    let num_bufs = s:BERebuildBufferList(g:bufExplorerShowUnlisted == 0)
+    call s:BEUpdateHelpStatus()
 endfunction
 
-" ToggleShowRelativePath {{{1
-function s:ToggleShowRelativePath()
-  let g:bufExplorerShowRelativePath = !g:bufExplorerShowRelativePath
-  call s:RebuildBufferList()
-  call s:UpdateHelpStatus()
+" BEToggleFindActive {{{1
+function! s:BEToggleFindActive()
+    let g:bufExplorerFindActive = !g:bufExplorerFindActive
+    call s:BEUpdateHelpStatus()
 endfunction
 
-" ToggleShowUnlisted {{{1
-function s:ToggleShowUnlisted()
-  let g:bufExplorerShowUnlisted = !g:bufExplorerShowUnlisted
-  let num_bufs = s:RebuildBufferList(g:bufExplorerShowUnlisted == 0)
-  call s:UpdateHelpStatus()
+" BEToggleShowTabBuffer {{{1
+function! s:BEToggleShowTabBuffer()
+    let g:bufExplorerShowTabBuffer = !g:bufExplorerShowTabBuffer
+    call s:BEDisplayBufferList()
 endfunction
 
-" ToggleFindActive {{{1
-function s:ToggleFindActive()
-  let g:bufExplorerFindActive = !g:bufExplorerFindActive
-  call s:UpdateHelpStatus()
+" BEToggleOnlyOneTab {{{1
+function! s:BEToggleOnlyOneTab()
+    let g:bufExplorerOnlyOneTab = !g:bufExplorerOnlyOneTab
+    call s:BEDisplayBufferList()
 endfunction
 
-" RebuildBufferList {{{1
-function s:RebuildBufferList(...)
-  setlocal modifiable
+" BERebuildBufferList {{{1
+function! s:BERebuildBufferList(...)
+    setlocal modifiable
 
-  let curPos = getpos('.')
+    let curPos = getpos('.')
 
-  if a:0
-    " Clear the list first.
-    exec "keepjumps ".s:firstBufferLine.',$d "_'
-  endif
+    if a:0
+        " Clear the list first.
+        exec "keepjumps ".s:firstBufferLine.',$d "_'
+    endif
 
-  let num_bufs = s:BuildBufferList()
+    let num_bufs = s:BEBuildBufferList()
 
-  call setpos('.', curPos)
+    call setpos('.', curPos)
 
-  setlocal nomodifiable
+    setlocal nomodifiable
 
-  return num_bufs
+    return num_bufs
 endfunction
 
-" UpdateHelpStatus {{{1
-function s:UpdateHelpStatus()
-  setlocal modifiable
+" BEUpdateHelpStatus {{{1
+function! s:BEUpdateHelpStatus()
+    setlocal modifiable
 
-  let text = s:GetHelpStatus()
-  call setline(s:firstBufferLine - 2, text)
+    let text = s:BEGetHelpStatus()
+    call setline(s:firstBufferLine - 2, text)
 
-  setlocal nomodifiable
+    setlocal nomodifiable
 endfunction
 
-" MRUCmp {{{1
-function s:MRUCmp(line1, line2)
-  return index(s:MRUList, str2nr(a:line1)) - index(s:MRUList, str2nr(a:line2))
+" BEMRUCmp {{{1
+function! s:BEMRUCmp(line1, line2)
+    return index(s:MRUList, str2nr(a:line1)) - index(s:MRUList, str2nr(a:line2))
 endfunction
 
-" SortReverse {{{1
-function s:SortReverse()
-  let g:bufExplorerReverseSort = !g:bufExplorerReverseSort
-
-  call s:ReSortListing()
+" BESortReverse {{{1
+function! s:BESortReverse()
+    let g:bufExplorerReverseSort = !g:bufExplorerReverseSort
+    call s:BEReSortListing()
 endfunction
 
-" SortSelect {{{1
-function s:SortSelect()
-  let g:bufExplorerSortBy = get(s:sort_by, index(s:sort_by, g:bufExplorerSortBy) + 1, s:sort_by[0])
+" BESortSelect {{{1
+function! s:BESortSelect()
+    let g:bufExplorerSortBy = get(s:sort_by, index(s:sort_by, g:bufExplorerSortBy) + 1, s:sort_by[0])
+    call s:BEReSortListing()
+endfunction
 
-  call s:ReSortListing()
+" BEReverseSortSelect {{{1
+function! s:BEReverseSortSelect()
+    let g:bufExplorerSortBy = get(s:sort_by, (index(s:sort_by, g:bufExplorerSortBy) + len(s:sort_by) - 1) % len(s:sort_by), s:sort_by[0])
+    call s:BEReSortListing()
 endfunction
 
-" ReSortListing {{{1
-function s:ReSortListing()
-  setlocal modifiable
+" BEReSortListing {{{1
+function! s:BEReSortListing()
+    setlocal modifiable
 
-  let curPos = getpos('.')
+    let curPos = getpos('.')
 
-  call s:SortListing()
-  call s:UpdateHelpStatus()
+    call s:BESortListing()
+    call s:BEUpdateHelpStatus()
 
-  call setpos('.', curPos)
+    call setpos('.', curPos)
 
-  setlocal nomodifiable
+    setlocal nomodifiable
 endfunction
 
-" SortListing {{{1
-function s:SortListing()
+" BESortListing {{{1
+function! s:BESortListing()
   let sort = s:firstBufferLine.",$sort".((g:bufExplorerReverseSort == 1) ? "!": "")
 
   if g:bufExplorerSortBy == "number"
-                                " Easiest case.
+    " Easiest case.
     exec sort 'n'
   elseif g:bufExplorerSortBy == "name"
     if g:bufExplorerSplitOutPathName
@@ -761,7 +1028,7 @@ function s:SortListing()
     endif
   elseif g:bufExplorerSortBy == "fullpath"
     if g:bufExplorerSplitOutPathName
-                                " Sort twice - first on the file name then on the path.
+      " Sort twice - first on the file name then on the path.
       exec sort 'ir /\d.\{7}\zs\f\+\ze/'
     endif
 
@@ -771,7 +1038,7 @@ function s:SortListing()
   elseif g:bufExplorerSortBy == "mru"
     let l = getline(s:firstBufferLine, "$")
 
-    call sort(l, "<SID>MRUCmp")
+    call sort(l, "<SID>BEMRUCmp")
 
     if g:bufExplorerReverseSort
       call reverse(l)
@@ -781,67 +1048,67 @@ function s:SortListing()
   endif
 endfunction
 
-" MRUListShow {{{1
-function s:MRUListShow()
-  echomsg "MRUList=".string(s:MRUList)
+" BEMRUListShow {{{1
+function! s:BEMRUListShow()
+    echomsg "MRUList=".string(s:MRUList)
 endfunction
 
-" Error {{{1
-function s:Error(msg)
-  echohl ErrorMsg | echo a:msg | echohl none
+" BEError {{{1
+function! s:BEError(msg)
+    echohl ErrorMsg | echo a:msg | echohl none
 endfunction
 
-" Warning {{{1
-function s:Warning(msg)
-  echohl WarningMsg | echo a:msg | echohl none
+" BEWarning {{{1
+function! s:BEWarning(msg)
+    echohl WarningMsg | echo a:msg | echohl none
 endfunction
 
 " GetTabNbr {{{1
-function s:GetTabNbr(bufNbr)
-  " Searching buffer bufno, in tabs.
-  for i in range(tabpagenr("$"))
-    if index(tabpagebuflist(i + 1), a:bufNbr) != -1
-      return i + 1
-    endif
-  endfor
+function! s:BEGetTabNbr(bufNbr)
+    " Searching buffer bufno, in tabs.
+    for i in range(tabpagenr("$"))
+        if index(tabpagebuflist(i + 1), a:bufNbr) != -1
+            return i + 1
+        endif
+    endfor
 
-  return 0
+    return 0
 endfunction
 
 " GetWinNbr" {{{1
-function s:GetWinNbr(tabNbr, bufNbr)
-  " window number in tabpage.
-  return index(tabpagebuflist(a:tabNbr), a:bufNbr) + 1
+function! s:BEGetWinNbr(tabNbr, bufNbr)
+    " window number in tabpage.
+    return index(tabpagebuflist(a:tabNbr), a:bufNbr) + 1
 endfunction
 
 " Winmanager Integration {{{1
 let g:BufExplorer_title = "\[Buf\ List\]"
-call s:Set("g:bufExplorerResize", 1)
-call s:Set("g:bufExplorerMaxHeight", 25) " Handles dynamic resizing of the window.
+call s:BESet("g:bufExplorerResize", 1)
+call s:BESet("g:bufExplorerMaxHeight", 25) " Handles dynamic resizing of the window.
 
 " Function to start display. Set the mode to 'winmanager' for this buffer.
 " This is to figure out how this plugin was called. In a standalone fashion
 " or by winmanager.
-function BufExplorer_Start()
-  let b:displayMode = "winmanager"
-  call StartBufExplorer("e")
+function! BufExplorer_Start()
+    let b:displayMode = "winmanager"
+    call StartBufExplorer("e")
 endfunction
 
 " Returns whether the display is okay or not.
-function BufExplorer_IsValid()
-  return 0
+function! BufExplorer_IsValid()
+    return 0
 endfunction
 
 " Handles dynamic refreshing of the window.
-function BufExplorer_Refresh()
-  let b:displayMode = "winmanager"
-  call StartBufExplorer("e")
+function! BufExplorer_Refresh()
+    let b:displayMode = "winmanager"
+    call StartBufExplorer("e")
 endfunction
 
-function BufExplorer_ReSize()
+function! BufExplorer_ReSize()
   if !g:bufExplorerResize
     return
-  end
+  endif
 
   let nlines = min([line("$"), g:bufExplorerMaxHeight])
 
@@ -864,6 +1131,32 @@ function BufExplorer_ReSize()
 
   call setpos(".", pres)
 endfunction
+
+" Default values {{{1
+call s:BESet("g:bufExplorerDefaultHelp", 1)           " Show default help?
+call s:BESet("g:bufExplorerDetailedHelp", 0)          " Show detailed help?
+call s:BESet("g:bufExplorerFindActive", 1)            " When selecting an active buffer, take you to the window where it is active?
+call s:BESet("g:bufExplorerReverseSort", 0)           " sort reverse?
+call s:BESet("g:bufExplorerShowDirectories", 1)       " (Dir's are added by commands like ':e .')
+call s:BESet("g:bufExplorerShowRelativePath", 0)      " Show listings with relative or absolute paths?
+call s:BESet("g:bufExplorerShowUnlisted", 0)          " Show unlisted buffers?
+call s:BESet("g:bufExplorerSortBy", "mru")            " Sorting methods are in s:sort_by:
+call s:BESet("g:bufExplorerSplitOutPathName", 1)      " Split out path and file name?
+call s:BESet("g:bufExplorerSplitRight", &splitright)  " Should vertical splits be on the right or left of current window?
+call s:BESet("g:bufExplorerSplitBelow", &splitbelow)  " Should horizontal splits be below or above current window?
+call s:BESet("g:bufExplorerShowTabBuffer", 0)         " Show only buffer(s) for this tab?
+call s:BESet("g:bufExplorerOnlyOneTab", 1)            " If ShowTabBuffer = 1, only store the most recent tab for this buffer.
+
+" Global variables {{{1
+call s:BEReset()
+let s:running = 0
+let s:sort_by = ["number", "name", "fullpath", "mru", "extension"]
+let s:types = {"fullname": ':p', "path": ':p:h', "relativename": ':~:.', "relativepath": ':~:.:h', "shortname": ':t'}
+let s:originBuffer = 0
+let s:splitMode = ""
+let s:name = '[BufExplorer]'
+let s:refreshBufferList = 1
+let s:MRU_Exclude_List = ["[BufExplorer]","__MRU_Files__"]
 "1}}}
 
 " vim:ft=vim foldmethod=marker sw=2