ฉันจะปิดบัฟเฟอร์โดยไม่ปิดหน้าต่างได้อย่างไร


120

มุมมองหลายชั้นของ Vim (Windows, Buffers และ Tabs) ทำให้ฉันสับสนเล็กน้อย สมมติว่าฉันแยกการแสดงผล (: sp) แล้วเลือกบัฟเฟอร์อื่นเพื่อแสดงในแต่ละหน้าต่าง ตอนนี้ฉันต้องการปิดหนึ่งในบัฟเฟอร์ แต่ฉันไม่ต้องการให้หน้าต่างปิด (หลังจากการปิดมันสามารถแสดงบัฟเฟอร์ถัดไปในรายการหรือบัฟเฟอร์ว่างได้ก็ไม่สำคัญ) ฉันจะทำเช่นนี้ได้อย่างไร?

ขอบคุณ


มีเหตุผลที่คุณต้องการปิดบัฟเฟอร์แทนที่จะไม่เห็นที่นั่นอีกต่อไปหรือไม่?
rampion

9
ฉันเคยสงสัยเกี่ยวกับเรื่องนี้เช่นกัน การลบบัฟเฟอร์และต้องสร้างใหม่ในภายหลังทุกส่วนของการแยกของฉันถูกทำลายในกระบวนการนี้เป็นเรื่องที่น่ารำคาญ
brettkelly

3
29 คะแนนโหวตจนถึงขณะนี้ ฉันคิดว่านี่เป็นกรณีการใช้งานทั่วไป ฉันต้องการสิ่งนี้เมื่อฉันทำงานกับบัฟเฟอร์จำนวนมาก บางครั้งฉันใช้ 2 หน้าต่างและต้องการปิดบัฟเฟอร์ ฉันไม่ต้องการให้หน้าต่างนั้นหายไป ฉันแค่ต้องการให้บัฟเฟอร์ถัดไปแสดงที่นั่น
Wilson Freitas


หนึ่งนี้DeleteCurBufferNotCloseWindow()ทำงานได้ดีและสามารถอ่านได้ค่อนข้าง (Disclaimer: my answer)
qeatzy

คำตอบ:


31

มีสคริปต์ในVim wikiเพื่อทำสิ่งนี้ ฉันไม่คิดว่าจะมี builtin ที่ทำในสิ่งที่คุณต้องการ

รุ่นล่าสุดของกลุ่ม-bufkill อยู่บน GitHub


4
คำตอบที่ดีมันนำฉันไปสู่เวอร์ชันสุดท้ายของสคริปต์ที่: vim.org/scripts/script.php?script_id=1147
Mosh

145

ฉันยุ่งกับเรื่องนี้เล็กน้อยและในที่สุดก็เกิด:

:bp | sp | bn | bd

นี่คือเวอร์ชันคัดลอก / วางสำหรับการแมปคีย์:

:bp<bar>sp<bar>bn<bar>bd<CR>

ฉันทดสอบมาแล้วพอสมควรและทำงานได้อย่างสม่ำเสมอในหลาย ๆ สภาวะ เมื่อใช้กับบัฟเฟอร์สุดท้ายจะทำให้คุณมีบัฟเฟอร์เปล่าใหม่

โยนสิ่งนี้ใน. vimrc ของคุณ:

map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>

รีสตาร์ท Vim หรือเพียง:source ~/.vimrcเพื่อให้การเปลี่ยนแปลงมีผล ครั้งต่อไปที่คุณต้องการปิดบัฟเฟอร์ให้พิมพ์: \q(ถ้า\เป็นคีย์ผู้นำของคุณ)


1
ขอบคุณ! ดีและเรียบง่ายไม่เหมือนโซลูชันอื่น ๆ ที่ฉันเคยเห็น
jwd

16
สำหรับการเริ่มต้นโยนนี้ไว้ใน.vimrcmap <leader>q :bp<bar>sp<bar>bn<bar>bd<CR> : รีสตาร์ท VIM ครั้งต่อไปที่คุณต้องการปิดบัฟเฟอร์เพียงพิมพ์:\q
EasyCo

5
สิ่งนี้จะได้ผลลัพธ์ที่ไม่คาดคิดหากคุณมีหน้าต่างที่แบ่งออกเป็นแนวตั้ง ในความเป็นจริงการกำหนดค่าการแบ่งหน้าต่างนอกเหนือจากมาตรฐาน (สร้างโดยsp)
hitzg

