가장 오래된 버퍼를 자동으로 닫습니까?


9

최근에 각 파일을 약간 변경하기 위해 많은 파일을 편집해야했습니다. 각 파일에 도달하기 위해 NERDtree를 탐색하고 파일을 하나씩 열었습니다. 점점 더 많은 파일을 열었을 때 메모리 사용량이 많이 증가했음을 알았습니다. vim을 닫으면 많은 기억이 돌아 왔습니다.

플러그인이 많이 설치되어 있지만 메모리 사용량이 크게 증가한 이유는 몇 번의 편집 후에 열린 버퍼 수 때문이라고 생각합니다.

vim이 한 번에 열 수있는 버퍼 수를 제한하여 편집 시간과 관련하여 오래된 버퍼를 자동으로 닫는 방법이 있습니까?

답변:


5

증상을 치료하지 말고 문제를 해결합시다. Vim은 일반적으로 많은 양의 메모리를 사용해서는 안됩니다. 문제를 분리하는 것이 가장 좋습니다. 범인을 찾는 데 도움이되는 몇 가지 팁 :

  • 플러그인 비활성화 (이진 검색을 사용하여 더 빠르게 만들기)
  • ~/.vimrc문제가 있는지 아래로 줄이십시오.
  • ~/.vimrc통해 완전히 비활성화vim -u NONE

vimrc 파일을 어떻게 디버깅합니까?를 참조하십시오 .

플러그인으로 메모리 버그를 발견하면 플러그인 개발자에게 문의하십시오. Vim에서 메모리 버그를 발견하면 오류를 재현하는 단계가 포함 된 버그 보고서를 제출하십시오. 보다:h bugs


+1; Vim에서 gazillion 버퍼를 동시에 열 수 있고 여전히 좋습니다. 버퍼를 보지 않는 한 (윈도우 또는 "탭") 메모리에로드되지 않습니다.
— Martin Tournoij

버퍼가 창에 표시되지 않을 때 @Carpetsmoker, 버퍼 변수 및 설정이 사라지지 않습니다. Peter가 제안한 것처럼 플러그인이 각 버퍼에 대해 많은 정보를 저장하면 메모리가 낭비 될 수 있습니다 (최종 사용자는 버퍼로 더 이상 아무것도하지 않을 것입니다). BTW : 플러그인 관리자는 버퍼와 관련된 데이터를 저장할 수 없지만 플러그인 관리자가 공개 "namespace"를 오염시키지 않는 것을 선호 b:variables하는 s:plugin[bufid]경우 에 저장할 수 있습니다 . 이 경우 버퍼를 삭제한다고해서 모든 관련 변수 / 메모리가 반드시 수집되는 것은 아닙니다. b:
— Luc Hermitte

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
파이썬이 필요하지 않습니다. Vim은 충분합니다 : :let buffers = filter(range(0, bufnr('$')), 'buflisted(v:val) && ! getbufvar(v:val, "&modified")')+:exe 'bw '.join(buffers, ' ')
— Luc Hermitte

@LucHermitte True이지만 필요 는 없습니다 . Vimscript에 익숙하지 않습니다. IIRC bw의 도움에 따르면 "무엇을하고 있는지 알지 못한다면"사용하지 말아야합니다. 난 아니야 :)
— muru

오래된 습관. 나는 항상 사용 :bw하고 결코 사용 하지 않습니다 :bd. 버퍼에서 거의 모든 것을 삭제하는 지점을 보지 못했지만 실제로는 모든 것이 아닙니다.
— Luc Hermitte
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.