Czy automatycznie zamykasz najstarsze bufory?

9

Musiałem ostatnio edytować wiele plików, aby wprowadzić niewielką zmianę w każdym z nich. Aby dostać się do każdego pliku, przejrzałem NERDtree i otworzyłem jeden plik po drugim. Gdy otwierałem coraz więcej plików, zauważyłem, że moje użycie pamięci znacznie wzrosło. Zamknięcie vima przywróciło mi wiele pamięci.

Mam zainstalowanych sporo wtyczek, ale myślę, że przyczyną tak drastycznego zużycia pamięci była liczba buforów, które otworzyłem po kilku edycjach.

Czy istnieje sposób na ograniczenie liczby buforów, które vim pozwala otworzyć jednocześnie, automatycznie zamykając stare bufory w odniesieniu do czasu edycji?

TrueJournals
źródło

Odpowiedzi:

5

Rozwiążmy problem, nie leczmy objawów. Vim nie powinien normalnie używać dużej ilości pamięci. Najlepiej byłoby wyodrębnić problem. Kilka wskazówek, które pomogą znaleźć winowajcę:

  • Wyłącz wtyczki (użyj wyszukiwania binarnego, aby przyspieszyć)
  • Zmniejsz swój ~/.vimrcdół, aby zobaczyć, czy coś w tym jest problem
  • Wyłącz ~/.vimrccałkowicie przezvim -u NONE

Zobacz także Jak debugować mój plik vimrc?

Jeśli znajdziesz błąd pamięci związany z wtyczką, skontaktuj się z twórcą wtyczki. Jeśli znajdziesz błąd pamięci w Vimie, prześlij zgłoszenie błędu wraz z krokami, aby odtworzyć błąd. Widzieć:h bugs

Peter Rincker
źródło
+1; powinno być możliwe jednoczesne otwieranie buforów gazillionowych w Vimie i nadal być dobre. Dopóki nie przeglądasz bufora (w oknie lub „zakładce”), nie jest on ładowany do pamięci.
Martin Tournoij,
@Carpetsmoker, zmienne i ustawienia bufora nie znikają, gdy bufor nie jest wyświetlany w oknie. Jeśli wtyczka przechowuje wiele informacji dla każdego bufora, jak sugerował Peter, pamięć może zostać zmarnowana (biorąc pod uwagę, że użytkownik końcowy nie zrobi nic więcej z buforem). BTW: Wtyczka może nie przechowywać danych związanych z buforami w, b:variablesale s:plugin[bufid]jeśli opiekun wtyczki wolał nie zanieczyszczać publicznej b: „przestrzeni nazw” . W takim przypadku usunięcie bufora niekoniecznie zbierze wszystkie powiązane zmienne / pamięć.
Luc Hermitte,
5

Następujące powinny odpowiedzieć na twoje pytanie.

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

To należy upuścić do wtyczki. Następnie musisz wybrać sposób jego użycia.

Luc Hermitte
źródło
3

Nie jestem pewien, jak uzyskać najstarsze bufory w odniesieniu do czasu edycji, ale zamiast tego można spróbować zamknąć najstarsze niezbadane bufory. Coś jak:

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

Uwagi:

  • vim.buffersjest listą każdego bufora otwartego w bieżącej sesji, więc zawiera także bufory niepubliczne. To nie to samo, co lista zwrócona przez :ls.
  • Dlatego musimy odfiltrować ukryte lub usunięte bufory. Można to sprawdzić za pomocą options['buflisted'].
  • Podobnie, options['modified']sprawdźmy, czy bufor jest zmodyfikowany.
  • N to liczba niezmodyfikowanych, wymienionych buforów, które chcesz otworzyć.

Dzięki odpowiedzi Luca Hermitte'a, z której dowiedziałem się, jak uzyskać znaczniki czasu, możesz zamiast tego skorzystać z następujących opcji, aby najpierw wyrzucić najstarszego nieaktywnego:

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
źródło
1
Nie potrzebujesz pytona. Vim to więcej niż wystarczające: :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
Luc Hermitte
@LucHermitte Prawda, ale to nie jest kwestia potrzeby . Po prostu nie znam się dobrze na Vimscript. bwPomoc IIRC mówi, że nie powinieneś go używać „, chyba że wiesz, co robisz”. Ja nie. :)
muru
Stare zwyczaje. Zawsze używam :bwi nigdy :bd. Nigdy nie widziałem sensu usuwania prawie wszystkiego z bufora, ale nie wszystkiego.
Luc Hermitte,