2
ฉันคิดว่าข้อมูลโค้ดของสิ่งที่จะใส่ใน. vimrc ไม่ควรมีจุดต่อท้าย นอกเหนือจากนั้นสุดยอด! นี่ควรเป็นคำตอบที่ได้รับการยอมรับ
Ernesto

3
นี่คือความสง่างาม เป็นคนอื่น ๆ ได้กล่าวว่าถ้าคุณใช้ส่วนใหญ่จะแยกแนวตั้งสลับกับsp vspรายการ. vimrc ของฉันมีลักษณะดังนี้:cnoremap bd bp<bar>vsp<bar>bn<bar>bd
Connor

38

ฉันค้นหาสิ่งนี้ในวันนี้และได้มากับ

:b#|bd#

ซึ่งจะเปลี่ยนหน้าต่างปัจจุบันเป็นบัฟเฟอร์ที่เปิดไว้ก่อนหน้านี้และลบ / ซ่อนบัฟเฟอร์ที่คุณเพิ่งเปลี่ยนไป

สิ่งนี้ต้องการบัฟเฟอร์ที่รู้จักอย่างน้อยสองรายการ

หากหน้าต่างอื่น แต่ปัจจุบันแสดงบัฟเฟอร์เดียวกันสิ่งนี้จะยังคงทำลายการแยก คุณสามารถเปลี่ยนหน้าต่างทั้งหมดเป็นบัฟเฟอร์ที่เปิดไว้ก่อนหน้านี้ได้ด้วย

:windo b#

ฉันจะเพิ่มรายละเอียดเพิ่มเติมเกี่ยวกับคำสั่งอดีตการพูดคุยการทำแผนที่สำหรับมัน (และข้อผิดพลาดบางส่วน) ในคำตอบของคำถามที่คล้ายกัน


นอกจากนี้ยังสามารถทำได้ ... :#b|#bdเพียงแค่เปลี่ยนคำสั่งบัฟเฟอร์และหมายเลขบัฟเฟอร์ในด้านบน
Ashish

ฉันเคยใช้สิ่งนี้มาบ้างแล้ว แต่ฉันรู้สึกรำคาญที่มันเปิดบัฟเฟอร์ที่ปิดไว้ก่อนหน้านี้ขึ้นมาใหม่
ถั่วลิสง

@pean นั่นคือสิ่งที่ฉันพูดถึงในคำตอบที่เชื่อมโยง - ดู "หมายเหตุสำคัญ" ใช่จะดีกว่านี้ถ้าเปลี่ยนไปใช้บัฟเฟอร์แบบเปิดอื่น
ใช้ได้ใน

1
คุณยังสามารถทำ:bn|bd#หรือ:bp|bd#เปลี่ยนไปใช้บัฟเฟอร์ที่เปิดก่อนหน้าหรือถัดไปแทนได้ตามลำดับแทนที่จะเป็นบัฟเฟอร์ที่คุณเข้าถึงล่าสุด (b #)
pavon

12
nmap <leader>d :bprevious<CR>:bdelete #<CR>

ทำงานตามที่ควรจะเป็นจนกว่าจะเปิดบัฟเฟอร์หนึ่งในหลายหน้าต่าง ดีพอเว้นแต่คุณต้องการใช้สคริปต์ที่ใหญ่กว่านั้น

แก้ไข: นี่คือสิ่งที่ฉันใช้ตอนนี้:

function! BufferDelete()
    if &modified
        echohl ErrorMsg
        echomsg "No write since last change. Not closing buffer."
        echohl NONE
    else
        let s:total_nr_buffers = len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))

        if s:total_nr_buffers == 1
            bdelete
            echo "Buffer deleted. Created new buffer."
        else
            bprevious
            bdelete #
            echo "Buffer deleted."
        endif
    endif
endfunction

2
ฉันลองวิธีนี้ แต่มันไม่ได้ผลดีนักในขณะที่ใช้หลาย ๆ หน้าต่างแยก นี่คือวิธีแก้ปัญหาของฉันหากมีคนประสบปัญหาเดียวกัน:nmap <leader>d :ene<CR>:bd #<CR>
caio

7

ฉันคิดว่านี่คือสิ่งที่คุณกำลังมองหา

http://www.vim.org/htmldoc/windows.html#window-moving

ลองสิ่งนี้:

ดูรหัสบัฟเฟอร์ของคุณโดยใช้

:buffers

คุณจะเห็นรายการบัฟเฟอร์ที่นั่นเช่น

1  a.cpp
2  b.py
3  c.php

