¿Cómo puedo cerrar un búfer sin cerrar la ventana?

120

Las vistas de varias capas de Vim (Windows, Buffers y Tabs) me dejaron un poco confundido. Digamos que divido la pantalla (: sp) y luego selecciono un búfer diferente para mostrar en cada ventana. Ahora quiero cerrar uno de los búferes, pero no quiero que la ventana se cierre (después del cierre, puede mostrar el siguiente búfer de la lista o un búfer vacío, no importa). ¿Cómo puedo hacer esto?

Gracias.

Mosh
fuente
¿Hay alguna razón por la que desee cerrar el búfer en lugar de dejar de verlo allí?
rampion
9
De hecho, también me he estado preguntando sobre esto. Eliminar un búfer y tener que reconstruir posteriormente cualquier parte de mis divisiones que se destruyó en el proceso es molesto.
brettkelly
3
29 votos a favor hasta ahora. Creo que este es un caso de uso bastante común. Necesito esto cuando estoy trabajando con muchos búferes. A veces estoy usando 2 ventanas y quiero cerrar un búfer. No quiero que esa ventana desaparezca. Solo quiero que se muestre el siguiente búfer allí.
Wilson Freitas
posible duplicado de Vim: eliminar búfer sin perder la ventana dividida
George Hilliard
Este DeleteCurBufferNotCloseWindow()funciona bien y es bastante legible . (Descargo de responsabilidad: mi respuesta)
qeatzy

Respuestas:

145

Me metí un poco con esto y finalmente se me ocurrió:

:bp | sp | bn | bd

Aquí está la versión de copiar / pegar para la asignación de teclas:

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

Lo he probado bastante y funciona de manera constante en varias condiciones. Cuando se usa en el último búfer, le dejará un nuevo búfer en blanco.

Lanza esto en tu .vimrc:

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

Reinicie Vim o simplemente :source ~/.vimrcpara que los cambios surtan efecto. La próxima vez que desee cerrar un búfer, simplemente escriba: \q(si \es su clave principal)

Jonah Braun
fuente
1
¡Gracias! Agradable y simple, a diferencia de casi todas las demás soluciones que he visto.
jwd
16
Para el principiante, lanzar esto en su .vimrc : map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>. Reinicie VIM, la próxima vez que desee cerrar un búfer, simplemente escriba:\q
EasyCo
5
Esto tendrá un resultado inesperado si tuviera una ventana dividida verticalmente. De hecho, cualquier configuración de división de ventanas que no sea la estándar (creada por sp).
hitzg
2
Creo que el fragmento de qué poner en .vimrc no debe incluir el punto al final. Aparte de eso, ¡increíble! Esta debería ser la respuesta aceptada.
Ernesto
3
esto es elegante. como han dicho otras personas, si usa principalmente divisiones verticales, cambie spcon vsp. mi entrada .vimrc se ve así:cnoremap bd bp<bar>vsp<bar>bn<bar>bd
Connor
38

Busqué esto hoy y se me ocurrió

:b#|bd#

que cambia la ventana actual al búfer previamente abierto y elimina / oculta el búfer del que acaba de cambiar.

Esto requiere al menos dos búferes conocidos.

Si otra ventana, pero la actual muestra el mismo búfer, esto aún destruirá la división. Puede cambiar todas las ventanas al búfer previamente abierto con

:windo b#

Agregué más detalles sobre el comando anterior discutiendo un mapeo para él (y algunas trampas) en una respuesta a una pregunta similar .

válido
fuente
También esto se puede hacer ... :#b|#bdSimplemente intercambiando el comando de búfer y el número de búfer en lo anterior.
Ashish
He usado esto un poco, pero me seguía molestando que volviera a abrir un búfer previamente cerrado.
pean
@pean Eso es lo que mencioné en la respuesta vinculada; consulte "Notas importantes". Sí, sería mejor si esto cambiara a otro búfer abierto.
válido el
1
También puede hacer :bn|bd#o :bp|bd#cambiar al búfer abierto anterior o siguiente, respectivamente, en lugar del búfer al que accedió más recientemente (b #).
Pabellón
12
nmap <leader>d :bprevious<CR>:bdelete #<CR>

Funciona como debería hasta que se abre un búfer en varias ventanas. Lo suficientemente bueno a menos que desee utilizar los scripts más grandes que existen.

Editar: esto es lo que uso ahora:

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
fuente
1
Intenté de esta manera pero no funcionó muy bien al usar múltiples ventanas divididas. Aquí está mi solución si alguien tiene el mismo problema:nmap <leader>d :ene<CR>:bd #<CR>
caio
7

Creo que esto es lo que estas buscando

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

Prueba esto:

Mire su identificación de búfer usando

:buffers

verá una lista de búferes allí como

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

si desea eliminar b.py del búfer

:2bw

si desea eliminar / cerrar todos los búferes

:1,3bw
No
fuente
1
No quiero mover la ventana. Quiero cerrar el búfer sin tocar la posición, el tamaño o la existencia de la ventana.
Mosh
5

Para aquellos que usan NERDTree.

Solucioné esto usando este complemento https://github.com/jistr/vim-nerdtree-tabs y ahora puedo cerrar el único buff / file / tab sin cerrar la ventana.

