Como posso fechar um buffer sem fechar a janela?

120

As visualizações em várias camadas do Vim (Windows, Buffers e Tabs) me deixaram um pouco confuso. Digamos que eu divida a exibição (: sp) e selecione um buffer diferente para exibir em cada janela. Agora eu quero fechar um dos buffers, mas não quero que a janela feche (após o fechamento, pode exibir o próximo buffer da lista ou um buffer vazio, não importa). Como posso fazer isso?

Obrigado.

Mosh
fonte
Existe um motivo pelo qual você deseja fechar o buffer em vez de simplesmente não vê-lo mais lá?
aumento de
9
Na verdade, também estive pensando sobre isso. Excluir um buffer e ter que reconstruir subsequentemente qualquer parte das minhas divisões que foram destruídas no processo é irritante.
brettkelly
3
29 votos positivos até agora. Acho que este é um caso de uso bastante comum. Eu preciso disso quando estou trabalhando com muitos buffers. Às vezes estou usando 2 janelas e quero fechar um buffer. Não quero que essa janela vá embora. Eu só quero que o próximo buffer seja exibido lá.
Wilson Freitas
possível duplicata do Vim: Excluir buffer sem perder a janela dividida
George Hilliard

Respostas:

145

Eu baguncei um pouco com isso e finalmente descobri:

:bp | sp | bn | bd

Esta é a versão copiar / colar para mapeamento de teclas:

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

Eu testei bastante e funciona de forma consistente em várias condições. Quando usado no último buffer, ele deixará você com um novo buffer em branco.

Jogue isso em seu .vimrc:

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

Reinicie o Vim ou apenas :source ~/.vimrcpara que as alterações tenham efeito. Da próxima vez que você quiser fechar um buffer, basta digitar: \q(se \for a sua chave líder)

Jonah Braun
fonte
1
Obrigado! Agradável e simples, diferente de quase todas as outras soluções que já vi.
jwd
16
Para o novato, jogar isso no seu .vimrc : map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>. Reinicie o VIM, da próxima vez que você quiser fechar um buffer, basta digitar:\q
EasyCo
5
Isso terá um resultado inesperado se você tiver uma janela dividida verticalmente. Na verdade, qualquer configuração de divisão de janela diferente do padrão (criada por sp).
hitzg
2
Acho que o snippet do que inserir em .vimrc não deve incluir o ponto final. Fora isso, incrível! Esta deve ser a resposta aceita.
Ernesto
3
isso é elegante. como outras pessoas disseram, se você usa principalmente divisões verticais, troque spcom vsp. minha entrada .vimrc se parece com isto:cnoremap bd bp<bar>vsp<bar>bn<bar>bd
Connor
38

Eu pesquisei por isso hoje e encontrei

:b#|bd#

que muda a janela atual para o buffer aberto anteriormente e apaga / oculta o buffer do qual você acabou de trocar.

Isso requer pelo menos dois buffers conhecidos.

Se outra janela, mas a atual mostrar o mesmo buffer, isso ainda destruirá a divisão. Você pode alterar todas as janelas para o buffer aberto anteriormente com

:windo b#

Eu adicionei mais detalhes sobre o comando anterior que discute um mapeamento para ele (e algumas armadilhas) em uma resposta a uma pergunta semelhante .

válido
fonte
Isso também pode ser feito ... :#b|#bdBasta trocar o comando do buffer e o número do buffer acima.
Ashish
Eu usei isso um pouco, mas fiquei ficando irritado porque ele reabriu um buffer fechado anteriormente.
pean
@pean Isso é o que mencionei na resposta vinculada - consulte "Observações importantes". Sim, seria melhor se isso mudasse para outro buffer aberto.
válido em
1
Você também pode fazer :bn|bd#ou :bp|bd#alternar para o buffer aberto anterior ou seguinte, respectivamente, em vez do buffer que você acessou mais recentemente (b #).
pavon
12
nmap <leader>d :bprevious<CR>:bdelete #<CR>

Funciona como deveria até que um buffer seja aberto em várias janelas. Bom o suficiente, a menos que você queira usar os scripts maiores que existem.

Editar: é isso que eu uso agora:

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
ggustafsson
fonte
1
Tentei desta forma, mas não funcionou muito bem ao usar várias janelas divididas. Aqui está minha solução se alguém está tendo o mesmo problema:nmap <leader>d :ene<CR>:bd #<CR>
caio
7

Acho que é isso que você está procurando

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

Experimente isto:

Procure seu id de buffer usando

:buffers

você verá uma lista de buffers como

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

se você deseja remover b.py do buffer

:2bw

se você deseja remover / fechar todos os buffers

:1,3bw
Não
fonte
1
Eu não quero mover a janela. Quero fechar o buffer sem tocar na posição, tamanho ou existência da janela.
Mosh
5

Para quem usa NERDTree.

Corrijo isso usando este plugin https://github.com/jistr/vim-nerdtree-tabs e agora posso fechar o único buff / arquivo / guia sem fechar a janela.

Depois de instalar o plugin acima, coloque o seguinte código no meu .vimrc:

let g:nerdtree_tabs_autoclose=0

