" ============================================================================ " File: buffers.vim " Description: vim plugin that provides buffers helpers. Almost all of parts " are taken from Eclim project " Maintainer: Roman 'gryf' Dobosz " Last Change: 2010-08-28 " License: This program is free software: you can redistribute it and/or " modify it under the terms of the GNU General Public License as " published by the Free Software Foundation, either version 3 of " the License, or (at your option) any later version. " " This program is distributed in the hope that it will be useful, " but WITHOUT ANY WARRANTY; without even the implied warranty of " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " GNU General Public License for more details. " " You should have received a copy of the GNU General Public " License along with this program. If not, see " . " ============================================================================ let s:Eclim_ver = '1.6.0' " Eclim: {{{1 " files: " - plugin/eclim.vim (global vars) " - plugin/common.vim (commands) " Global Variables {{{2 if has("signs") if !exists("g:EclimSignLevel") let g:EclimSignLevel = 5 endif else let g:EclimSignLevel = 0 endif if !exists("g:EclimInfoHighlight") let g:EclimInfoHighlight = "Statement" endif if !exists("g:EclimLogLevel") let g:EclimLogLevel = 4 endif if !exists("g:EclimTraceHighlight") let g:EclimTraceHighlight = "Normal" endif if !exists("g:EclimDebugHighlight") let g:EclimDebugHighlight = "Normal" endif if !exists("g:EclimInfoHighlight") let g:EclimInfoHighlight = "Statement" endif if !exists("g:EclimWarningHighlight") let g:EclimWarningHighlight = "WarningMsg" endif if !exists("g:EclimErrorHighlight") let g:EclimErrorHighlight = "Error" endif if !exists("g:EclimFatalHighlight") let g:EclimFatalHighlight = "Error" endif if !exists("g:EclimShowCurrentError") let g:EclimShowCurrentError = 1 endif if !exists("g:EclimShowCurrentErrorBalloon") let g:EclimShowCurrentErrorBalloon = 1 endif if !exists("g:EclimOpenQFLists") let g:EclimOpenQFLists = 1 endif " }}} " Command Declarations {{{2 if !exists(":Buffers") command Buffers :call s:Buffers() endif " }}} " End Eclim: }}} " Common Buffers: {{{1 " Global Variables {{{2 if !exists('g:EclimBuffersSort') let g:EclimBuffersSort = 'file' endif if !exists('g:EclimBuffersSortDirection') let g:EclimBuffersSortDirection = 'asc' endif if !exists('g:EclimBuffersDefaultAction') let g:EclimBuffersDefaultAction = 'edit' endif if !exists('g:EclimOnlyExclude') let g:EclimOnlyExclude = \ '\(NERD_tree_*\|__Tag_List__\|command-line\)' endif " }}} " Buffers() eclim/autoload/eclim/common/buffers.vim {{{2 " Like, :buffers, but opens a temporary buffer. function! s:Buffers() redir => list silent exec 'buffers' redir END let buffers = [] let filelength = 0 for entry in split(list, '\n') let buffer = {} let buffer.status = substitute(entry, '\s*[0-9]\+\s\+\(.\{-}\)\s\+".*', '\1', '') let buffer.path = substitute(entry, '.\{-}"\(.\{-}\)".*', '\1', '') let buffer.path = fnamemodify(buffer.path, ':p') let buffer.file = fnamemodify(buffer.path, ':p:t') let buffer.dir = fnamemodify(buffer.path, ':p:h') exec 'let buffer.bufnr = ' . substitute(entry, '\s*\([0-9]\+\).*', '\1', '') exec 'let buffer.lnum = ' . \ substitute(entry, '.*"\s\+line\s\+\([0-9]\+\).*', '\1', '') call add(buffers, buffer) if len(buffer.file) > filelength let filelength = len(buffer.file) endif endfor if g:EclimBuffersSort != '' call sort(buffers, 'BufferCompare') endif let lines = [] for buffer in buffers call add(lines, s:BufferEntryToLine(buffer, filelength)) endfor call TempWindow('[buffers]', lines) let b:eclim_buffers = buffers setlocal modifiable noreadonly call append(line('$'), ['', '" use ? to view help']) setlocal nomodifiable readonly let b:eclim_buffers = buffers " syntax set ft=eclim_buffers hi link BufferActive Special hi link BufferHidden Comment syntax match BufferActive /+\?active\s\+\(\[RO\]\)\?/ syntax match BufferHidden /+\?hidden\s\+\(\[RO\]\)\?/ syntax match Comment /^".*/ " mappings nnoremap :call BufferOpen2(g:EclimBuffersDefaultAction) nnoremap E :call BufferOpen2('edit') nnoremap S :call BufferOpen2('split') nnoremap T :call BufferOpen('tablast \| tabnew') nnoremap D :call BufferDelete() " assign to buffer var to get around weird vim issue passing list containing " a string w/ a '<' in it on execution of mapping. let b:buffers_help = [ \ ' - open buffer with default action', \ 'E - open with :edit', \ 'S - open in a new split window', \ 'T - open in a new tab', \ 'D - delete the buffer', \ ] nnoremap ? \ :call BufferHelp(b:buffers_help, 'vertical', 40) "augroup eclim_buffers " autocmd! " autocmd BufAdd,BufWinEnter,BufDelete,BufWinLeave * " \ call eclim#common#buffers#BuffersUpdate() " autocmd BufUnload autocmd! eclim_buffers "augroup END endfunction " }}} " BufferCompare(buffer1, buffer2) eclim/autoload/eclim/common/buffers.vim {{{2 function! BufferCompare(buffer1, buffer2) exec 'let attr1 = a:buffer1.' . g:EclimBuffersSort exec 'let attr2 = a:buffer2.' . g:EclimBuffersSort let compare = attr1 == attr2 ? 0 : attr1 > attr2 ? 1 : -1 if g:EclimBuffersSortDirection == 'desc' let compare = 0 - compare endif return compare endfunction " }}} " s:BufferDelete() {{{2 function! s:BufferDelete() let line = line('.') if line > len(b:eclim_buffers) return endif let index = line - 1 setlocal modifiable setlocal noreadonly exec line . ',' . line . 'delete _' setlocal nomodifiable setlocal readonly let buffer = b:eclim_buffers[index] call remove(b:eclim_buffers, index) exec 'bd ' . buffer.bufnr endfunction " }}} " s:BufferEntryToLine(buffer, filelength) eclim/autoload/eclim/common/buffers.vim {{{2 function! s:BufferEntryToLine(buffer, filelength) let line = '' let line .= a:buffer.status =~ '+' ? '+' : ' ' let line .= a:buffer.status =~ 'a' ? 'active' : 'hidden' let line .= a:buffer.status =~ '[-=]' ? ' [RO] ' : ' ' let line .= a:buffer.file let pad = a:filelength - len(a:buffer.file) + 2 while pad > 0 let line .= ' ' let pad -= 1 endwhile let line .= a:buffer.dir return line endfunction " }}} " s:BufferOpen(cmd) eclim/autoload/eclim/common/buffers.vim {{{2 function! s:BufferOpen(cmd) let line = line('.') if line > len(b:eclim_buffers) return endif let file = bufname(b:eclim_buffers[line - 1].bufnr) let winnr = b:winnr close exec winnr . 'winc w' call GoToBufferWindowOrOpen(file, a:cmd) endfunction " }}} " End Common Buffers: }}} " Util: {{{1 " Script Variables eclim/autoload/eclim/util.vim {{{2 let s:buffer_write_closing_commands = '^\s*\(' . \ 'wq\|xa\|' . \ '\d*w[nN]\|\d*wp\|' . \ 'ZZ' . \ '\)' let s:bourne_shells = ['sh', 'bash', 'dash', 'ksh', 'zsh'] let s:c_shells = ['csh', 'tcsh'] let s:show_current_error_displaying = 0 " }}} " DelayedCommand(command, [delay]) eclim/autoload/eclim/util.vim {{{2 " Executes a delayed command. Useful in cases where one would expect an " autocommand event (WinEnter, etc) to fire, but doesn't, or you need a " command to execute after other autocommands have finished. " Note: Nesting is not supported. A delayed command cannot be invoke off " another delayed command. function! DelayedCommand(command, ...) let uid = fnamemodify(tempname(), ':t:r') if &updatetime > 1 exec 'let g:eclim_updatetime_save' . uid . ' = &updatetime' endif exec 'let g:eclim_delayed_command' . uid . ' = a:command' let &updatetime = len(a:000) ? a:000[0] : 1 exec 'augroup delayed_command' . uid exec 'autocmd CursorHold * ' . \ ' if exists("g:eclim_updatetime_save' . uid . '") | ' . \ ' let &updatetime = g:eclim_updatetime_save' . uid . ' | ' . \ ' unlet g:eclim_updatetime_save' . uid . ' | ' . \ ' endif | ' . \ ' exec g:eclim_delayed_command' . uid . ' | ' . \ ' unlet g:eclim_delayed_command' . uid . ' | ' . \ ' autocmd! delayed_command' . uid exec 'augroup END' endfunction " }}} " EscapeBufferName(name) eclim/autoload/eclim/util.vim {{{2 " Escapes the supplied buffer name so that it can be safely used by buf* " functions. function! EscapeBufferName(name) let name = a:name " escaping the space in cygwin could lead to the dos path error message that " cygwin throws when a dos path is referenced. if !has('win32unix') let name = escape(a:name, ' ') endif return substitute(name, '\(.\{-}\)\[\(.\{-}\)\]\(.\{-}\)', '\1[[]\2[]]\3', 'g') endfunction " }}} " GoToBufferWindow(buf) eclim/autoload/eclim/util.vim {{{2 " Focuses the window containing the supplied buffer name or buffer number. " Returns 1 if the window was found, 0 otherwise. function! GoToBufferWindow(buf) if type(a:buf) == 0 let winnr = bufwinnr(a:buf) else let name = EscapeBufferName(a:buf) let winnr = bufwinnr(bufnr('^' . name)) endif if winnr != -1 exec winnr . "winc w" call DelayedCommand('doautocmd WinEnter') return 1 endif return 0 endfunction " }}} " GoToBufferWindowOrOpen(name, cmd) eclim/autoload/eclim/util.vim {{{2 " Gives focus to the window containing the buffer for the supplied file, or if " none, opens the file using the supplied command. function! GoToBufferWindowOrOpen(name, cmd) let name = EscapeBufferName(a:name) let winnr = bufwinnr(bufnr('^' . name)) if winnr != -1 exec winnr . "winc w" call DelayedCommand('doautocmd WinEnter') else let cmd = a:cmd " if splitting and the buffer is a unamed empty buffer, then switch to an " edit. if cmd == 'split' && expand('%') == '' && \ !&modified && line('$') == 1 && getline(1) == '' let cmd = 'edit' endif silent exec cmd . ' ' . escape(Simplify(a:name), ' ') endif endfunction " }}} " GoToBufferWindowRegister(buf) eclim/autoload/eclim/util.vim {{{2 " Registers the autocmd for returning the user to the supplied buffer when the " current buffer is closed. function! GoToBufferWindowRegister(buf) exec 'autocmd BufWinLeave ' . \ 'call GoToBufferWindow("' . escape(a:buf, '\') . '") | ' . \ 'doautocmd BufEnter' endfunction " }}} " Simplify(file) eclim/autoload/eclim/util.vim {{{2 " Simply the supplied file to the shortest valid name. function! Simplify(file) let file = a:file " Don't run simplify on url files, it will screw them up. if file !~ '://' let file = simplify(file) endif " replace all '\' chars with '/' except those escaping spaces. let file = substitute(file, '\\\([^[:space:]]\)', '/\1', 'g') let cwd = substitute(getcwd(), '\', '/', 'g') if cwd !~ '/$' let cwd .= '/' endif if file =~ '^' . cwd let file = substitute(file, '^' . cwd, '', '') endif return file endfunction " }}} " TempWindow(name, lines, [readonly]) eclim/autoload/eclim/util.vim {{{2 " Opens a temp window w/ the given name and contents which is readonly unless " specified otherwise. function! TempWindow(name, lines, ...) let filename = expand('%:p') let winnr = winnr() call TempWindowClear(a:name) let name = EscapeBufferName(a:name) if bufwinnr(name) == -1 silent! noautocmd exec "botright 10sview " . escape(a:name, ' ') let b:eclim_temp_window = 1 setlocal nowrap setlocal winfixheight setlocal noswapfile setlocal nobuflisted setlocal buftype=nofile setlocal bufhidden=delete else exec bufwinnr(name) . "winc w" endif setlocal modifiable setlocal noreadonly call append(1, a:lines) retab silent 1,1delete _ if len(a:000) == 0 || a:000[0] setlocal nomodified setlocal nomodifiable setlocal readonly endif silent doautocmd BufEnter " Store filename and window number so that plugins can use it if necessary. if filename != expand('%:p') let b:filename = filename let b:winnr = winnr augroup eclim_temp_window autocmd! BufWinLeave call GoToBufferWindowRegister(b:filename) augroup END endif endfunction " }}} " TempWindowClear(name) eclim/autoload/eclim/util.vim {{{2 " Clears the contents of the temp window with the given name. function! TempWindowClear(name) let name = EscapeBufferName(a:name) if bufwinnr(name) != -1 let curwinnr = winnr() exec bufwinnr(name) . "winc w" setlocal modifiable setlocal noreadonly silent 1,$delete _ exec curwinnr . "winc w" endif endfunction " }}} " End Util: }}} " Eclim Help: {{{1 " BufferHelp(lines, orientation, size) eclim/autoload/eclim/help.vim {{{ " Function to display a help window for the current buffer. function! BufferHelp(lines, orientation, size) let orig_bufnr = bufnr('%') let name = expand('%') if name =~ '^\W.*\W$' let name = name[:-2] . ' Help' . name[len(name) - 1] else let name .= ' Help' endif let bname = EscapeBufferName(name) let orient = a:orientation == 'vertical' ? 'v' : '' if bufwinnr(bname) != -1 exec 'bd ' . bufnr(bname) return endif silent! noautocmd exec a:size . orient . "new " . escape(name, ' ') let b:eclim_temp_window = 1 setlocal nowrap winfixheight setlocal noswapfile nobuflisted nonumber setlocal buftype=nofile bufhidden=delete nnoremap ? :bd setlocal modifiable noreadonly silent 1,$delete _ call append(1, a:lines) retab silent 1,1delete _ if len(a:000) == 0 || a:000[0] setlocal nomodified nomodifiable readonly endif let help_bufnr = bufnr('%') augroup eclim_help_buffer autocmd! BufWinLeave autocmd BufWinLeave nested autocmd! eclim_help_buffer * exec 'autocmd BufWinLeave nested ' . \ 'autocmd! eclim_help_buffer * ' exec 'autocmd! BufWinLeave ' exec 'autocmd BufWinLeave nested bd ' . help_bufnr augroup END return help_bufnr endfunction " }}} " }}} " Gryfs Mods: {{{ " s:BufferOpen2(cmd) (gryf) {{{2 function! s:BufferOpen2(cmd) let line = line('.') if line > len(b:eclim_buffers) return endif let bufnr = b:eclim_buffers[line - 1].bufnr let winnr = b:winnr close exec winnr . 'winc w' call s:GoToBufferWindowOrOpen2(bufnr, a:cmd) endfunction " }}} " GoToBufferWindowOrOpen2(nr, cmd) (gryf) {{{2 " modified function GoToBufferWindowOrOpen. instead of buffer name it accepts " buffer number. function! s:GoToBufferWindowOrOpen2(nr, cmd) let winnr = bufwinnr(a:nr) if winnr != -1 exec winnr . "winc w" call DelayedCommand('doautocmd WinEnter') else if a:cmd == 'edit' silent exec 'buffer ' . a:nr elseif a:cmd == 'split' silent exec 'sbuffer ' . a:nr endif endif endfunction " }}} " End Gryfs Mods: }}} " vim:ft=vim:fdm=marker