2010-07-01 17 views
82

Zakładając, że mam wiele plików otwartych jako bufory w Vimie. Pliki mają numer *.cpp, *.h, a niektóre z nich to *.xml. Chcę zamknąć wszystkie pliki XML za pomocą :bd *.xml. Jednak Vim na to nie pozwala (E93: więcej niż jeden mecz ...).Jak usunąć wiele buforów w Vimie?

Czy jest jakiś sposób to zrobić?

P.S. Wiem, że działa :bd file1 file2 file3. Czy mogę w jakiś sposób ocenić *.xml na file1.xml file2.xml file3.xml?

Odpowiedz

131

można użyć <C-a> ukończyć wszystkie mecze. Więc jeśli wpiszesz :bd *.xml a następnie uderzył <C-a> Vim zakończy polecenie :bd file1.xml file2.xml file3.xml.

+3

Awesome! Bez wtyczek :) Dziękuję. – Salil

+0

tak niesamowite. dzięki! – tester

+3

lub '' zamiast '' działa również. – Florian

4

Możesz tego użyć.

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

Dodanie polecenia do polecenia powinno być całkiem łatwe.

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

Nie znam się na Vimscript, ale co z funkcją glob()? –

+1

'glob()' poda tylko istniejące pliki (na dysku twardym) i nie otwiera buforów. –

+0

Zapomniałeś nazwy buforów 'fnameescape()'. – ZyX

4

Wypróbuj poniższy skrypt. Przykład dotyczy "txt", zmień go w razie potrzeby, np. do "xml". Zmodyfikowane bufory nie są usuwane. Naciśnij przycisk \ bd, aby usunąć bufory.

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 

[Edytuj] samo bez: bufdo (wymagane przez Luc Hermitte patrz komentarz poniżej)

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

Nie lubię ': bufdo', ponieważ powoduje to przepełnienie bieżącego okna. –

+0

o.k., Przebuduję to na – Habi

+2

Zrobione. Zobacz [Edycja] powyżej. – Habi

2

Ja też miałem potrzebę tej funkcji przez cały czas. To jest rozwiązanie, które mam w moim 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>') 

Teraz mogę tylko zrobić :BW regex (np :BW \.cpp$ i wytrzeć wszystkie pasujące bufory, które mają zgodne ze wzorcem w ich ścieżki.

Jeśli chcesz usunąć zamiast wycierać, można oczywiście zastąpić exec 'bw ' . join(l:matchList, ' ') z exec 'bd ' . join(l:matchList, ' ')

+0

Czasami zastanawiam się, dlaczego vim nie obsługuje wszędzie wyrażeń regularnych (': badd',': bdelete', ': bufdo',': bn' ...) – puk

1

Po prostu: użyj polecenia :bd[elete]. Na przykład, :bd[elete] buf#1 buf#5 buf#3 usunie bufory 1, 3 i 5.

8

Można również używać alternatywnie użyć:

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

To działa dobrze. Robię * * ls *, aby zobaczyć numery buforów i ich *: a, bbd *, aby usunąć bufory z numeru a do b –

0

TAB uzupełni tylko jeden plik dla ciebie jak z Vim 7.4.282
użyj <c-a> do autouzupełniania wszystkich plików.

można po prostu użyć:

bd filetype 

następnie wystarczy użyć <c-a> aby ułatwić ukończenie wszystkich otwartych plików określonego typu pliku.

Na przykład masz 1.xml, 2.xml, 3.xml i 4.xml, można zrobić:

bd xml 

następnie naciśnij <c-a>

vim uzupełni dla Ciebie następujące:

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

można po prostu naciśnij ENTER, aby zakończyć polecenie.

jeśli zostały wprowadzone zmiany w jednym z plików wymienionych powyżej, należy pamiętać, aby zrobić:

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

kasuje bufor zakres od 3 do 5.

+1

Oto odpowiedź, której szukałem. Dzięki. – user3751385

+1

To samo. Dziękuję Ci! –