A descrição da variável acima é: Feche a guia atual se houver apenas uma janela nela e for NERDTree (padrão 1)

Mais informações aqui: https://github.com/jistr/vim-nerdtree-tabs#configuration

Lucas serafim
fonte
2

Não acho que haja uma maneira única de fazer isso, mas você pode fazer :enewou :lslistar seus buffers e trocar para um diferente usando :b [number].

Uma vez que você tenha um buffer diferente na janela :bd #, o buffer anterior será excluído da janela e, como o buffer atual ainda existe, a janela não será fechada.

Andrew Khosravian
fonte
2

Eu costumava usar :

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

Mas descobri certas ocasiões em que fechou minha janela.

Recentemente, percebi que sempre uso isso quando estou trabalhando em um projeto e preciso abrir o meu rapidamente .tmux.conf .zshrcantes de voltar ao trabalho.

Para este uso, acho melhor:

  • voltar para o buffer em que estava trabalhando anteriormente C-6
  • digite :bd#para eliminar o tampão anterior (I mapearam-lo assim: nnoremap <leader>d :bd#<CR>)

Isso me permite controlar o buffer para o qual estou voltando e parece mais natural.

DaftWooly
fonte
1

Seria

:enew

faça o que você quiser? ele editará um novo buffer sem nome na janela atual, deixando o arquivo existente aberto em qualquer outra janela.

Mikej
fonte
Isso abrirá um novo buffer vazio. Quero fechar o buffer atual sem fechar a janela.
Mosh
1

Minha solução favorita para isso é o plugin bufkill.vim ( GitHub ). Ele fornece versões alternativas dos vários:b comandos -prefix que funcionam da mesma forma que suas contrapartes, mas deixam a janela aberta. Eles exibem qualquer que seja o último buffer visível contido, ou um buffer vazio / novo se não houver nenhum buffer anterior.

Da documentação:

Quando você deseja descarregar / excluir / limpar um buffer, use:
  : bun /: bd /: bw para fechar a janela também (comando vim), ou
  : BUN /: BD /: BW para deixar a (s) janela (s) intacta (s) (este script).
Jim Stewart
fonte
1

Para 'fechar' uma visualização, use :hid[e]. Funciona se você conseguiu dividir a janela de exibição ou abriu vários arquivos. Você não pode ocultar o último buffer em exibição.

1 Outra dica que me ajudou: use :e ./path/to/file.workpara abrir um arquivo no viewport sem dividir a janela.

PS Depois de dois dias no vim, ainda tenho problemas para encontrar os comandos de ajuda precisos. Espero que isso ajude alguém a continuar trabalhando até que consiga realmente tempo para entender o vim.

Sennekuyl
fonte
1

Aqui está uma função vimscript muito legível, que lida bem com todos os casos ,

  • se comportar de forma semelhante ao integrado :bd(se apenas uma janela, basta invocá-la!),
    • emitir um aviso e não fazer nada se o buffer for modificado.
    • se não houver outro buffer, crie um, via :enew.
    • se houver buffer alternativo e buffer-listestiver ativado, mude para ele, senão vá em seguida, via :bn.
  • comportamento mais razoável para layout de múltiplas janelas
    • não fechando nenhuma janela,
    • sempre fique na janela original.
    • para cada janela que exibe o buffer atual, siga as instruções acima e exclua o buffer atual antigo.
nnoremap <Leader> b: chame DeleteCurBufferNotCloseWindow () <CR>

func! DeleteCurBufferNotCloseWindow () abortar
    se & modificado
        echohl ErrorMsg
        echom "E89: nenhuma gravação desde a última alteração"
        echohl Nenhum
    elseif winnr ('$') == 1
        bd
    senão "janela múltipla
        deixe oldbuf = bufnr ('%')
        deixe oldwin = winnr ()
        enquanto 1 "todas as janelas que exibem oldbuf permanecerão abertas
            se buflisted (bufnr ('#'))
                b #
            outro
                bn
                deixe curbuf = bufnr ('%')
                if curbuf == oldbuf
                    enew "oldbuf é o único buffer, crie um
                fim se
            fim se
            deixe win = bufwinnr (oldbuf)
            se ganhar == -1
                pausa
            else "há outra janela que exibe oldbuf
                exec win 'wincmd w'
            fim se
        no fim
        "excluir oldbuf e restaurar janela para oldwin
        exec oldbuf 'bd'
        exec oldwin 'wincmd w'
    fim se
endfunc
qeatzy
fonte
0

Se você é como eu e veio aqui tentando fazer o contrário , feche a janela sem fechar o buffer, você pode fazer isso via:

:close

xdhmoore
fonte
0

Uma versão simples que eu uso pessoalmente é

:bp|bd#

Ele vai para o buffer anterior e exclui o outro buffer (que na verdade é o original de onde saltamos). Isso faz o que você esperaria em 99% dos casos, sem scripts complicados.

Como um atalho de teclado, uso o seguinte

nnoremap <silent> <Leader>c :bp<BAR>bd#<CR>
Dorian B.
fonte
-5

use ": bd" como um comando.

Silvanus
fonte