Secara otomatis menutup buffer terlama?

9

Saya perlu mengedit banyak file baru-baru ini untuk perubahan kecil di setiap file. Untuk sampai ke setiap file, saya melihat-lihat NERDtree dan membuka satu file demi satu. Ketika saya membuka semakin banyak file, saya perhatikan bahwa penggunaan memori saya bertambah banyak. Penutupan vim memberi saya banyak memori kembali.

Saya telah menginstal beberapa plugin, tetapi saya berpikir bahwa alasan penggunaan memori saya tumbuh secara drastis adalah karena jumlah buffer yang saya buka setelah beberapa pengeditan.

Apakah ada cara untuk membatasi jumlah buffer yang memungkinkan vim untuk dibuka pada satu waktu, secara otomatis menutup buffer lama sehubungan dengan waktu pengeditan?

Jurnal Sejati
sumber

Jawaban:

5

Mari kita selesaikan masalahnya, bukan mengobati gejalanya. Vim seharusnya tidak menggunakan memori dalam jumlah besar. Akan lebih baik mengisolasi masalah ini. Beberapa tips untuk membantu menemukan pelakunya:

  • Nonaktifkan plugin (gunakan pencarian biner untuk membuatnya lebih cepat)
  • Kurangi ~/.vimrcdown Anda untuk melihat apakah ada masalah di sana
  • Nonaktifkan ~/.vimrcsepenuhnya Anda melaluivim -u NONE

Juga lihat Bagaimana cara men-debug file vimrc saya?

Jika Anda menemukan bug memori dengan plugin, maka hubungi pengembang plugin. Jika Anda menemukan bug memori dengan Vim kemudian kirimkan laporan bug dengan langkah-langkah untuk mereproduksi kesalahan. Lihat:h bugs

Peter Rincker
sumber
+1; harus dimungkinkan untuk membuka trilyun penyangga di Vim pada saat yang sama dan masih bagus. Selama Anda tidak melihat buffer (di jendela, atau "tab") itu tidak dimuat dalam memori.
Martin Tournoij
@Carpetsmoker, variabel buffer, dan pengaturan tidak hilang saat buffer tidak ditampilkan di jendela. Jika sebuah plugin menyimpan banyak informasi untuk setiap buffer, seperti yang disarankan Peter, maka memori dapat terbuang sia-sia (mengingat pengguna akhir tidak akan melakukan apa-apa lagi dengan buffer). BTW: Sebuah plugin mungkin tidak menyimpan data yang terkait dengan buffer di b:variablestetapi dalam s:plugin[bufid]jika pengelola plugin lebih suka untuk tidak mencemari b: "namespace" publik . Dalam hal ini, menghapus buffer tidak harus mengumpulkan semua variabel / memori yang terkait.
Luc Hermitte
5

Yang berikut harus menjawab pertanyaan Anda.

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

Ini akan dimasukkan ke dalam plugin. Kemudian, Anda harus memilih cara menggunakannya.

Luc Hermitte
sumber
3

Saya tidak yakin bagaimana cara mendapatkan buffer tertua sehubungan dengan waktu pengeditan, tetapi orang bisa, sebaliknya, mencoba untuk menutup buffer yang belum diedit yang tertua. Sesuatu seperti:

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

Catatan:

  • vim.buffersadalah daftar setiap buffer yang dibuka di sesi saat ini, sehingga juga termasuk buffer yang tidak terdaftar. Ini tidak sama dengan daftar yang dikembalikan oleh :ls.
  • Karena itu, kita harus memfilter buffer yang tersembunyi atau dihapus. Ini dapat diperiksa menggunakan options['buflisted'].
  • Demikian pula, options['modified']mari kita periksa apakah buffer diubah.
  • N adalah jumlah buffer terdaftar yang tidak dimodifikasi yang ingin Anda buka.

Berkat jawaban Luc Hermitte dari mana saya belajar cara mendapatkan stempel waktu, Anda dapat menggunakan yang berikut ini, untuk mengeluarkan yang tidak aktif terlama dulu:

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
sumber
1
Anda tidak perlu python. Vim lebih dari cukup: :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte
@LucHermitte Benar, tapi itu bukan masalah kebutuhan . Saya hanya tidak cukup akrab dengan Vimscript. bwBantuan IIRC mengatakan Anda tidak boleh menggunakannya "kecuali Anda tahu apa yang Anda lakukan". Bukan saya. :)
muru
Kebiasaan lama. Saya selalu menggunakan :bw, dan tidak pernah :bd. Saya belum pernah melihat titik menghapus hampir semua dari buffer, tetapi sebenarnya tidak semuanya.
Luc Hermitte