Як видалити кілька буферів у Vim?


120

Припустимо, що у Vim у мене є декілька файлів, відкритих як буфери. Файли є *.cpp, *.hа деякі є*.xml . Я хочу закрити всі файли XML :bd *.xml. Однак Vim цього не дозволяє (E93: Більше однієї відповідності ...).

Чи можна це зробити?

PS Я знаю, що :bd file1 file2 file3працює. Так що я можу як - то оцінювати *.xmlз file1.xml file2.xml file3.xml?

Відповіді:


194

Ви можете використовувати <C-a>для завершення всіх матчів. Тож якщо ви введете :bd *.xmlі потім натиснете <C-a>, vim виконає команду на :bd file1.xml file2.xml file3.xml.


8
@Florian <tab>дозволяє лише переглядати сірники, ставлячи в командному рядку один запис, <C-a>додаючи відразу всі збіги.
Björn Steinbrink

мій боже, ти маєш рацію! вибачте. вкладка працює лише тоді, коли є лише один можливий результат.
Флоріан Кляйн

Як ви використовуєте <Ca> з vim на tmux?
набн

4
tmux не прив'язує <Ca> за замовчуванням, але якщо ви налаштували його, наприклад, використовуйте <Ca> замість <Cb> для емуляції екрана, ви також повинні налаштувати його для відображення, наприклад, <Ca> a для передачі < Са> до програми, що працює всередині tmux. Це робить екран-keys.conf, який постачається з tmux.
Бьорн Штайнбрінк

7
JFTR, якщо ви vim-rsiвстановили (я думаю, це обов'язково для всіх на * nix), щоб отримати <C-a>роботу оригінальним способом у командному рядку, ви повинні використовувати <C-x> <C-a>замість цього.
kostix


19

Ви також можете використовувати альтернативне використання:

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

1
Це добре працює. Я роблю : ls побачити буферні номери та їх : a, bbd, щоб видалити буфери з числа a до b
Neaţu Ovidiu Gabriel

5

Ви можете використовувати це.

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

Додавати його до команди слід досить просто.

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>)

Я майже нічого не знаю про Vimscript, але як щодо функції glob ()?
Thanh DK

1
glob()надасть лише наявні файли (на вашому жорсткому диску), а не відкриті буфери.
Люк Ермітт

Ви забули fnameescape()буферні імена.
ZyX

Я щойно перевірив c:/Program files/foo.bar, і навіть, foo.bar.fooі це працювало чудово. fnameescape()може знадобитися, якщо я використовував буферні імена. Але я лише перевіряю, чи імена буферів відповідають даному виразу: \.{ext}$- Я даю буферні номери: bd`. Я не маю жодних причин уникати нічого для збігу регулярних виразів.
Люк Ермітта

5

Спробуйте сценарій нижче. Приклад наведено для "txt", змінюйте його за потребою, наприклад, на "xml". Змінені буфери не видаляються. Натисніть \ bd, щоб видалити буфери.

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

[Редагувати] Те саме без: bufdo (як вимагає Люк Ермітт, див. Коментар нижче)

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
Мені не подобається, :bufdoяк воно замикає поточне вікно.
Люк Ермітт

3

У мене теж весь час була потреба в цій функціональності. Це рішення, яке я маю в своєму 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>')

Тепер я можу просто зробити :BW regex(наприклад, :BW \.cpp$і стерти всі відповідні буфери, які відповідають цьому шаблону в їх імені шляху.

Якщо ви хочете видалити, а не стерти, можете, звичайно, замінити exec 'bw ' . join(l:matchList, ' ')наexec 'bd ' . join(l:matchList, ' ')


Я іноді дивуюся , чому ВІМ не підтримує регулярні вирази всюди ( :badd, :bdelete, :bufdo, :bn...)
PUK

1

Дуже просто: використовуйте :bd[elete]команду. Наприклад, :bd[elete] buf#1 buf#5 buf#3буде видалено буфери 1, 3 і 5.


1

TABтільки автозаповнення один файл для вас , як з Vim 7.4.282
використання <c-a>автозаповнення всіх файлів.

Ви можете просто використовувати:

bd filetype

то просто використовувати <c-a> для полегшення заповнення всіх відкритих файлів вказаного файлу.

Наприклад, у вас є 1.xml, 2.xml, 3.xml і 4.xml, ви можете:

bd xml

потім натисніть <c-a>

vim автоматично заповнить для вас наступним чином:

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

ви можете просто натиснути клавішу Enter, щоб виконати команду.

якщо ви внесли зміни в один із згаданих вище файлів, не забудьте зробити:

bd! xml
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.