Después de tener instalado el complemento anterior, coloque el siguiente código en mi .vimrc:

let g:nerdtree_tabs_autoclose=0

La descripción de la variable anterior es: Cerrar la pestaña actual si solo hay una ventana en ella y es NERDTree (predeterminado 1)

Más información aquí: https://github.com/jistr/vim-nerdtree-tabs#configuration

Lucas Serafim
fuente
2

No creo que haya una manera única de hacer esto, pero podrías hacerlo :enewo :lslistar tus búferes y cambiar a uno diferente usando :b [number].

Una vez que tenga un búfer diferente en la ventana, :bd #se eliminará el búfer anterior en la ventana, y dado que el búfer actual todavía existe, la ventana no se cerrará.

Andrew Khosravian
fuente
2

Solía ​​usar :

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

Pero encontré ciertas ocasiones en las que cerraba mi ventana.

Recientemente me di cuenta de que siempre uso esto cuando estoy trabajando en un proyecto y necesito abrir rápidamente mi .tmux.conf .zshrcantes de volver al trabajo.

Para este uso, encuentro mejor:

  • volver al búfer con el que estaba trabajando anteriormente C-6
  • escribir :bd#para borrar el buffer anterior (He mapeado de esta manera: nnoremap <leader>d :bd#<CR>)

Me permite controlar el búfer al que vuelvo y se siente más natural.

DaftWooly
fuente
1

haría

:enew

¿Haz lo que quieras? editará un búfer nuevo sin nombre en la ventana actual dejando el archivo existente abierto en cualquier otra ventana.

mikej
fuente
Esto abrirá un nuevo búfer vacío. Quiero cerrar el búfer actual sin cerrar la ventana.
Mosh
1

Mi solución favorita para esto es el complemento bufkill.vim ( GitHub ). Proporciona versiones alternativas de los distintos:b comandos -prefix que funcionan igual que sus contrapartes, pero dejan la ventana abierta. Muestran lo que contenga el último búfer visible, o un búfer nuevo / vacío si no había búfer anterior.

De la documentación:

Cuando desee descargar / eliminar / limpiar un búfer, use:
  : bun /: bd /: bw para cerrar la ventana también (comando vim), o
  : BUN /: BD /: BW para dejar las ventanas intactas (este script).
Jim Stewart
fuente
1

Para 'cerrar' una vista, use :hid[e]. Funciona si ha logrado dividir la ventana gráfica o ha abierto varios archivos. No puede ocultar el último búfer en pantalla.

1 Otro consejo que me ayudó: utilícelo :e ./path/to/file.workpara abrir un archivo en la ventana gráfica sin dividir la ventana.

PD: A los dos días de vim todavía tengo problemas para encontrar los comandos de ayuda precisos. Con suerte, esto ayudará a alguien más a seguir trabajando hasta que realmente tenga tiempo para entender vim.

Sennekuyl
fuente
1

Aquí hay una función vimscript muy legible, que maneja bien todos los casos ,

  • se comporta de manera similar a la incorporada :bd(si solo hay una ventana, ¡simplemente invocala!),
    • emitir una advertencia y no hacer nada si se modifica el búfer.
    • si no hay otro búfer, cree uno, a través de :enew.
    • si existe un búfer alternativo y en buffer-list, cámbielo, de lo contrario, vaya a través de :bn.
  • comportamiento más razonable para el diseño de múltiples ventanas
    • sin cerrar ninguna ventana,
    • permanezca siempre en la ventana original.
    • para cada ventana que muestre el búfer actual, haga lo que se indica arriba y luego elimine el búfer actual antiguo.
nnoremap <Leader> b: llama DeleteCurBufferNotCloseWindow () <CR>

func! DeleteCurBufferNotCloseWindow () abortar
    si & modificado
        echohl ErrorMsg
        echom "E89: no se ha escrito desde el último cambio"
        echohl Ninguno
    elseif winnr ('$') == 1
        bd
    else "ventana múltiple
        deje oldbuf = bufnr ('%')
        deja oldwin = winnr ()
        mientras que 1 "todas las ventanas que muestran oldbuf permanecerán abiertas
            si está en la lista de búfer (bufnr ('#'))
                si#
            más
                bn
                deje curbuf = bufnr ('%')
                si curbuf == oldbuf
                    enew "oldbuf es el único búfer, cree uno
                terminara si
            terminara si
            deja ganar = bufwinnr (oldbuf)
            si gana == -1
                descanso
            else "hay otra ventana que muestra oldbuf
                ejecutivo gana 'wincmd w'
            terminara si
        terminar mientras
        "eliminar oldbuf y restaurar la ventana a oldwin
        exec oldbuf 'bd'
        ejecutivo oldwin 'wincmd w'
    terminara si
endfunc
qeatzy
fuente
0

Si eres como yo y viniste aquí tratando de hacer lo contrario , cierra la ventana sin cerrar el búfer, puedes hacerlo a través de:

:close

xdhmoore
fuente
0

Una versión simple que uso personalmente es

:bp|bd#

Va al búfer anterior y borra el otro búfer (que en realidad es el original desde donde saltamos). Esto hace lo que cabría esperar en el 99% de los casos sin guiones complicados.

Como atajo de teclado utilizo lo siguiente

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

utilice ": bd" como comando.

Silvanus
fuente