หากคุณต้องการลบ b.py จากบัฟเฟอร์

:2bw

หากคุณต้องการลบ / ปิดทั้งหมดจากบัฟเฟอร์

:1,3bw

1
ฉันไม่ต้องการย้ายหน้าต่าง ฉันต้องการปิดบัฟเฟอร์โดยไม่ต้องสัมผัสตำแหน่งขนาดหรือการมีอยู่ของหน้าต่าง
Mosh

5

สำหรับผู้ที่ใช้ NERDTree

ฉันแก้ไขสิ่งนี้โดยใช้ปลั๊กอินนี้https://github.com/jistr/vim-nerdtree-tabsและตอนนี้ฉันสามารถปิดเฉพาะ buff / file / tab โดยไม่ต้องปิดหน้าต่าง

หลังจากติดตั้งปลั๊กอินด้านบนแล้วให้ใส่รหัสต่อไปนี้ใน. vimrc ของฉัน:

let g:nerdtree_tabs_autoclose=0

คำอธิบายสำหรับตัวแปรด้านบนคือปิดแท็บปัจจุบันหากมีเพียงหน้าต่างเดียวในนั้นและเป็น NERDTree (ค่าเริ่มต้น 1)

ข้อมูลเพิ่มเติมที่นี่: https://github.com/jistr/vim-nerdtree-tabs#configuration


2

ฉันไม่คิดว่าจะมีวิธีการยิงเพียงครั้งเดียว แต่คุณสามารถทำได้:enewหรือ:lsแสดงรายการบัฟเฟอร์ของคุณและเปลี่ยนเป็นแบบอื่นโดยใช้:b [number].

เมื่อคุณมีบัฟเฟอร์อื่นในหน้าต่างแล้ว:bd #จะลบบัฟเฟอร์ก่อนหน้านี้ในหน้าต่างและเนื่องจากบัฟเฟอร์ปัจจุบันยังคงมีอยู่หน้าต่างจะไม่ถูกปิด


2

ฉันเคยใช้:

:bp<bar>sp<bar>bn<bar>bd<CR>

แต่ฉันพบบางครั้งที่มันปิดหน้าต่างของฉัน

เมื่อเร็ว ๆ นี้ฉันสังเกตเห็นว่าฉันมักจะใช้สิ่งนี้เมื่อฉันทำงานในโครงการและต้องรีบเปิด.tmux.conf .zshrcก่อนที่จะกลับไปทำงาน

สำหรับการใช้งานนี้ฉันพบว่าดีกว่าที่จะ:

  • สลับกลับไปที่บัฟเฟอร์ที่ฉันใช้งานก่อนหน้านี้ C-6
  • พิมพ์:bd#เพื่อลบบัฟเฟอร์ก่อนหน้านี้ (ฉันได้แมปไว้เช่นนี้nnoremap <leader>d :bd#<CR>:)

มันช่วยให้ฉันควบคุมบัฟเฟอร์ที่ฉันกำลังจะกลับไปและรู้สึกเป็นธรรมชาติมากขึ้น


1

หากว่า

:enew

ทำในสิ่งที่คุณต้องการ? มันจะแก้ไขบัฟเฟอร์ใหม่ที่ไม่มีชื่อในหน้าต่างปัจจุบันโดยปล่อยให้ไฟล์ที่มีอยู่เปิดในหน้าต่างอื่น ๆ


การดำเนินการนี้จะเปิดบัฟเฟอร์ว่างใหม่ ฉันต้องการปิดบัฟเฟอร์ปัจจุบันโดยไม่ต้องปิดหน้าต่าง
Mosh

1

ทางออกที่ฉันชอบคือปลั๊กอินbufkill.vim ( GitHub ) มี:bคำสั่ง -prefix เวอร์ชันอื่นที่ทำงานเหมือนกับคำสั่งคู่กัน แต่เปิดหน้าต่างทิ้งไว้ ซึ่งจะแสดงบัฟเฟอร์ที่มองเห็นได้ล่าสุดหรือบัฟเฟอร์ว่าง / ใหม่หากไม่มีบัฟเฟอร์ก่อนหน้า

จากเอกสารประกอบ:

เมื่อคุณต้องการยกเลิกการโหลด / ลบ / ล้างบัฟเฟอร์ให้ใช้:
  : bun /: bd /: bw เพื่อปิดหน้าต่างด้วย (คำสั่ง vim) หรือ
  : BUN /: BD /: BW เพื่อปล่อยให้หน้าต่างไม่บุบสลาย (สคริปต์นี้)

