Vim 開啟大檔案會變慢、慢到難以忍受的問題,通常停用一些功能就會改善了。 極端點用 vim -u NONE filename(不讀 vimrc 也不開任何外掛)開檔,就知道是檔案太大還是設定問題。

Dr Chip 的 LargeFile plugin 就是在偵測到大型檔案時,自動關閉 syntax、folding 等昂貴功能,離開 buffer 時再調回來。 使用上不必多做什麼動作,就能達到明顯加速效果,20 萬行的 rails log 開起來也沒什麼感覺。


原版 LargeFile 設定較少,所以我的 .vimrc 一直有整段抄襲版的 BigFile 實作,用了好幾年,一直有解不開的怪問題,發作起來會把全域 'undolevels' 設為 -1 害我完全不能 undo,非常困擾。

這次直接 fork 原版 LargeFile,程式先重構一下,居然就解掉了……
自訂的選項也都加了進去,專案在 bootleq/LargeFile,再測一陣子就會送交原作者處置。


具體設定例

基本選項,就這幾個:

let g:LargeFile           = 40            " 超過這個 size 才會處理。 預設是 20
let g:LargeFile_size_unit = 1024          " g:LargeFile 的單位,1024 就是 KB。 預設是 MB
let g:LargeFile_patterns  = '*.log,*.sql' " 只處理 log 和 sql 檔案。 預設是 *
let g:LargeFile_verbose   = 0             " 不要顯示訊息(例如 LargeFile 生效時)。 預設是 1

LargeFile 會停用 FileType autocmd,如果想對特定檔案動手腳,可使用新增的 autocmd 事件:

autocmd User LargeFileRead call s:large_file_read()   " 每次 Large File 發生 BufRead 時發動
autocmd User LargeFile call s:large_file_detected()   " 偵測到 Large File 時發動,包含 :edit! 或 jump 進入時

function! s:large_file_detected()
  let ext_name = expand('%:e')
  if ext_name == 'log'
    " nnoremap <buffer> <LocalLeader>ddd :EmptyFile<CR>   " 按這個鍵把 log 全清掉(實作省略……)
  endif
endfunction

function! s:large_file_read()
  let dir_name = expand('%:p:h')
  if dir_name =~ '/home/www/some_rails_app/\(\w\+/\)\?log'
    if &fileencoding != 'utf-8'   " 不是 utf-8 就重讀吧
      edit! ++enc=utf-8
    endif
    syntax match railslogEscape '\e\[[0-9;]*m' conceal    " 有這個才不會看到一堆色碼(需要裝 rails.vim)
  elseif dir_name == '/home/www/logs'
    set syntax=httplog    " 上色(需要裝 httplog)
  endif
endfunction