最近我的vim又讓我鬧心了. 問題出現在supertab的補全速度上, 有時候按下tab鍵半天才彈出補全列表, 即便是彈出了列表在列表上下移動也變得的相當緩慢, 這讓我的很是蛋疼. 在完全無法接受這個問題之后決定再一次踏上折騰vim之路(已經沒有折騰vim好長一段時間了). 之前有一次vim出現tab補全的卡死問題折騰了好幾個小時才把原因找到, 這次這個更加詭異, 沒有折騰之前就覺得一定不簡單. 后來果然應驗, 這個問題足足花掉了我一整天的時間!
首先是縮小問題的范圍, supertab在我這里是為了實現就近補全而用的, 也就是指supertab這里充當了ctrl+p的映射的功能. 這個推測很快得到結果是問題和supertab本身沒有關系, 因為即在vunder中將supertab關閉掉.ctrl+p補全依然會出現同樣的問題. 接着需要鎖定問題出現的場合, 經過多次測試,發現ctrl+p補全在文件末尾總是非常的快速, 即便文件很大也是如此, 但如果將光標移到文件的中間位置, 這個時候再觸發ctrl+p補全響應就變得龜速, 而且在文件中間不同的位置往往會出現可以感覺到的速度差別. 到這里其實還是沒有任何線索, 反而讓問題變得更加詭異. 想了半天無果, 開始懷疑是否是別的插件產生的問題, 使用vunder便捷的批量注釋插件來慢慢的縮小范圍,這樣做高效而准確, 我覺得這是vunder帶來最大的好處之一. 經過插件的禁用測試, 最終發現當關閉indentLine這個插件的時候補全速度得到提升. 這時我很自信的認為是indentLine帶來的問題. 第一反應是放棄indentLine用類似的插件代替, 百度了半天發現只有一個indent-guide插件可以實現indentLine的縮進線, 可惜的是indent-guide使用的是高亮來實現縮進線, 以前就試過,因為不習慣它那很粗的縮進線(最細只能降低到一個英文字符寬度)而放棄, 更加要命的是我現在使用了externtab設置來讓空格直接取代tab, 這樣一來indent-guide直接完全無法使用了.
沒辦法放棄indentLine只能通過修改indentLine的源碼來砰砰運氣了. 找到源碼打開一看, 我來個去. 整個插件源碼加起來不到100行, 這么精簡的插件怎么會對vim有這么大的影響呢? 對着這個百來行vim腳本修改了半天發現indentLine是通過vim7.3才引入的conceal特性來實現縮進線高亮的. indentLine也只是簡單的添加了一個Conceal高亮規則. 只要這個Conceal高亮規則一打開ctrl+p在文件中間位置補全就變得很慢!難道這是vim本身的一個漏洞???7.3都發布好幾年了, 沒道理這個漏洞網路上沒有記錄阿, 重點是我現在已經將vim升級到了最新的7.4版本這個版本作者不是說做1000多項的修改和修改, 怎么可能這么大的效率問題沒有堵上? 胡思亂想了半天雖然覺得奇怪但也沒有其他辦法, 最終還是將indentLine關閉放棄使用Conceal特性.
之后的幾個小時我在沒有indentLine提供的縮進線帶來的各種不習慣下使用vim編碼.很快新的問題被察覺, 雖然在沒有了Conceal之后ctrl+p補全的速度有明顯的提升, 但在代碼中間位置的補全速度還是和文件尾有所差別. 實際上到這里我反而覺得一個好兆頭, 因為這里證明了真正的原因可能不是Conceal帶來的. 也就是指indentLine可能會保留下來.
再次尋找原因的第一步直接來個狠的, 將.vimrc移動到別的地方, 直接禁止所有配置, 打開vim, 定位到文件中間位置發現ctrl+p的反應速到完全沒有問題. 也就是指問題不在插件而是vimrc中其他地方的配置中. 現在的vimrc中有效的配置長度有500行以上. 在這么多配置的定位問題以前就干過, 那真的是利用注釋來二分查找阿! 實在不想這么大動干戈, 本能的再次救助網絡, 之前在百度上用中文搜索基本上沒有資料, 這次決定找找谷歌大大, 搜索了一會最后通過"vim ctrl+n slow"做關鍵此找到到了下面這個鏈接
還好自己的英文能勉強看外網(注意這個網址是外網, 你懂的), 這里的作者說大文件的ctrl+n很慢是因為:set syntax on :set foldmethod=syntax
這兩句配置導致, 后來又說的它發現自己的vim是測試版, 所以不知道是否應該保留這個問題的結論以供后來人參考. 在貼子的回復中最后作者還提及導致ctrl+n變慢的根本原因是:set foldmethod=syntax這個配置. 這個配置我的確是有的, 在很久以前就加上去了, 主要是設置vim該怎樣折疊. 折疊風格怎么會和ctrl+n/ctrl+p的效率產生關系呢? 真的是打死也想不到阿. 報着試試看的心理將自己vimrc中這一行注釋掉. 我來個擦!...真的見證奇跡的時刻阿... ctrl+p那犀利的速度就這么回來了. 打開indentLine試試, 完全沒有問題! oooh, mygod! 巨坑阿有木有, 折疊竟然和補全真的有關系阿有木有!
到這里一切就水落石出了,雖然花掉了我一整天的時間, 不過結果還是值得慶幸的. 不僅解決了supertab的效率問題, 還保住了indentLine插件.
為了讓vim的折疊功能可以繼續使用, 這里的將flodmethod設置indent, 即:
set foldmethod=indent