1

ที่ 'ปิด' :hid[e]มุมมองการใช้งาน ใช้งานได้ถ้าคุณจัดการเพื่อแยกวิวพอร์ตหรือเปิดหลายไฟล์ คุณไม่สามารถซ่อนบัฟเฟอร์สุดท้ายที่แสดงได้

1 เคล็ดลับเพิ่มเติมที่ช่วยฉัน: ใช้:e ./path/to/file.workเพื่อเปิดไฟล์ในวิวพอร์ตโดยไม่ต้องแยกหน้าต่าง

ป.ล. สองวันเข้ากลุ่มฉันยังคงมีปัญหาในการค้นหาคำสั่งช่วยเหลือที่แม่นยำ หวังว่าสิ่งนี้จะช่วยให้คนอื่นทำงานต่อไปจนกว่าพวกเขาจะมีเวลาทำความเข้าใจกับคนกลุ่มนี้จริงๆ


1

นี่คือฟังก์ชั่น vimscript อ่านได้มากซึ่งจัดการทุกกรณีดี ,

  • ทำงานคล้ายกับในตัว:bd(หากมีเพียงหน้าต่างเดียวให้เรียกใช้!)
    • ออกคำเตือนและไม่ทำอะไรเลยหากแก้ไขบัฟเฟอร์
    • หากไม่มีบัฟเฟอร์อื่นให้สร้างโดยใช้:enew.
    • ถ้ามีอยู่บัฟเฟอร์อื่นและในสวิทช์ไปที่อื่นไปต่อไปผ่านทางbuffer-list:bn
  • พฤติกรรมที่เหมาะสมกว่าสำหรับเค้าโครงหลายหน้าต่าง
    • ไม่ปิดหน้าต่างใด ๆ
    • อยู่บนหน้าต่างเดิมเสมอ
    • สำหรับแต่ละหน้าต่างที่แสดงบัฟเฟอร์ปัจจุบันให้ทำตามรายการด้านบนจากนั้นลบบัฟเฟอร์ปัจจุบันเก่า
nnoremap <Leader> b: เรียก DeleteCurBufferNotCloseWindow () <CR>

func! DeleteCurBufferNotCloseWindow () ยกเลิก
    ถ้า & แก้ไข
        echohl ErrorMsg
        echom "E89: ไม่เขียนตั้งแต่เปลี่ยนครั้งล่าสุด"
        echohl ไม่มี
    elseif winnr ('$') == 1
        BD
    else "หลายหน้าต่าง
        ให้ oldbuf = bufnr ('%')
        ให้ oldwin = winnr ()
        ในขณะที่ 1 "หน้าต่างทั้งหมดที่แสดง oldbuf จะยังคงเปิดอยู่
            ถ้า buflisted (bufnr ('#'))
                B #
            อื่น
                พันล้าน
                ให้ curbuf = bufnr ('%')
                ถ้า curbuf == oldbuf
                    enew "oldbuf เป็นบัฟเฟอร์เดียวสร้างใหม่
                endif
            endif
            ให้ชนะ = bufwinnr (oldbuf)
            ถ้าชนะ == -1
                หยุดพัก
            else "มีหน้าต่างอื่นที่แสดง oldbuf
                exec ชนะ 'wincmd w'
            endif
        endwhile
        "ลบ oldbuf และเรียกคืนหน้าต่างเป็น oldwin
        exec oldbuf 'bd'
        exec oldwin 'wincmd w'
    endif
endfunc

0

ถ้าคุณชอบฉันและคุณมาที่นี่โดยพยายามทำสิ่งที่ตรงกันข้ามให้ปิดหน้าต่างโดยไม่ต้องปิดบัฟเฟอร์คุณสามารถทำได้ผ่าน:

:close


0

เวอร์ชันง่ายๆที่ฉันใช้เป็นการส่วนตัวคือ

:bp|bd#

มันไปที่บัฟเฟอร์ก่อนหน้าและลบบัฟเฟอร์อื่น ๆ (ซึ่งจริงๆแล้วเป็นบัฟเฟอร์ดั้งเดิมที่เราข้ามมา) สิ่งนี้ทำในสิ่งที่คุณคาดหวังใน 99% ของกรณีโดยไม่มีสคริปต์ที่ซับซ้อน

ในฐานะแป้นพิมพ์ลัดฉันใช้สิ่งต่อไปนี้

nnoremap <silent> <Leader>c :bp<BAR>bd#<CR>

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