Как я могу закрыть буфер, не закрывая окно? - PullRequest
109 голосов
/ 18 сентября 2009

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

Спасибо.

Ответы [ 13 ]

118 голосов
/ 21 декабря 2011

Я немного обдумал это и, наконец, придумал:

: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 (если \ ваш ключ лидера)

34 голосов
/ 27 октября 2013

Я искал это сегодня и придумал

:b#|bd#

, который изменяет текущее окно на ранее открытый буфер и удаляет / скрывает буфер, из которого вы только что отключились.

Для этого требуется как минимум два известных буфера.

Если другое окно, кроме текущего, показывает тот же буфер, это все равно уничтожит разбиение. Вы можете изменить все окна на ранее открытый буфер с помощью

:windo b#

Я добавил более подробную информацию о прежней команде, обсуждающей ее отображение (и некоторые подводные камни) в ответе на аналогичный вопрос .

27 голосов
/ 18 сентября 2009

В Vim wiki есть скрипт для этого. Я не думаю, что есть встроенный, который делает то, что вы хотите.

Последняя версия vim-bufkill находится на github .

12 голосов
/ 03 марта 2011
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
6 голосов
/ 18 сентября 2009

Я думаю, это то, что вы ищете

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

Попробуйте это:

Посмотрите свой идентификатор буфера, используя

:buffers

там вы увидите список буферов вроде

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

если вы хотите удалить b.py из буфера

:2bw

если вы хотите удалить / закрыть все из буферов

:1,3bw
4 голосов
/ 03 ноября 2014

Для тех, кто использует 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 голосов
/ 16 августа 2016

Я использовал для:

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

Но я нашел определенные случаи, когда это закрывало мое окно.

Недавно я заметил, что всегда использую это, когда работаю над проектом, и мне нужно быстро открыть мой .tmux.conf .zshrc, прежде чем вернуться к работе.

Для этого использования, я считаю, лучше:

  • переключиться обратно в буфер, над которым я ранее работал с C-6
  • введите :bd#, чтобы удалить предыдущий буфер (я отобразил его так: nnoremap <leader>d :bd#<CR>)

Это позволяет мне контролировать буфер, к которому я возвращаюсь, и выглядит более естественным.

2 голосов
/ 18 сентября 2009

Я не думаю, что есть способ сделать это одним выстрелом, но вы могли бы сделать :enew или :ls, чтобы вывести список своих буферов и переключиться на другой, используя :b [number].

Как только у вас появится другой буфер в окне :bd # удалит предыдущий буфер в окне, и поскольку текущий буфер все еще существует, окно не будет закрыто.

1 голос
/ 06 июля 2017

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

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

func! DeleteCurBufferNotCloseWindow() abort
    if &modified
        echohl ErrorMsg
        echom "E89: no write since last change"
        echohl None
    elseif winnr('$') == 1
        bd
    else  " multiple window
        let oldbuf = bufnr('%')
        let oldwin = winnr()
        while 1   " all windows that display oldbuf will remain open
            if buflisted(bufnr('#'))
                b#
            else
                bn
                let curbuf = bufnr('%')
                if curbuf == oldbuf
                    enew    " oldbuf is the only buffer, create one
                endif
            endif
            let win = bufwinnr(oldbuf)
            if win == -1
                break
            else        " there are other window that display oldbuf
                exec win 'wincmd w'
            endif
        endwhile
        " delete oldbuf and restore window to oldwin
        exec oldbuf 'bd'
        exec oldwin 'wincmd w'
    endif
endfunc
1 голос
/ 26 сентября 2013

Мое любимое решение для этого - плагин bufkill.vim ( GitHub ). Он предоставляет альтернативные версии различных команд :b -prefix, которые работают так же, как и их аналоги, но оставляют окно открытым. Они отображают, какой последний видимый буфер содержался, или пустой / новый буфер, если предшествующего буфера не было.

Из документации:

When you want to unload/delete/wipe a buffer, use:
  :bun/:bd/:bw to close the window as well (vim command), or
  :BUN/:BD/:BW to leave the window(s) intact (this script).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...