จะลบบัฟเฟอร์หลายตัวใน Vim ได้อย่างไร?


120

สมมติว่าฉันมีไฟล์หลายไฟล์ที่เปิดเป็นบัฟเฟอร์ใน Vim ไฟล์ที่มี*.cpp, และบาง*.h *.xmlฉันต้องการปิดไฟล์ XML ทั้งหมดด้วย:bd *.xml. อย่างไรก็ตาม Vim ไม่อนุญาตสิ่งนี้ (E93: มากกว่าหนึ่งรายการ ... )

มีวิธีใดบ้างที่จะทำเช่นนี้?

ปล. รู้ว่า:bd file1 file2 file3ใช้ได้ ฉัน*.xmlจะประเมินได้file1.xml file2.xml file3.xmlอย่างไร?

คำตอบ:


194

คุณสามารถใช้<C-a>เพื่อทำการแข่งขันทั้งหมด ดังนั้นถ้าคุณพิมพ์:bd *.xmlแล้วกด<C-a>, :bd file1.xml file2.xml file3.xmlเสียงเรียกเข้าจะเสร็จสิ้นคำสั่งไปยัง


8
@Florian <tab>อนุญาตให้คุณหมุนเวียนการแข่งขันโดยใส่รายการเดียวในบรรทัดคำสั่ง<C-a>เพิ่มการแข่งขันทั้งหมดในครั้งเดียว
Björn Steinbrink

พระเจ้าของฉันคุณพูดถูก! ขอโทษ แท็บจะทำงานเมื่อมีผลลัพธ์ที่เป็นไปได้เพียงอย่างเดียว
Florian Klein

คุณใช้ <Ca> กับ vim บน tmux อย่างไร?
58

4
tmux ไม่ผูก <Ca> ตามค่าเริ่มต้น แต่ถ้าคุณกำหนดค่าให้เช่นใช้ <Ca> แทนการใช้ <Ca> เพื่อจำลองหน้าจอคุณควรกำหนดค่าให้แมปด้วยเช่น <Ca> a เพื่อส่งผ่าน <Ca> Ca> ผ่านไปยังโปรแกรมที่ทำงานภายใน tmux screen-keys.conf ที่มาพร้อมกับ tmux ทำเช่นนั้น
Björn Steinbrink

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
ใช้งานได้ดี ฉันทำ a : 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()จะให้เฉพาะไฟล์ที่มีอยู่ (ในฮาร์ดไดรฟ์ของคุณ) และไม่เปิดบัฟเฟอร์
Luc Hermitte

คุณลืมfnameescape()ชื่อบัฟเฟอร์
ZyX

ฉันเพิ่งตรวจสอบc:/Program files/foo.barและแม้กระทั่งfoo.bar.fooและทำงานได้อย่างสมบูรณ์ fnameescape()อาจจำเป็นถ้าฉันใช้ชื่อบัฟเฟอร์ แต่ฉันแค่ตรวจสอบว่าชื่อบัฟเฟอร์ตรงกับนิพจน์ที่กำหนดหรือไม่: \.{ext}$- ฉันให้หมายเลขบัฟเฟอร์กับ: bd` ฉันไม่มีเหตุผลที่จะหลีกหนีอะไรเลยสำหรับการจับคู่นิพจน์ทั่วไป
Luc Hermitte

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 (ตามที่ Luc Hermitte ร้องขอดูความคิดเห็นด้านล่าง)

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เพราะมันยุ่งกับหน้าต่างปัจจุบัน
Luc Hermitte

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... )
ปึก


1

TABจะเติมข้อความอัตโนมัติเพียงไฟล์เดียวสำหรับคุณในขณะที่ Vim 7.4.282
ใช้<c-a>เพื่อเติมไฟล์ทั้งหมดโดยอัตโนมัติ

คุณสามารถใช้:

bd filetype

จากนั้นใช้<c-a>เพื่ออำนวยความสะดวกในการดำเนินการไฟล์ที่เปิดทั้งหมดของประเภทไฟล์ที่ระบุให้เสร็จสมบูรณ์

ตัวอย่างเช่นคุณมี 1.xml, 2.xml, 3.xml และ 4.xml คุณสามารถทำได้:

bd xml

จากนั้นกด <c-a>

กลุ่มจะเติมข้อความอัตโนมัติให้คุณดังต่อไปนี้:

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

คุณสามารถกด Enter เพื่อทำคำสั่งให้เสร็จสิ้น

หากคุณได้ทำการเปลี่ยนแปลงในไฟล์ใดไฟล์หนึ่งที่กล่าวมาข้างต้นอย่าลืมทำ:

bd! xml
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.