Как мне закрыть буфер, не закрывая окно?


120

Многоуровневые представления Vim (окна, буферы и вкладки) немного сбили меня с толку. Скажем, я разделил отображение (: sp), а затем выбрал другой буфер для отображения в каждом окне. Теперь я хочу закрыть один из буферов, но не хочу, чтобы окно закрывалось (после закрытия оно может отображать следующий буфер в списке или пустой буфер, это не имеет значения). Как я могу это сделать?

Спасибо.


Есть ли причина, по которой вы хотите закрыть буфер, а не просто больше не видеть его?
rampion

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Просто поменяв местами команду буфера и номер буфера в приведенном выше.
Ashish

Я использовал это немного, но меня продолжало раздражать, что он повторно открывает ранее закрытый буфер.
pean

@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

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, и теперь я могу закрыть единственный бафф / файл / вкладку, не закрывая окно.

После установки указанного выше плагина поместите следующий код в мой .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чтобы открыть файл в окне просмотра без разделения окна.

PS Через два дня после запуска vim у меня все еще возникают проблемы с поиском точных команд помощи. Надеюсь, это поможет кому-то другому продолжать работать, пока у них действительно не будет времени, чтобы понять vim.


1

Вот очень читаемая функция vimscript, которая хорошо обрабатывает все случаи ,

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

FUNC! DeleteCurBufferNotCloseWindow () прервать
    если & изменено
        echohl ErrorMsg
        echom "E89: нет записи с момента последнего изменения"
        echohl Нет
    elseif winnr ('$') == 1
        бод
    else "несколько окон
        пусть oldbuf = bufnr ('%')
        пусть oldwin = winnr ()
        пока 1 ", все окна, отображающие oldbuf, останутся открытыми
            если ошибка (bufnr ('#'))
                б #
            еще
                млрд
                пусть curbuf = bufnr ('%')
                если curbuf == oldbuf
                    enew "oldbuf - единственный буфер, создайте его
                ENDIF
            ENDIF
            пусть победа = bufwinnr (oldbuf)
            если победа == -1
                перерыв
            else "есть другие окна, отображающие oldbuf
                exec win '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>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.