Fermer automatiquement les tampons les plus anciens?

9

J'ai eu besoin d'éditer beaucoup de fichiers récemment pour un petit changement dans chaque fichier. Pour accéder à chaque fichier, j'ai parcouru NERDtree et ouvert un fichier après l'autre. En ouvrant de plus en plus de fichiers, j'ai remarqué que mon utilisation de la mémoire avait beaucoup augmenté. Fermer vim m'a redonné beaucoup de mémoire.

J'ai pas mal de plugins installés, mais je pense que la raison pour laquelle mon utilisation de la mémoire a augmenté de manière drastique est due au nombre de tampons que j'avais ouverts après quelques modifications.

Existe-t-il un moyen de limiter le nombre de tampons que vim permet d'ouvrir simultanément, fermant automatiquement les anciens tampons par rapport au temps d'édition?

TrueJournals
la source

Réponses:

5

Résolvons le problème, ne traitons pas les symptômes. Vim ne devrait normalement pas utiliser de grandes quantités de mémoire. Il serait préférable d'isoler le problème. Quelques conseils pour trouver le coupable:

  • Désactivez les plugins (utilisez une recherche binaire pour accélérer)
  • Réduisez votre ~/.vimrcduvet pour voir s'il y a un problème
  • Désactivez ~/.vimrccomplètement votre viavim -u NONE

Voir aussi Comment déboguer mon fichier vimrc?

Si vous trouvez un bug de mémoire avec un plugin, contactez le développeur du plugin. Si vous trouvez un bogue de mémoire avec Vim, soumettez un rapport de bogue avec les étapes pour reproduire l'erreur. Voir:h bugs

Peter Rincker
la source
+1; il devrait être possible d'ouvrir un gazillion de tampons dans Vim en même temps et tout de même être bon. Tant que vous ne visualisez pas le tampon (dans une fenêtre ou "onglet"), il n'est pas chargé en mémoire.
Martin Tournoij
@Carpetsmoker, les variables de tampon et les paramètres ne disparaissent pas lorsque le tampon n'est pas affiché dans une fenêtre. Si un plugin stocke beaucoup d'informations pour chaque tampon, comme Peter l'a suggéré, alors la mémoire pourrait être gaspillée (étant donné que l'utilisateur final ne fera plus rien avec le tampon). BTW: Un plugin peut ne pas stocker de données liées aux tampons b:variablesmais dans un s:plugin[bufid]si le responsable du plugin préfère ne pas polluer le b: "namespace" public . Dans ce cas, la suppression du tampon ne collectera pas nécessairement toutes les variables / mémoire associées.
Luc Hermitte
5

Ce qui suit devrait répondre à votre question.

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

Cela doit être déposé dans un plugin. Ensuite, vous devrez choisir comment l'utiliser.

Luc Hermitte
la source
3

Je ne sais pas comment obtenir les tampons les plus anciens en ce qui concerne le temps d'édition, mais on pourrait plutôt essayer de fermer les tampons les plus anciens non modifiés. Quelque chose comme:

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

Remarques:

  • vim.buffersest une liste de tous les tampons ouverts dans la session en cours, il inclut donc également les tampons non répertoriés. Ce n'est pas la même chose que la liste retournée par :ls.
  • Par conséquent, nous devons filtrer les tampons cachés ou supprimés. Cela peut être vérifié à l'aide de options['buflisted'].
  • De même, options['modified']permet de vérifier si le tampon est modifié.
  • N est le nombre de tampons répertoriés et non modifiés que vous souhaitez ouvrir.

Grâce à la réponse de Luc Hermitte à partir de laquelle j'ai appris comment obtenir les horodatages, vous pouvez utiliser les éléments suivants à la place, pour que le plus ancien inactif soit expulsé en premier:

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
la source
1
Vous n'avez pas besoin de python. Vim est plus que suffisant: :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte
@LucHermitte C'est vrai, mais ce n'est pas une question de besoin . Je ne connais pas assez Vimscript. bwL'aide de l' IIRC indique que vous ne devriez pas l'utiliser "à moins que vous sachiez ce que vous faites". Je ne. :)
muru
Vieilles habitudes. J'utilise toujours :bw, et jamais :bd. Je n'ai jamais vu l'intérêt de supprimer presque tout d'un tampon, mais pas tout.
Luc Hermitte