Chiudi automaticamente i buffer più vecchi?


9

Ho dovuto modificare molti file di recente per una piccola modifica in ciascun file. Per accedere a ciascun file, ho sfogliato NERDtree e ho aperto un file dopo l'altro. Come ho aperto sempre più file, ho notato che il mio utilizzo della memoria è cresciuto molto. Chiudere Vim mi ha restituito un sacco di memoria.

Ho installato alcuni plugin, ma sto pensando che il motivo per cui il mio utilizzo della memoria è cresciuto così drasticamente sia dovuto al numero di buffer che avevo aperto dopo alcune modifiche.

C'è un modo per limitare il numero di buffer che vim consente di aprire contemporaneamente, chiudendo automaticamente i vecchi buffer rispetto al tempo di modifica?

Risposte:


5

Risolviamo il problema, non trattiamo i sintomi. Vim non dovrebbe normalmente utilizzare grandi quantità di memoria. Sarebbe meglio isolare il problema. Alcuni consigli per aiutarti a trovare il colpevole:

  • Disabilita i plugin (usa una ricerca binaria per renderlo più veloce)
  • Riduci il tuo ~/.vimrcdown per vedere se c'è qualcosa nel problema
  • Disabilita ~/.vimrccompletamente viavim -u NONE

Vedi anche Come posso eseguire il debug del mio file vimrc?

Se trovi un bug di memoria con un plugin, contatta lo sviluppatore del plugin. Se trovi un bug di memoria con Vim, invia una segnalazione di bug con i passaggi per riprodurre l'errore. Vedere:h bugs


+1; dovrebbe essere possibile aprire un gazillion buffer in Vim allo stesso tempo ed essere comunque buono. Finché non si visualizza il buffer (in una finestra o "scheda") non viene caricato in memoria.
Martin Tournoij,

@Carpetsmoker, le variabili e le impostazioni del buffer non scompaiono quando il buffer non viene visualizzato in una finestra. Se un plug-in memorizza molte informazioni per ciascun buffer, come suggerito da Peter, la memoria potrebbe essere sprecata (considerando che l'utente finale non farà nulla di più con il buffer). A proposito: un plug-in potrebbe non archiviare i dati relativi ai buffer b:variablesma in un s:plugin[bufid]caso in cui il manutentore del plug-in preferisse non inquinare lo b: "spazio dei nomi" pubblico . In questo caso, l'eliminazione del buffer non raccoglierà necessariamente tutte le variabili / memoria correlate.
Luc Hermitte,

5

Quanto segue dovrebbe rispondere alla tua domanda.

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

Questo deve essere rilasciato in un plugin. Quindi, dovrai scegliere come usarlo.


3

Non sono sicuro di come ottenere i buffer più vecchi rispetto al tempo di modifica, ma si potrebbe invece provare a chiudere i buffer non modificati più vecchi. Qualcosa di simile a:

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()

Appunti:

  • vim.buffersè un elenco di tutti i buffer aperti nella sessione corrente, quindi include anche buffer non elencati. Non è uguale all'elenco restituito da :ls.
  • Pertanto, dobbiamo filtrare i buffer nascosti o eliminati. Questo può essere verificato usando options['buflisted'].
  • Allo stesso modo, options['modified']controlliamo se il buffer è stato modificato.
  • N è il numero di buffer elencati non modificati che si desidera aprire.

Grazie alla risposta di Luc Hermitte da cui ho imparato come ottenere i timestamp, è possibile utilizzare invece quanto segue, per ottenere prima il più vecchio inattivo eliminato:

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))

1
Non hai bisogno di Python. Vim è più che sufficiente: :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte,

@LucHermitte Vero, ma non è una questione di necessità . Non ho abbastanza familiarità con Vimscript. bwL 'aiuto di IIRC dice che non dovresti usarlo "se non sai cosa stai facendo". Io non. :)
muru,

Vecchie abitudini. Uso sempre :bwe mai :bd. Non ho mai visto il punto di eliminare quasi tutto da un buffer, ma in realtà non tutto.
Luc Hermitte,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.