Fechar automaticamente os buffers mais antigos?

9

Eu precisava editar muitos arquivos recentemente para uma pequena alteração em cada arquivo. Para acessar cada arquivo, naveguei no NERDtree e abri um arquivo após o outro. Ao abrir mais e mais arquivos, notei que meu uso de memória aumentou muito. Fechar o vim me devolveu muita memória.

Eu tenho alguns plugins instalados, mas acho que o motivo pelo qual o uso da minha memória aumentou drasticamente foi devido ao número de buffers que eu abri depois de algumas edições.

Existe uma maneira de limitar o número de buffers que o vim permite que sejam abertos ao mesmo tempo, fechando automaticamente os buffers antigos em relação ao tempo de edição?

TrueJournals
fonte

Respostas:

5

Vamos resolver o problema, não tratar os sintomas. O Vim normalmente não deve usar grandes quantidades de memória. Seria melhor isolar o problema. Algumas dicas para ajudar a encontrar o culpado:

  • Desativar plug-ins (use uma pesquisa binária para torná-lo mais rápido)
  • Reduza seu ~/.vimrctempo para ver se há algum problema
  • Desative ~/.vimrccompletamente o seuvim -u NONE

Consulte também Como depurar meu arquivo vimrc?

Se você encontrar um erro de memória com um plug-in, entre em contato com o desenvolvedor do plug-in. Se você encontrar um erro de memória no Vim, envie um relatório de erro com as etapas para reproduzir o erro. Vejo:h bugs

Peter Rincker
fonte
+1; deve ser possível abrir um zilhão de buffers no Vim ao mesmo tempo e ainda assim ser bom. Contanto que você não esteja visualizando o buffer (em uma janela ou "guia"), ele não estará carregado na memória.
Martin Tournoij 25/02
@Carpetsmoker, variáveis ​​e configurações do buffer não desaparecem quando o buffer não é exibido em uma janela. Se um plug-in armazena muitas informações para cada buffer, como Peter sugeriu, a memória pode ser desperdiçada (considerando que o usuário final não fará mais nada com o buffer). Entre: Um plug-in pode não armazenar dados relacionados a buffers, b:variablesmas s:plugin[bufid]se o mantenedor do plug-in preferir não poluir o b: "espaço para nome" público . Nesse caso, a exclusão do buffer não coletará necessariamente todas as variáveis ​​/ memória relacionadas.
Luc Hermitte 25/02
5

O seguinte deve responder sua pergunta.

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

Isso deve ser descartado em um plugin. Então, você terá que escolher como usá-lo.

Luc Hermitte
fonte
3

Não sei como obter os buffers mais antigos em relação ao tempo de edição, mas, em vez disso, é possível tentar fechar os buffers mais antigos não editados. 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.buffersé uma lista de todos os buffers abertos na sessão atual, portanto, também inclui buffers não listados. Não é o mesmo que a lista retornada por :ls.
  • Portanto, devemos filtrar os buffers ocultos ou excluídos. Isso pode ser verificado usando options['buflisted'].
  • Da mesma forma, options['modified']vamos verificar se o buffer está modificado.
  • N é o número de buffers listados não modificados que você deseja abrir.

Graças à resposta de Luc Hermitte, da qual aprendi como obter os carimbos de data e hora, você pode usar o seguinte, para eliminar primeiro o inativo mais antigo:

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
fonte
11
Você não precisa de python. Vim é mais que suficiente: :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte 25/02
@ LucHermitte True, mas não é uma questão de necessidade . Só não estou familiarizado o suficiente com o Vimscript. bwA ajuda do IIRC diz que você não deve usá-lo "a menos que saiba o que está fazendo". Eu não. :)
muru
Velhos hábitos. Eu sempre uso :bw, e nunca :bd. Eu nunca vi o ponto de excluir quase tudo de um buffer, mas na verdade não tudo.
Luc Hermitte