自动关闭最旧的缓冲区?


9

最近,我需要编辑大量文件,以使每个文件有一个小的更改。为了获得每个文件,我浏览了NERDtree并打开了一个文件。随着我打开越来越多的文件,我注意到我的内存使用量增长了很多。关闭vim给了我很多记忆。

我已经安装了许多插件,但是我认为我的内存使用量之所以急剧增长的原因是经过几次编辑后打开的缓冲区数量。

有没有办法限制vim允许一次打开的缓冲区数量,并根据编辑时间自动关闭旧缓冲区?

Answers:


5

让我们解决问题,而不是治疗症状。Vim通常不应该使用大量内存。最好将问题隔离开。一些有助于找到罪魁祸首的技巧:

  • 禁用插件(使用二进制搜索使其更快)
  • 减轻~/.vimrc压力,看看其中是否有任何问题
  • ~/.vimrc通过完全禁用您的vim -u NONE

另请参阅如何调试vimrc文件?

如果发现插件存在内存错误,请与插件开发人员联系。如果您发现Vim有内存错误,请提交错误报告,并附有步骤以重现该错误。看到:h bugs


+1; 应该有可能同时在Vim中打开大量的缓冲区,并且仍然会很好。只要您不查看缓冲区(在窗口或“选项卡”中),它就不会加载到内存中。
马丁·图尔诺伊

当缓冲区未显示在窗口中时,@ Carpetsmoker,缓冲区变量和设置不会消失。如果一个插件为每个缓冲区存储了很多信息(如Peter所建议的那样),则可能会浪费内存(考虑到最终用户不会对缓冲区做更多的事情)。BTW:一个插件可以不存储在关系到缓冲器的数据b:variables,但在s:plugin[bufid]是否优先于外挂程式维护不污染公众b: “命名空间”。在这种情况下,删除缓冲区不一定会收集所有相关的变量/内存。
卢克·赫米特

5

以下应回答您的问题。

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

这将被放入插件中。然后,您必须选择如何使用它。


3

我不确定如何获得关于编辑时间最旧的缓冲区,但是可以尝试关闭最旧的未编辑缓冲区。就像是:

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

笔记:

  • vim.buffers是当前会话中打开的每个缓冲区的列表,因此它还包括未列出的缓冲区。它与传回的清单不同:ls
  • 因此,我们必须过滤掉隐藏或删除的缓冲区。可以使用检查options['buflisted']
  • 同样,options['modified']让我们检查缓冲区是否被修改。
  • N 是您要打开的未修改的列出缓冲区的数量。

感谢Luc Hermitte的答案,我从中得到了如何获取时间戳的信息,您可以使用以下代码代替,以最老的不活动方式被首先踢出:

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
您不需要python。Vim绰绰有余::let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte 2015年

@LucHermitte是的,但这不是需要的问题。我只是对Vimscript不够熟悉。IIRC bw的帮助说“除非您知道自己在做什么”,否则不应使用它。我不。:)
muru 2015年

旧习惯。我总是用:bw,从不:bd。我从未见过从缓冲区中删除几乎所有内容,但实际上不是所有内容的意义。
Luc Hermitte
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.