2010-07-01 15 views
82

Suponiendo que tengo varios archivos abiertos como almacenamientos intermedios en Vim. Los archivos tienen *.cpp, *.h y algunos son *.xml. Quiero cerrar todos los archivos XML con :bd *.xml. Sin embargo, Vim no permite esto (E93: más de un partido ...).¿Cómo eliminar múltiples búferes en Vim?

¿Hay alguna manera de hacer esto?

P.S. Sé que :bd file1 file2 file3 funciona. Entonces, ¿puedo de alguna manera evaluar *.xml a file1.xml file2.xml file3.xml?

Respuesta

131

puede utilizar <C-a> para completar todos los partidos. Así que si escribe :bd *.xml y luego pulsa <C-a>, vim completará el comando para :bd file1.xml file2.xml file3.xml.

+3

¡Impresionante! No se necesitan complementos :) Gracias. – Salil

+0

tan impresionante. ¡Gracias! – tester

+3

o '' en lugar de '', también funciona. – Florian

4

Puede usar esto.

:exe 'bd '. join(filter(map(copy(range(1, bufnr('$'))), 'bufname(v:val)'), 'v:val =~ "\.xml$"'), ' ') 

Debería ser bastante fácil agregarlo a un comando.

function! s:BDExt(ext) 
    let buffers = filter(range(1, bufnr('$')), 'buflisted(v:val) && bufname(v:val) =~ "\.'.a:ext.'$"') 
    if empty(buffers) |throw "no *.".a:ext." buffer" | endif 
    exe 'bd '.join(buffers, ' ') 
endfunction 

command! -nargs=1 BDExt :call s:BDExt(<f-args>) 
+0

No sé casi nada sobre Vimscript, pero ¿qué hay de la función glob()? –

+1

'glob()' solo le proporcionará los archivos existentes (en su disco duro) y los búferes no abiertos. –

+0

Olvidó los nombres de buffer 'fnameescape()'. – ZyX

4

Pruebe la secuencia de comandos siguiente. El ejemplo es para "txt", cámbielo según sea necesario, p. a "xml". Los búferes modificados no se eliminan. Presione \ bd para eliminar los búferes.

map <Leader>bd :bufdo call <SID>DeleteBufferByExtension("txt") 

function! <SID>DeleteBufferByExtension(strExt) 
    if (matchstr(bufname("%"), ".".a:strExt."$") == ".".a:strExt) 
     if (! &modified) 
     bd 
     endif 
    endif 
endfunction 

[Editar] mismo sin: bufdo (conforme a lo solicitado por Luc Hermitte, véase el comentario a continuación)

map <Leader>bd :call <SID>DeleteBufferByExtension("txt") 

function! <SID>DeleteBufferByExtension(strExt) 
    let s:bufNr = bufnr("$") 
    while s:bufNr > 0 
     if buflisted(s:bufNr) 
      if (matchstr(bufname(s:bufNr), ".".a:strExt."$") == ".".a:strExt) 
       if getbufvar(s:bufNr, '&modified') == 0 
       execute "bd ".s:bufNr 
       endif 
      endif 
     endif 
     let s:bufNr = s:bufNr-1 
    endwhile 
endfunction 
+0

No me gusta ': bufdo' ya que estropea la ventana actual. –

+0

o.k., lo volveré a trabajar – Habi

+2

Hecho. Ver [Editar] arriba. – Habi

2

yo también tenía una necesidad de esta funcionalidad todo el tiempo. Esta es la solución que tengo en mi vimrc.

function! GetBufferList() 
    return filter(range(1,bufnr('$')), 'buflisted(v:val)') 
endfunction 

function! GetMatchingBuffers(pattern) 
    return filter(GetBufferList(), 'bufname(v:val) =~ a:pattern') 
endfunction 

function! WipeMatchingBuffers(pattern) 
    let l:matchList = GetMatchingBuffers(a:pattern) 

    let l:count = len(l:matchList) 
    if l:count < 1 
     echo 'No buffers found matching pattern ' . a:pattern 
     return 
    endif 

    if l:count == 1 
     let l:suffix = '' 
    else 
     let l:suffix = 's' 
    endif 

    exec 'bw ' . join(l:matchList, ' ') 

    echo 'Wiped ' . l:count . ' buffer' . l:suffix . '.' 
endfunction 

command! -nargs=1 BW call WipeMatchingBuffers('<args>') 

Ahora, puedo hacer :BW regex (por ejemplo :BW \.cpp$ y limpie todos los tampones a juego que tienen que coincida con el patrón en su ruta.

Si desea eliminar en lugar de limpiar, por supuesto puede sustituir exec 'bw ' . join(l:matchList, ' ') con exec 'bd ' . join(l:matchList, ' ')

+0

A veces me pregunto por qué vim no admite expresiones regulares en todas partes (': badd',': bdelete', ': bufdo',': bn' ...) – puk

1

Muy simple: use el comando :bd[elete]. Por ejemplo, :bd[elete] buf#1 buf#5 buf#3 borrará las memorias intermedias de 1, 3 y 5.

8

También se puede utilizar como alternativa utilizar:

:.,$-bd[elete] " to delete buffers from the current one to last but one 
    :%bd[elete]  " to delete all buffers 
+0

Esto funciona bien. Hago un *: ls * para ver los números del buffer y ellos *: a, bbd * para borrar los buffers del número a a b –

0

TAB sólo autocompletar un archivo para que a partir del Vim 7.4.282
use <c-a> para autocompletar todos los archivos.

sólo puede utilizar:

bd filetype 

continuación, sólo tiene que utilizar <c-a> para facilitar la realización de todos los archivos abiertos de tipo de archivo especificado.

por ejemplo, tiene 1.xml, 2.xml, 3.xml y 4.xml, que puede hacer:

bd xml 

a continuación, pulse <c-a>

vim autocompletará para usted como sigue:

bd 1.xml 2.xml 3.xml 4.xml 

que sólo puede pulsar ENTER para completar el comando.

si se han realizado cambios en uno de los archivos mencionados anteriormente, recuerde que hacer:

bd! xml 
9
:3,5bd[elete] 

eliminará gama memoria intermedia del 3 al 5.

+1

Esa es la respuesta que estaba buscando. Gracias. – user3751385

+1

Lo mismo. ¡Gracias! –

Cuestiones relacionadas