Come eliminare più buffer in Vim?


120

Supponendo che io abbia più file aperti come buffer in Vim. I file lo hanno *.cpp, *.he alcuni lo sono *.xml. Voglio chiudere tutti i file XML con :bd *.xml. Tuttavia, Vim non lo consente (E93: più di una corrispondenza ...).

C'è un modo per fare questo?

PS So che :bd file1 file2 file3funziona. Così posso in qualche modo valutare *.xmla file1.xml file2.xml file3.xml?

Risposte:


194

È possibile utilizzare <C-a>per completare tutte le partite. Quindi se digiti :bd *.xmle poi premi <C-a>, vim completerà il comando per :bd file1.xml file2.xml file3.xml.


8
@Florian <tab>ti consente solo di scorrere le partite, mettendo una singola voce sulla riga di comando, <C-a>aggiunge tutte le corrispondenze contemporaneamente.
Björn Steinbrink

mio dio hai ragione! spiacente. scheda funziona solo quando c'è un solo risultato possibile.
Florian Klein

Come usi <Ca> con vim su tmux?
nabn

4
tmux non associa <Ca> per impostazione predefinita, ma se l'hai configurato ad esempio per usare <Ca> invece di <Cb> per emulare lo schermo, dovresti anche configurarlo per mappare, ad esempio, <Ca> a per passare un < Ca> fino al programma in esecuzione all'interno di tmux. Lo screen-keys.conf fornito con tmux lo fa.
Björn Steinbrink

7
JFTR, nel caso tu abbia vim-rsiinstallato (penso, è un must per tutti su * nix), per ottenere il <C-a>lavoro nel modo originale nella riga di comando, dovresti usare <C-x> <C-a>invece.
kostix

43
:3,5bd[elete]   

Eliminerà l'intervallo di buffer da 3 a 5.


19

Puoi anche usare in alternativa usare:

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

1
Funziona bene. Faccio a : ls per vedere i numeri del buffer e loro : a, bbd per eliminare i buffer dal numero a alla b
Neaţu Ovidiu Gabriel

5

Puoi usarlo.

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

Dovrebbe essere abbastanza facile aggiungerlo 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>)

Non so quasi nulla di Vimscript, ma che ne dici della funzione glob ()?
Thanh DK

1
glob()ti darà solo i file esistenti (sul tuo disco rigido) e non i buffer aperti.
Luc Hermitte

Hai dimenticato di fnameescape()memorizzare i nomi.
ZyX

Ho appena controllato c:/Program files/foo.bar, e anche foo.bar.fooe ha funzionato perfettamente. fnameescape()potrebbe essere stato richiesto se ho usato i nomi del buffer. Ma sto solo controllando se i nomi del buffer corrispondono a una data espressione: \.{ext}$- Assegno i numeri del buffer a: bd`. Non ho motivo di sfuggire a nulla per la corrispondenza delle espressioni regolari.
Luc Hermitte

5

Prova lo script qui sotto. L'esempio è per "txt", modificalo secondo necessità, ad esempio in "xml". I buffer modificati non vengono eliminati. Premere \ bd per eliminare i buffer.

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

[Modifica] Lo stesso senza: bufdo (come richiesto da Luc Hermitte, vedi commento sotto)

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

1
Non mi piace :bufdoperché rovina la finestra corrente.
Luc Hermitte

3

Anch'io avevo sempre bisogno di questa funzionalità. Questa è la soluzione che ho nel mio 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>')

Ora, posso semplicemente fare :BW regex(ad esempio :BW \.cpp$e cancellare tutti i buffer corrispondenti che hanno corrispondenza con quel modello nel loro percorso.

Se desideri eliminare anziché cancellare, puoi ovviamente sostituire exec 'bw ' . join(l:matchList, ' ')conexec 'bd ' . join(l:matchList, ' ')


A volte mi chiedo perché vim non supporta le espressioni regolari in tutto il mondo ( :badd, :bdelete, :bufdo, :bn...)
puk

1

Molto semplicemente: usa il :bd[elete]comando. Ad esempio, :bd[elete] buf#1 buf#5 buf#3eliminerà i buffer 1, 3 e 5.


1

TABsarà completare automaticamente un solo file per voi come di Vim 7.4.282
utilizzo <c-a>per completare automaticamente tutti i file.

Puoi semplicemente usare:

bd filetype

quindi usalo <c-a>per facilitare il completamento di tutti i file aperti del tipo di file specificato.

ad esempio, hai 1.xml, 2.xml, 3.xml e 4.xml, puoi fare:

bd xml

quindi premere <c-a>

vim si completerà automaticamente come segue:

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

puoi semplicemente premere invio per completare il comando.

se hai apportato modifiche a uno dei file sopra menzionati, ricordati di fare:

bd! xml
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.