Älteste Puffer automatisch schließen?

9

Ich musste in letzter Zeit viele Dateien bearbeiten, um eine kleine Änderung in jeder Datei vorzunehmen. Um zu jeder Datei zu gelangen, habe ich NERDtree durchsucht und eine Datei nach der anderen geöffnet. Als ich immer mehr Dateien öffnete, bemerkte ich, dass meine Speichernutzung um ein Vielfaches zunahm. Das Schließen von vim gab mir viel Gedächtnis zurück.

Ich habe einige Plugins installiert, aber ich denke, dass der Grund, warum meine Speichernutzung so drastisch anstieg, in der Anzahl der Puffer lag, die ich nach einigen Änderungen geöffnet hatte.

Gibt es eine Möglichkeit, die Anzahl der Puffer zu begrenzen, die vim gleichzeitig öffnen darf, um alte Puffer in Bezug auf die Bearbeitungszeit automatisch zu schließen?

TrueJournals
quelle

Antworten:

5

Lassen Sie uns das Problem lösen, nicht die Symptome behandeln. Vim sollte normalerweise nicht viel Speicher verwenden. Es wäre am besten, das Problem zu isolieren. Einige Tipps, um den Täter zu finden:

  • Plugins deaktivieren (verwenden Sie eine binäre Suche, um es schneller zu machen)
  • Reduzieren Sie Ihre ~/.vimrcDaunen, um festzustellen, ob das Problem vorliegt
  • Deaktivieren Sie Ihre ~/.vimrcvollständig übervim -u NONE

Siehe auch Wie debugge ich meine vimrc-Datei?

Wenn Sie einen Speicherfehler mit einem Plugin finden, wenden Sie sich an den Plugin-Entwickler. Wenn Sie einen Speicherfehler mit Vim finden, senden Sie einen Fehlerbericht mit Schritten zur Reproduktion des Fehlers. Sehen:h bugs

Peter Rincker
quelle
+1; Es sollte möglich sein, gleichzeitig eine Unmenge Puffer in Vim zu öffnen und trotzdem gut zu sein. Solange Sie den Puffer nicht anzeigen (in einem Fenster oder "Tab"), wird er nicht in den Speicher geladen.
Martin Tournoij
@Carpetsmoker, Puffervariablen und Einstellungen verschwinden nicht, wenn der Puffer nicht in einem Fenster angezeigt wird. Wenn ein Plugin viele Informationen für jeden Puffer speichert, wie Peter vorgeschlagen hat, kann Speicherplatz verschwendet werden (wenn man bedenkt, dass der Endbenutzer mit dem Puffer nichts mehr macht). Übrigens: Ein Plugin speichert möglicherweise keine Daten, die sich auf Puffer beziehen, b:variablesin einem, s:plugin[bufid]wenn der Plugin-Betreuer es vorgezogen hat, den öffentlichen b: "Namespace" nicht zu verschmutzen . In diesem Fall werden beim Löschen des Puffers nicht unbedingt alle zugehörigen Variablen / Speicher erfasst.
Luc Hermitte
5

Das Folgende sollte Ihre Frage beantworten.

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

Dies ist in einem Plugin abzulegen. Dann müssen Sie auswählen, wie Sie es verwenden möchten.

Luc Hermitte
quelle
3

Ich bin nicht sicher, wie ich die ältesten Puffer in Bezug auf die Bearbeitungszeit erhalten soll, aber man könnte stattdessen versuchen, die ältesten unbearbeiteten Puffer zu schließen. Etwas wie:

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

Anmerkungen:

  • vim.buffersist eine Liste aller in der aktuellen Sitzung geöffneten Puffer, enthält also auch nicht aufgelistete Puffer. Es ist nicht dasselbe wie die von zurückgegebene Liste :ls.
  • Daher müssen wir die versteckten oder gelöschten Puffer herausfiltern. Dies kann mit überprüft werden options['buflisted'].
  • In ähnlicher Weise options['modified']können wir überprüfen, ob der Puffer geändert wurde.
  • N ist die Anzahl der unveränderten, aufgelisteten Puffer, die geöffnet werden sollen.

Dank der Antwort von Luc Hermitte, aus der ich gelernt habe, wie man die Zeitstempel erhält, können Sie stattdessen Folgendes verwenden, um den ältesten inaktiven zuerst rauszuschmeißen:

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
quelle
1
Du brauchst kein Python. Vim ist mehr als genug: :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte
@ LucHermitte Stimmt, aber es ist keine Frage der Notwendigkeit . Ich bin mit Vimscript einfach nicht vertraut genug. bwDie Hilfe des IIRC besagt, dass Sie es nicht verwenden sollten, "es sei denn, Sie wissen, was Sie tun". Ich nicht. :)
Muru
Alte Gewohnheiten. Ich benutze immer :bwund nie :bd. Ich habe noch nie den Sinn gesehen, fast alles aus einem Puffer zu löschen, aber eigentlich nicht alles.
Luc Hermitte