¿Cerrar automáticamente los tampones más antiguos?

9

Necesitaba editar muchos archivos recientemente para un pequeño cambio en cada archivo. Para acceder a cada archivo, examiné NERDtree y abrí un archivo tras otro. A medida que abría más y más archivos, noté que mi uso de memoria creció MUCHO. Cerrar vim me devolvió un montón de memoria.

Tengo bastantes complementos instalados, pero creo que la razón por la que mi uso de memoria creció tan drásticamente se debió a la cantidad de búferes que había abierto después de algunas ediciones.

¿Hay alguna manera de limitar el número de buffers que vim permite que se abran al mismo tiempo, cerrando automáticamente los viejos buffers con respecto al tiempo de edición?

TrueJournals
fuente

Respuestas:

5

Solucionemos el problema, no tratemos los síntomas. Vim normalmente no debería usar grandes cantidades de memoria. Sería mejor aislar el problema. Algunos consejos para ayudar a encontrar al culpable:

  • Deshabilite los complementos (use una búsqueda binaria para hacerlo más rápido)
  • Disminuya la ~/.vimrcvelocidad para ver si hay algún problema.
  • Desactiva tu ~/.vimrccompletamente a través devim -u NONE

Consulte también ¿Cómo depuro mi archivo vimrc?

Si encuentra un error de memoria con un complemento, póngase en contacto con el desarrollador del complemento. Si encuentra un error de memoria con Vim, envíe un informe de error con los pasos para reproducir el error. Ver:h bugs

Peter Rincker
fuente
+1; Debería ser posible abrir una gran cantidad de buffers en Vim al mismo tiempo y seguir siendo bueno. Mientras no esté viendo el búfer (en una ventana o "pestaña") no está cargado en la memoria.
Martin Tournoij
@Carpetsmoker, las variables y configuraciones del búfer no desaparecen cuando el búfer no se muestra en una ventana. Si un complemento almacena mucha información para cada búfer, como Peter sugirió, entonces la memoria podría desperdiciarse (considerando que el usuario final no hará nada más con el búfer). Por cierto: es posible que un complemento no almacene datos relacionados con buffers, b:variablespero s:plugin[bufid]si el encargado del complemento prefiere no contaminar el b: "espacio de nombres" público . En este caso, eliminar el búfer no necesariamente recopilará todas las variables / memoria relacionadas.
Luc Hermitte
5

Lo siguiente debería responder a su pregunta.

function! s:SortTimeStamps(lhs, rhs)
  return a:lhs[1] > a:rhs[1] ? 1 
     \   a:lhs[1] < a:rhs[1] ? -1
     \                       : 0
endfunction

function! s:Close(nb_to_keep)
  let saved_buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')
  let times = map(copy(saved_buffers), '[(v:val), getftime(bufname(v:val))]')
  call filter(times, 'v:val[1] > 0')
  call sort(times, function('s:SortTimeStamps'))
  let nb_to_keep = min([a:nb_to_keep, len(times)])
  let buffers_to_strip = map(copy(times[0:(nb_to_keep-1)]), 'v:val[0]')
  exe 'bw '.join(buffers_to_strip, ' ') 
endfunction

" Two ways to use it
" - manually
command! -nargs=1 CloseOldBuffers call s:Close(<args>)
" - or automatically
augroup CloseOldBuffers
  au!
  au BufNew * call s:Close(g:nb_buffers_to_keep)
augroup END
" and don't forget to set the option in your .vimrc
let g:nb_buffers_to_keep = 42

Esto se debe colocar en un complemento. Luego, tendrás que elegir cómo usarlo.

Luc Hermitte
fuente
3

No estoy seguro de cómo obtener los buffers más antiguos con respecto al tiempo de edición, pero uno podría, en cambio, tratar de cerrar los buffers más antiguos sin editar. Algo como:

function CloseLast ()
    python <<EOF
import vim
N = 10
listed_buffers = [b for b in vim.buffers if b.options['buflisted'] and not b.options['modified']]
for i in range (0, len (listed_buffers) - N):
    vim.command (':bd' + str (listed_buffers[i].number))
EOF
endfunction

autocmd BufNew * call CloseLast()

Notas:

  • vim.bufferses una lista de cada búfer abierto en la sesión actual, por lo que también incluye búferes no listados. No es lo mismo que la lista devuelta por :ls.
  • Por lo tanto, debemos filtrar los búferes ocultos o eliminados. Esto se puede verificar usando options['buflisted'].
  • Del mismo modo, options['modified']nos permite verificar si el búfer está modificado.
  • N es la cantidad de búferes listados no modificados que desea abrir.

Gracias a la respuesta de Luc Hermitte de la que aprendí cómo obtener las marcas de tiempo, podría usar lo siguiente en su lugar, para eliminar primero al inactivo más antiguo:

listed_buffers = (b for b in vim.buffers if b.options['buflisted'] and not b.options['modified'])
oldest_buffers = sorted (listed_buffers, key = lambda b: eval('getftime("' + b.name + '")'))
for i in range (0, len (oldest_buffers) - N):
    vim.command (':bd' + str (oldest_buffers[i].number))
muru
fuente
1
No necesitas python. Vim es más que suficiente: :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte
@LucHermitte True, pero no es una cuestión de necesidad . Simplemente no estoy lo suficientemente familiarizado con Vimscript. bwLa ayuda del IIRC dice que no debe usarlo "a menos que sepa lo que está haciendo". Yo no. :)
muru
Viejos hábitos. Yo siempre uso :bw, y nunca :bd. Nunca he visto el punto de eliminar casi todo de un búfer, pero en realidad no todo.
Luc Hermitte