2009-12-08 11 views
27

Qualcuno sa come chiudere un buffer in VIM quando si usa NERDTree senza rovinare tutte le finestre? L'albero NERD normalmente suddivide il tuo schermo in due finestre verticali (il browser alla tua sinistra e poi la tua finestra principale sulla destra). Se chiudi un buffer, sei ridotto a una finestra di navigazione di file giganti. Se selezioni un altro file, allora apre una seconda finestra ma la separa orizzontalmente. Qualche idea?VIM e NERD Tree - chiusura di un buffer correttamente

risposta

12

Non utilizzo Albero NERD, ma se ho capito bene, si desidera chiudere un buffer senza chiudere una finestra. Se il mio ragionamento è corretto, prova questo script.

" Delete buffer while keeping window layout (don't close buffer's windows). 
" Version 2008-11-18 from http://vim.wikia.com/wiki/VimTip165 
if v:version < 700 || exists('loaded_bclose') || &cp 
finish 
endif 
let loaded_bclose = 1 
if !exists('bclose_multiple') 
let bclose_multiple = 1 
endif 

" Display an error message. 
function! s:Warn(msg) 
echohl ErrorMsg 
echomsg a:msg 
echohl NONE 
endfunction 

" Command ':Bclose' executes ':bd' to delete buffer in current window. 
" The window will show the alternate buffer (Ctrl-^) if it exists, 
" or the previous buffer (:bp), or a blank buffer if no previous. 
" Command ':Bclose!' is the same, but executes ':bd!' (discard changes). 
" An optional argument can specify which buffer to close (name or number). 
function! s:Bclose(bang, buffer) 
if empty(a:buffer) 
let btarget = bufnr('%') 
elseif a:buffer =~ '^\d\+$' 
let btarget = bufnr(str2nr(a:buffer)) 
else 
let btarget = bufnr(a:buffer) 
endif 
if btarget < 0 
call s:Warn('No matching buffer for '.a:buffer) 
return 
endif 
if empty(a:bang) && getbufvar(btarget, '&modified') 
call s:Warn('No write since last change for buffer '.btarget.' (use :Bclose!)') 
return 
endif 
" Numbers of windows that view target buffer which we will delete. 
let wnums = filter(range(1, winnr('$')), 'winbufnr(v:val) == btarget') 
if !g:bclose_multiple && len(wnums) > 1 
call s:Warn('Buffer is in multiple windows (use ":let bclose_multiple=1")') 
return 
endif 
let wcurrent = winnr() 
for w in wnums 
execute w.'wincmd w' 
let prevbuf = bufnr('#') 
if prevbuf > 0 && buflisted(prevbuf) && prevbuf != w 
buffer # 
else 
bprevious 
endif 
if btarget == bufnr('%') 
" Numbers of listed buffers which are not the target to be deleted. 
let blisted = filter(range(1, bufnr('$')), 'buflisted(v:val) && v:val != btarget') 
" Listed, not target, and not displayed. 
let bhidden = filter(copy(blisted), 'bufwinnr(v:val) < 0') 
" Take the first buffer, if any (could be more intelligent). 
let bjump = (bhidden + blisted + [-1])[0] 
if bjump > 0 
execute 'buffer '.bjump 
else 
execute 'enew'.a:bang 
endif 
endif 
endfor 
execute 'bdelete'.a:bang.' '.btarget 
execute wcurrent.'wincmd w' 
endfunction 
command! -bang -complete=buffer -nargs=? Bclose call <SID>Bclose('<bang>', '<args>') 
nnoremap <silent> <Leader>bd :Bclose<CR> 
nnoremap <silent> <Leader>bD :Bclose!<CR> 
+0

impressionante ... questo è esattamente quello che stavo cercando per –

+0

thakns, funziona alla grande - e utile non solo per NERDTree! – nihique

5

:bd lavora per me a Vim 7.3 e NERDTree 4.1.0.

+0

Sì, ho appena aggiornato MacVim alla 7.3, ora funziona anche per me. – mxgrn

+2

Hm, sono su Vim 7.3 e NERDTree 4.1 su Ubuntu 12.04 e ho ancora il problema dell'OP. – Milimetric

+0

Non funziona per me su Vim 7.4, NERDTree 4.2.0 su un computer Windows 7. – Juan

8

Anche il plug-in bufkill sembra risolvere questo problema.

22

Prova questa mappatura: nnoremap <leader>q :bp<cr>:bd #<cr>

+0

Funziona alla grande e così semplice :) – newUserNameHere

+0

Soluzione assolutamente stupenda. Era sulla punta della mia lingua. – cbartondock