Як я можу закрити буфер, не закриваючи вікно?


120

Багатошарові погляди Віма (Windows, буфери та вкладки) мене трохи збентежили. Скажімо, я розділив дисплей (: sp), а потім виберіть інший буфер для відображення у кожному вікні. Тепер я хочу закрити один з буферів, але я не хочу, щоб вікно закривалося (після закриття він може відображати наступний буфер у списку або порожній буфер, це не має значення). Як я можу це зробити?

Дякую.


Чи є причина, що ви хочете закрити буфер, а не просто більше не бачити його там?
чемпіон

9
Я насправді про це теж цікавився. Видалення буфера та згодом необхідність відновлення будь-якої частини моїх розщеплень були знищені в процесі.
brettkelly

3
Поки що було 29 голосів. Я думаю, що це досить поширений випадок використання. Мені це потрібно, коли я працюю з великою кількістю буферів. Іноді я використовую 2 вікна і хочу закрити буфер. Я не хочу, щоб це вікно відходило. Я просто хочу, щоб там був відображений наступний буфер.
Вільсон Фрейтас


Відповіді:



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
Для новачка, кинути це в вашому .vimrc : map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>. Перезапустіть VIM, наступного разу, коли ви хочете закрити буфер, просто введіть:\q
EasyCo

5
Це матиме несподіваний результат, якщо у вас було вертикально розбите вікно. Насправді будь-яка конфігурація розбиття вікон, крім стандартної (створена sp).
hitzg

2
Я думаю, що фрагмент того, що потрібно вкласти .vimrc, не повинен включати період наприкінці. Крім цього, дивовижно! Це має бути прийнятою відповіддю.
Ернесто

3
це елегантно. як казали інші люди, якщо ви в основному використовуєте вертикальні розколи, перемикайтесь spіз vsp. мій запис .vimrc виглядає приблизно так:cnoremap bd bp<bar>vsp<bar>bn<bar>bd
Коннор

38

Я сьогодні це шукав і придумав

:b#|bd#

яке змінює поточне вікно на раніше відкритий буфер і видаляє / приховує буфер, від якого ви щойно відключилися.

Для цього потрібно щонайменше два відомих буфера.

Якщо інше вікно, але поточне показує той самий буфер, це все одно знищить розщеплення. Ви можете змінити всі вікна на раніше відкритий буфер за допомогою

:windo b#

Я додав більше деталей про колишню команду, обговорюючи відображення для неї (та деякі підводні камені) у відповіді на подібне запитання .


Також це можна зробити ... :#b|#bdПросто помінявши команду буфера та номер буфера у вищевказаному.
Ашиш

Я трохи використав це, але я постійно дратувався, що він знову відкрив раніше закритий буфер.
піан

@pean Ось що я згадував у пов'язаній відповіді - див. "Важливі примітки". Так, було б приємніше, якби це перейшло на інший відкритий буфер.
дійсний

1
Ви також можете зробити :bn|bd#або :bp|bd#замість цього перейти на попередній або наступний відкритий буфер, а не на буфер, до якого ви нещодавно зверталися (b #).
павон

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

1
Я спробував це, але це не дуже добре під час використання декількох розділених вікон. Ось моє рішення, якщо хтось має таку ж проблему: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
Я не хочу переміщати вікно. Я хочу закрити буфер, не торкаючись положення вікна, розміру чи наявності.
Мош

5

Для тих, хто використовує NERDTree.

Я виправляю це за допомогою цього плагіна https://github.com/jistr/vim-nerdtree-tabs, і тепер я можу закрити єдиний баф / файл / вкладку, не закриваючи вікно.

Після того, як плагін був встановлений вище, поставте наступний код на мій .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

роби що хочеш? він редагує новий безіменний буфер у поточному вікні, залишаючи існуючий файл відкритим у будь-яких інших вікнах.


Це відкриє новий порожній буфер. Я хочу закрити поточний буфер, не закриваючи вікно.
Мош

1

Моє улюблене рішення для цього - плагін bufkill.vim ( GitHub ). Він надає альтернативні версії різних :bкоманд -prefix, які працюють так само, як їх аналоги, але залишають вікно відкритим. Вони відображають незалежно від останнього видимого буфера або порожнього / нового буфера, якщо попереднього буфера не було.

З документації:

Коли ви хочете вивантажити / видалити / стерти буфер, використовуйте:
  : bun /: bd /: bw, щоб також закрити вікно (команда vim), або
  : BUN /: BD /: BW, щоб залишити вікно (и) недоторканим (цей сценарій).

1

Щоб "закрити" подання, використовуйте :hid[e]. Працює, якщо вам вдалося розділити вікно перегляду або відкрити кілька файлів. Ви не можете приховати останній буфер на дисплеї.

1 Наступна порада, яка допомогла мені: використовуйте :e ./path/to/file.workдля відкриття файлу у вікні перегляду, не розділяючи вікно.

PS Через два дні у vim у мене все ще виникають проблеми з пошуку точних команд довідки. Сподіваємось, це допоможе комусь іншому продовжувати працювати, поки вони дійсно не знайдуть час зрозуміти vim.


1

Ось дуже читабельна функція vimscript, яка добре обробляє всі випадки ,

  • поводитися схоже на вбудований :bd(якщо тільки одне вікно, просто викликайте його!),
    • видавати попередження і нічого не робити, якщо буфер модифікований.
    • якщо немає іншого буфера, створіть його через :enew.
    • якщо альтернативний буфер існує і в buffer-list, перемкніть його, інакше перейдіть далі, через :bn.
  • більш розумна поведінка для макета з декількома вікнами
    • не закриваючи жодного вікна,
    • завжди залишайтеся на оригінальному вікні.
    • для кожного вікна, що відображає поточний буфер, виконайте, як зазначено вище, а потім видаліть старий поточний буфер.
nnoremap <Leader> b: виклик DeleteCurBufferNotCloseWindow () <CR>

функція! DeleteCurBufferNotCloseWindow () скасувати
    якщо та змінено
        ErrorMsg
        echom "E89: немає запису з моменту останньої зміни"
        echohl Ні
    elseif winnr ('$') == 1
        бд
    else "кілька вікон
        нехай oldbuf = bufnr ('%')
        нехай oldwin = winnr ()
        поки 1 "всі вікна, на яких відображається oldbuf, залишаться відкритими
            якщо в списку (bufnr ('#'))
                b #
            ще
                bn
                нехай curbuf = bufnr ('%')
                якщо curbuf == oldbuf
                    enew "oldbuf - єдиний буфер, створити його
                закінчення
            закінчення
            нехай win = bufwinnr (oldbuf)
            якщо виграти == -1
                перерва
            else "є інше вікно, в якому відображається oldbuf
                exec win 'wincmd w'
            закінчення
        зрештою
        "видалити oldbuf та відновити вікно до oldwin
        exec oldbuf 'bd'
        exec oldwin 'wincmd w'
    закінчення
endfunc

0

Якщо ви схожі на мене, і ви прийшли сюди, намагаючись зробити навпаки , закрийте вікно, не закриваючи буфер, ви можете зробити це за допомогою:

:close


0

Проста версія, якою я особисто користуюся

:bp|bd#

Він переходить до попереднього буфера і видаляє інший буфер (який насправді є оригіналом, з якого ми перестрибнули). Це робить те, що ви очікували б у 99% випадків без складних сценаріїв.

Як ярлик клавіатури я використовую наступне

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

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