vim之補全2(徹底我的定製版)

  關於補全的方面要說的的確不少, 這裏選擇分爲兩個章敘述. 若是你想學vim, 你須要有很強的耐心, 若是你想鍛鍊這種耐心, 你能夠試着先看完我以前的文章. 好了, 下面繼續咱們的vim補全吧.php

  vim補全1中曾經說起到supertab在更換版本後和UltiSnips成功共用tab的解決方案, 在此以前主要的敘述主要在作一件事情:將vim的tags補全和字典補全從supertab的補全功能中分離出來, 讓supertab只負責一件事情:就近補全. 這樣子作彷佛沒有必要, 由於咱們徹底能夠將他們所有放到supertab接管的tab鍵上來, 下面要說的就是爲何咱們須要這樣作.python

  從最初的敘述中不難看出的想要實現最快最智能的補全的須要實現的幾個功能:優秀的補全列表排列算法,可預見性的補全列表結果,高速的補全列表創建.優秀的補全算法這一點上其實vim也有比較好的插件, 從很早依賴與tags的Autocomplpop和omnicppcomplete到後來比較出名的neocomplcache,再到後來至關智能的YouCompleteMe,最後到我如今留下的clang_complete. 下面就一一看一下這些插件的特色. linux

  首先是Autocomlpop和omnicppcomplete他們都是經過tags生成補全列表的,同時對tags的內容作過更加精確的分析能夠實現諸如c++的一些類成員補全的高級功能. 不過因爲tags文件自己的限制, 這種補全在實用性方面並非太好. 他們都是比較早的vim補全插件.c++

  後來出現的一個neocomplcache插件比較出名, 網絡上介紹他的文章不少. 主要的特色是經過在打開文件的時候一次性創建補全信息的緩存來提升補全速度. 這個插件我曾經使用過一段時間, 首先是打開文件的時候因爲necocomplcache須要創建緩存, 若是文件比較大的話你將明顯感受到卡頓. 現最新的neocomplcache 已經更名爲neocomplete,新的neocomplete經過lua的支持解決了啓動時創建緩存的過慢的問題. 固然他也須要更加高版本的vim的支持. 緩存一旦創建完成就比較快了. 補全列表幾乎所有是瞬間彈出, 但是這麼高的補全速度不見得是好事, 若是你設置了necomplcache的自動彈出功能. 你將發現,這個彈出功能在不少不須要彈出的地方依然工做, 因爲彈出速度至關的快,不少時候你在快速的移動光標的時候他均可見縫插針的彈出補全, 這個麼積極的補全最終讓我選擇了關閉他的自動補全. 在須要的時候經過按鍵觸發. 這個觸發鍵天然會被想到映射到tab鍵上, 網絡上的確有這樣作的實現方案. 很明顯neocomplete是不能和supertab共存的. 這問題並非太過嚴重而且我曾經翻遍網絡後在一個外文網站上找到了讓neocomplcache和UltiSnips共存的方法. 但是最爲嚴重的的問題是neocomplete和clang_complete衝突. 由於他們同時調用vim提升的全能補全函數接口. 調用同一個接口的結果是一個插件老是壓制另外一個插件致使被壓制插件徹底沒有觸發的能力.這種衝出彷佛徹底沒有辦法解決. 而clang_comlete又有不少我沒法替代的優秀特性. 最終我仍是選擇了放棄neocomplcache.git

  關於YouCompleteMe就更加奇葩了, 首先是他沒法和clang_complete,supertab,neocmplcache共存. 其次是他須要clang3.3的支持, ubuntu目前默認支持比較完整的clang3.0,這包括clang3.0相關的libclang庫(這個庫能夠加快clang_complete的速度) 不知道是否是因爲clang沒到3.3的問題, 在我成功編譯安裝了YouCompleteMe以後clang支持的全部補全特性一個都沒有出來過. 官方文檔之說YouCompleteMe是支持UltiSnips的,在使用中我也發現補全列表中有UltiSnips觸發關鍵字的身影,惋惜的是在選擇這個些觸發關鍵詞以後簡單的按enter鍵是沒法展開UltiSnips的代碼補全塊的.百度後得出的解釋是這裏須要設置UltiSnips的展開鍵映射到<tab>鍵以外的其餘鍵上並在補全列表中選擇觸發關鍵字以後經過這個從新映射的展開鍵來展開.惋惜, 我沒倒騰到這一步就已經把YouCompleteMe卸載了, 由於他的clang特性在個人ubuntu12.04中始終沒有成功過! 另外, 這個插件在編譯以後居然達到了60M的大小!我其餘vim配置加起來20M都不到, 真是佩服.,這麼大的容量明顯在編譯YouCompleteMe的時候clang3.3是下載了的, 但是誰能告訴我, 爲何clang的特性一個都沒實現呢. 程序員

  上面四個補全工具一一被淘汰以後, 最後剩下的惟一一個自動補全就是clang_complete了, 這是一個比較難控制的插件, 好在他和supertab以及UltiSnips並不衝突. 在ubuntu下使用clang_complete首先你須要下載clang編譯器和libclang庫. 下載命令以下:github

sudo apt-get install clang libclang1 libclang-dev算法

  安裝好clang編譯器環境以後clang_complete就能夠正常工做了.clang_complete主要實現了兩個很重要的功能, 第一個是clang_complete能夠動態的檢測代碼中語法錯誤, 這些語法錯誤是創建在clang編譯器時時編譯的結果的基礎上的,所以至關準確. 其實clang_complete經過分析clang時時編譯的結果實現比較高級的補全. 其中默認狀況下clang_complete在". , ->和::"三個標識符後面自動觸發. 這個這些標識符在C和C++中表明這指針的間接訪問, 類對象成員變量和成員函數的調用等.這些地方的補全在簡單的關鍵字檢索方式很難實現精確的補全. clang_complete藉助與calng編譯器時時編譯結果中的元素信息實現了這類補全的精確補全. 這個功能在補全C代碼中的結構體, C++中的類對象時變得超級實用.數據庫

    clang_complete的配置選衆多, 網絡中有不少地方能夠找到一些現成的配置.但這些配置大可能是相似的, 我按照網絡上能找到的配置放在vimrc中之後發現vim變得不穩定. 首先是vim在某些狀況下比較容易崩潰. 好比#include代碼的中出現錯誤時就容易直接閃退. 又好比在寫c代碼時常常會收到vim被致命信號ABRT中斷的問題. 很明顯這些不穩定是clang_complete在clang後臺時時編譯代碼後動態解析編譯結果並將編譯錯誤顯示到vim的時候出現了沒法解析的內容所致.這是一個嚴重的問題. 由於你不知道vim會何時崩潰, 崩潰後以前編寫後沒保存的代碼將會丟失, 又一個坑字了得!  好在一天實在受不了clang的隨時駕崩以後. 我開始查看clang的幫助文檔. 在幫助文檔的幫助下終於解決了這個問題.下面是關於calng_complete全局變量配置的一些意義和功能解說:編程

g:clang_complete-auto_select 該變量置1時,calng_complete在彈出補全列表以後會自動選擇第一個選項但不會生效, 置2時自動選擇首選項後同時將該項生效.

最初我將該變量設置爲1, 後來發現這個選擇徹底可使用默認的0, 由於在彈出補全列表以後你能夠經過tab實現相同的效果.

g:clang_complete_copen 該變量控制語法錯誤檢查後是否打開quickfix窗口列表. 默認值是0表示不打開. 若是你不想在編碼時時不時看到quickfix窗口的彈出, 這裏保持默認設置便可.

g:clang_hl_errors 該變量控制是否高亮顯示clang檢測到的語法錯誤, 這個功能至關實用. 默認值是1表示打開, 若是你但願用到clang_complete的智能語法檢測功能.這裏保持默認設置便可.

g:clang_periodic_quickfix 這個變量是上面崩潰問題的關鍵, 網絡上的配置爲實現clang_complete對當前代碼的時時語法檢查, 這裏大多將其設置成了1, 這個變量控制着是否認時刷新quickfix裏的錯誤信息. 在該變量等於1時,只要咱們的光標在vim中保持三秒不動, clang_complete就會在後臺給咱們刷新clang時時編譯出來的結果. 這個功能的本意是好的. 但是clang_complete在刷新quickfix的時候彷佛對某些錯誤沒法正確的解析, 這就致使了vim忽然的退出和致命錯誤提示. 很明顯爲了不vim忽然的退出致使的編輯內容丟失. 這裏必定要保持默認設置.

g:clang_close_preview  clang_complete在補全的時候默認是能夠打開補全預覽的,所謂的補全預覽就是在vim的上面展開一個小的名爲"草稿"窗口, 裏面顯示的是當前補全列表中選擇內容的完整內容預覽, 這個功能並不實用, 由於補全列表中的內容已經至關詳細了, 忽然打開的草稿窗口只會給編輯帶來不暢感.所以這裏建議將其設置爲1來關閉預覽功能.

 g:clang_snippets_engine clang_complete的補全帶有必定的snippets功能, 所謂的snippets功能就是當補全內容是一個函數的時候clang_complete在補全確認後會首先定位到函數的第一個參數區並讓用戶修改, 修改完畢以後你能夠經過回到普通模式(我這裏經過`鍵返回普通模式)後使用tab鍵跳轉到下一個變量區繼續修改.clang_complete的說明文檔中彷佛表示支持Ultisnips的snippets功能, 也就是若是咱們安裝了UltiSnips並在這裏將clang_snippets_engine設置成UltiSnips我就能夠通<<vim之補全1>>中說起的ii和II來跳轉可修改區. 惋惜的是我嘗試過這裏設置成UltiSnips結果是snippets功能紊亂. 最後仍是保持了默認的普通模式tab鍵跳轉的方式. 好在這個方式仍是至關方便的.

g:clang_snippets 這個變量彷佛是用於開啓clang_complete的snippets功能的, 而clang_complete的這個選擇默認值是0,所以這裏能夠設置成1

g:clang_use_library 這個變量用於開啓經過libclang庫來加快clang_complete的反應速度. ubuntu在安裝了libclang1 和 libclang-dev庫以後就可以使用libclang庫了. 因此這裏明顯是須要打開的.

g:clang_user_options 這一項用於對編譯器的一些設置, C語言編輯下這裏不須要設置, C++開發時能夠在其中添加必要的參數.

g:clang_complete_macros 彷佛是用來補全宏什麼的, 暫時不太清楚到底有啥做用, 將其設置爲1暫時沒有發現問題.

綜合上面的描述, 最終咱們的對clang_complete的配置能夠歸結爲一下幾句話, 將其寫到vimrc中便可:

"clang_complete插件設置
let g:clang_snippets=1
let g:clang_use_library=1
let g:clang_close_preview=1
let g:clang_complete_macros=1
"let g:clang_user_options='-stdlib=libc++ -std=c++11 -IIncludePath'

上面的設置咱們關閉了quickfix的定時更新功能. 這是爲了防止vim意外崩潰而作的設置, 但是這也將致使clang_complete沒法自動時時的顯示語法錯誤了. 是否clang_complete提供給咱們的強悍的語法檢查功能就沒法使用了呢? 非也, 幫助文檔中提到咱們能夠經過手動調用函數的方式來觸發quickfix的更新.也就是說任何說後咱們但願看到clang時時編譯以後的語法錯誤提示, 咱們只有手動調用這個函數便可. 固然,每次看個語法錯誤提示還要手動調用個函數當前不是個人風格. 經過將這個函數的調用捆綁在快捷鍵上是我慣用的伎倆, 但是捆綁在那個快捷鍵上好呢? 個人設計是和共用保存快捷鍵. 這樣的共用設計實現了任什麼時候候刷新quickfix內容以前文件老是被保存過了, 首先是這樣的手動更新vim崩潰的可能性變得很小, 其次即使崩潰了,也不要緊, 由於咱們剛剛保存過! 在個人vimrc中保存用的快捷被映射到了alt+w上所以咱們只要添加下面的配置就能夠實現保存和clang_complete語法檢測共用alt+w組合的效果(爲了防止在普通文件保存時觸發ClangUpdateQuickFix函數而出現錯誤提示,這裏配置成只在c和cpp類型的文件中觸發該函數調用):

imap ^[w        <esc>:call Smart_save()<cr>a
imap <a-w>    <esc>:call Smart_save()<cr>a
nmap ^[w       <esc>:call Smart_save()<cr>
nmap <a-w>   <esc>:call Smart_save()<cr>
func! Smart_save()
   exec "w"
   if &filetype == 'c' || &filetype == 'cpp'
      call g:ClangUpdateQuickFix()
   endif
endfunc

注意其中的^[w 是經過在插入模式下先按下ctrl+v再按下alt+w產生的特殊字符,這種方式輸入的alt+w是ubuntu的gnome-terminal終端惟一能識別的alt組合鍵的配置方法, 關於alt鍵的映射問題能夠經過 :help map-alt-keys 和 :help map 以及 :help alt 來得到相關幫助.

和clang_complete相關的配置還有一個是

set completeopt=menu,longest 這是一個至關有效的設置. 這在後面的字典補全的地方會有說明,這裏暫時就不作解釋了.

最後要說起和calng_complete的相關的設置是項目根目錄下.clang_complete文件. 這個文件是咱們手動創建的. 假設你當前編輯的項目源碼中包含了一個本身定義的頭文件,而這個頭文件並再也不當前源文件所在的文件夾中而是在項目根目錄的子目錄include下面, 很明顯,若是不告訴clang這個咱們本身的頭文件的位置所在, clang在時時編譯咱們的當前的源文件的時候將老是提示咱們的頭文件找不到. 爲了解決這個類問題, 咱們須要配置項目根目錄的.clang_complete文件. 這個文件中能夠設置全部和編譯器相關的參數. 示例以下:

-w
-I include
-I lib/ipc
-I lib/unix
-I lib/net

-w 表示不對編譯時的warning報錯和高亮, 若是你但願代碼更加嚴重, 最好不要在這裏加入-w, 若是你不想消除代碼中的worning有不想每次查看語法錯誤的時候都看到這些worning被高亮, 那麼能夠在這裏添加-w

-I 後面跟的是目錄名錶示告訴編譯器到那裏去找到咱們本身定義的頭文件.

  clang_complete補全對應着優秀的補全必要特性中的高級算法. 另外一個必要特性是可碰見性的補全結果.這個特性主要是爲了提升補全的命中率和盲補的可能性. 在VAX中因爲算法比較複雜, 補全的可預見性也被算法接管, 但vim中就不是這樣了, 由於vim沒有這麼智能. 雖然和其餘的IDE相比vim在補全的智能程度上的確有所不及.可是真所謂笨鳥先飛, 傻人有傻福.(^_^). vim的做者在設計vim的時候很明顯也意識到了這一點, 既然程序自己不能作到高度的智能, 那麼咱們就須要將一部分須要智能區分的工做交給用戶, 要知道人永遠要比計算機更加的智能. vim爲此設計了多達15種補全模式, 爲的就是將不一樣場景中的補全分開而且將觸發各類補全的時機交給用戶, 也就是但願用戶能夠智能的先過濾到一部分徹底沒必要要的補全來達到提升補全精度的目的. 這十種補全中咱們須要關注的只有幾個,  下面要說的就是最後要上場的四個vim自帶的補全配置, 這些補全在<<vim之補全1>>中最開始就提到過. 首先要說的是tags補全, 因爲tags補全對項目中不在上下文和buffer中的關鍵字補全行之有效而且tags補全大多時候是能夠預測的(可預測指到在咱們知道何時時候後須要觸發的tags補全).  所以, 咱們有必要將其保留, tags補全分析到這裏最後須要考慮的就是怎麼能更加簡單的調用它. vim大多數捕全面是經過ctrl+x加上另外一組ctrl組合鍵觸發, 沒調用一次補全須要按四個鍵, 很明顯這是不合適的. 爲此,咱們須要想出更好的調用方式. 不過, 在思考這個問題以前咱們須要解決另外一個更加棘手的問題: 不知道是否是插件衝突的問題, 在我根據上面的表述將supertab和UltiSnips成功的共存以後, 出現了一個嚴重的問題: 在插入模式下輸入ctrl+x組合鍵的時候, vim會自動輸入下面的字段:

=<SNR>53_ManualCompletionEnter(
      )

很明顯這是某個地方映射了ctrl+x鍵而且沒有正確執行的結果. 定位的咱們安裝的supertab.vim文件中, 搜索<c-x>, 很快728行(你可能不在這一行).找到了以下代碼:

  imap <c-x> <c-r>=<SID>ManualCompletionEnter()<cr>

 在這一行的開頭添加"將其註釋掉, 清除全部.vim/view目下的全部記錄, 打開文件從新輸入<ctrl+x><ctrl+]>, tags補全成功被調出.

  supertab的映射問題解決以後咱們能夠繼續考慮上面的需求. 咱們須要儘可能用最少和最容易操做的按鍵來觸發補全的調用.補全的觸發鍵首先是ctrl和alt組合鍵不能用, 由於在個人<<vim之快速跳轉>>中有說起,ctrl的組合鍵首先是有一部分被vim默認佔用後不可從新映射, 另有一部分如組合鍵直接不能實現映射. 其餘能用的ctrl組合鍵大多用於實現vim的跳轉和定位. alt組合鍵在操做上並不流暢,比較適合作操做並不頻繁的各類功能映射. 其次, 補全的觸發鍵必須在插入模式直接觸發, 這樣
又致使這裏的映射不能像普通模式那樣經過單鍵來實現.
  ctrl,alt,單鍵都不能作映射, 難道補全就不能實現更好的重映射了嗎? 非也, 以前提過vim有一個神奇的雙鍵映射功能. 因爲vim有一個按鍵等待模式, 所以即使的實在插入模式下雙鍵映射依然能夠很好的工做, 好比咱們的在插入模式下用jj作映射,任什麼時候候咱們在插入模式下快速的輸入jj鍵均可以觸發這個映射. 你可能會問題, 這樣一來我不是不能輸入連續的兩個jj了嗎?非也, vim對全部的用戶輸入若是在功能上沒法是未決的, 那麼vim會進入輸入等待模式,這個等待時間默認是1秒, 在你輸入一個字符後的1妙內,vim會等待你輸入第二個字符來肯定輸入的功能. 若是在這一秒內你沒有輸入第二個字符來觸發某個映射.那麼vim就會認爲你是但願單純的輸入第一個字符. 所以在1秒後你的字符會轉換爲正常的字符並上屏.這樣一來, 若是咱們對jj作了映射, 咱們有但願輸入兩個連續的jj的話就很容易實現了, 咱們只要在輸入第一個j以後等待大約1妙再輸入下一個j就能夠了.若是你不了vim多字符映射功能, 那麼你極可能會爲在某天你從別人那借鑑了某些設置以後發現本身vim的輸入變得莫名奇妙的卡頓了.實際上這種卡頓在大多數狀況下是不會影響咱們正常編輯的, 只要咱們編輯的的內容沒有和雙字映射重疊, 咱們大可沒必要理會這樣的停頓, 你的編碼速度有多快就寫多快吧.放心, vim會跟上你的編輯速度的. 固然這裏在作雙鍵映射的時候也不能作任意的組合, 某些在你編碼或編輯中出現頻率很高度組合是不適合作雙字映射的.好比方便又按的"ll"就不適合編程的人用來作映射."ll"在不少很經常使用的的單詞中出現(malloc是最多的一個),所以若是你用他來的作映射,那麼你不得不在每次輸入malloc的都時候都要停頓一次,而且這種停頓每每被咱們一鼓作氣的打出一個malloc所誤傷! 第二個雙字映射須要注意的是要儘可能使用那些儘可能容易操做的組合, "jj"組合要遠比"pp"組合好按的多. 最後一個須要注意的時候最好只用幾個特定的按鍵來產生各類不一樣的組合來的映射.由於只要一個按鍵在你的vim配置中有一個相關開頭的映射, 咱們在任什麼時候候輸入這個按鍵都會看到卡頓現象. 若是你把鍵盤上的26個字母和其餘字符全用雙字映射了一遍, 那麼每一個按鍵在任什麼時候候按下的時候都會被卡頓. 我想應該不會有人會喜歡中樣的輸入體驗的.綜合上面的敘述, 個人雙字映射中大多用到了"jkl"和"JKL"這六個字符作組合映射. 這裏我挑選了至關好按鍵的"kk"來作爲tags補全的觸發映射.

  你可能會說"jj"鍵比"kk"鍵更加易於操做, 爲何不用它來作爲tags補全的映射呢? 答案是咱們還有一個比tags補全使用更加頻繁有效的補全方式, 那就是字典補全! 這個補全在vim中的默認觸發鍵是<ctrl+x><ctrl+k>, 在我以前敘述中屢次提到過字典補全, 可見他的功效之高, 首先說明字典補全的原理:咱們在一個任意名字的文件中用空格作爲關鍵詞寫下多個詞組, 這些詞組是咱們但願用於補全的詞組. 在.vimrc經過下面的方式告訴vim咱們的字典在哪裏:
set dictionary+=~/.vim/tab/C.dic
  我將全部的我的補全字典所有放在了~/.vim/tab目錄下, 出了用於c語言補全的C.dic還有針對c++的cpp.dic和針對於網絡編程開發net.dic等等, 這些字典完事是咱們本身設計的所以字典的名稱,字典內容以及字典的分類方式徹底取決於咱們我的. 若是咱們用c語言的同時還須要使用網絡方面的開發接口, 這裏能夠在vimrc繼續添加以下內容:
set dictionary+=~/.vim/tab/net.dic
字典在路徑指定給vim以後插入模式下任什麼時候候咱們經過<ctrl+x><ctrl+k>觸發字典補全,vim都會按照vimrc中添加的順序來檢索全部存在的字典文件. 單個文件中vim的檢索順序是從文件頭順序到文件尾.

  字典補全的原理是很簡單的, 第一次看到你可能會以爲字典補全沒有什麼特別,也沒什麼強大的地方. 不過下面對字典補全優勢的分析可能會讓你改變這個見解.首先, 字典補全的字典是咱們本身設計的, 這將給予咱們的是最爲靈活的補全列表定製功能. 使用vim的人大可能是程序員, 而程序員使用的語言有不少, 也許你和我同樣是一個普通的c語言的使用者. 也可能你是一個php工程師或着使用python作開發. 不管你是用什麼語言, 字典補全老是可用的. 由於你php的工程師徹底能夠本身定製一個php.dic供本身使用.其次字典補全可讓步補全的精度提到很是高的一個高度. 如今假設你和我同樣都是C語言程序員, 但個人開發主要是作網絡信息採集和處理, 而你的開發是用c語言來寫驅動程序.這麼一來即使咱們用的是徹底相同的語言, 個人C.dic也可能和你的c字典大不相同, 由於我可能永遠不會用到驅動程序裏的接口函數, 你也可能徹底無論任何應用開發使用的函數.補全字典能夠作到補全列表的高度定製化, 任何你用不到的關鍵詞均可以被你排除在外, 等到哪天你須要用到它時, 再添加和修改字典補全也是很容易的. 這種徹底按需求的定製字典能夠保證補全列表中基本沒有冗餘的內容. 第三個補全字典的優勢是便於切換,這在以前已經提到, 咱們徹底能夠定製補全種類的字典的在不一樣場合單獨或組合使用. 字典補全的第四個優勢是補全的結果是可預測的. 這個特性至關的實用, 由於它可讓字典補全實現盲補(我本身發明的詞, 在<<vim之補全1>>中有說起). 盲補就像盲打同樣是全部補全中最快的一個, vim在檢索補全字典中的內容時老是按照從頭至尾的順序掃描並排列結果的. 一來只要字典中的關鍵詞順序沒有變. 補全出來的結果也不會變, 二來咱們任什麼時候候均可以經過修改補全字典中關鍵字的內容和順序來讓補全列表的結果變得更加合理高效.字典補全最適合用於各類編程語言或普通編輯中那些不變的語法關鍵詞, 這些語法類的關鍵詞首先是固定不變的, 其次是高頻率的出現. 好比C語言中語法關鍵子struct這個關鍵詞出現的頻率至關的高, 若是咱們使用就近補全或者是tags補全等其餘方式的話, 補全列表的結果會因上下文內容的變化而產生化, 這樣咱們不得不在每次的觸發中下意識的去查找.而字典補全則徹底不一樣, 若是你吧sturct在C.dic中放置在很是靠前的地方, 那麼你將可以肯定每次經過s觸發字典補全的時候首選詞老是struct, 這樣就實現了盲補的特色. 字典補全的最後一個優勢是對一些有規律的很長的帶有體系特色而且每每很長的接口函數和接口關鍵詞的的補補全行之有效.下面是個人C.dic中關於linux線程的字典記錄:

pthread_t
   pthread_create()        pthread_exit()
   pthread_keycreate()     pthread_keydelete()
   pthread_join()          pthread_self()
   pthread_setpecific()    pthread_getspecific()
   pthread_cleanup_push()  pthread_cancel()
   pthread_detach()        pthread_equal()

   pthread_attr_t
   pthread_attr_default()        pthread_attr_init()
   pthread_attr_getschedparam()  pthread_attr_setcheparam()
   pthread_attr_setscope()       pthread_attr_setdetachstate()

   PTHREAD_
   PTHREAD_CANCELED
   PTHREAD_PROCESS_
   PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_SHARED
   PTHREAD_SCOPE_
   PTHREAD_SCOPE_SYSTEM    PTHREAD_SCOPE_PROSESS
   PTHREAD_CREATE_
   PTHREAD_CREATE_DETACHED PTHREAD_CREATE_JOINABLE

   cond_attr
   pthread_cond_
   pthread_cond_init() pthread_cond_destroy()
   pthread_cond_broadcast() pthread_cond_singal()
   pthread_cond_timewait() pthread_cond_wait()

   pthread_delay_t
   pthread_delay_np()

   pthread_mutex_t
   pthread_mutex_init()          pthread_mutex_destroy()
   pthread_mutex_lock()          pthread_mutex_unlock()
   pthread_mutex_mutex()         pthread_mutex_trylock()
   pthread_mutexattr_setptype()  pthread_mutexattr_setpshared()
   pthread_mutexattr_init()      pthread_mutexattr_destroy()
      PTHREAD_MUTEX_
      PTHREAD_MUTEX_NORMAL    PTHREAD_MUTEX_ERRORCHECK
      PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_DEFAULT
      PTHREAD_MUTEX_INITIALIZER

   sched_param {
      sched_priority
   }
   sched_

   pthread_once_t
   PTHREAD_ONCE_INIT

   這個不怎完善的線程接口字典有不少規律性的特色 他們大多以pthread_和PTHREAD_開頭後面每每還有一些子字段,它們中大多數比較長而顯得不那麼友好, 若是你老是一個一個去打的話,即使利用就近補全只打首次, 你也會以爲很麻煩. 這裏利用字典補全當咱們利用字典補全在任什麼時候候經過pth觸發, 出如今補全列表首的將會是pthread_這個開頭總會是正確的, 咱們在他的後面再加上一些子字段的關鍵字繼續補全就會將補全精肯定位到咱們須要的結果上.這個補全至關的好用.
  你可能會以爲製做這個補全字典比較麻煩, 首先是你能夠在感受到某個高頻詞須要加入字典的時候將其添加進來. 你也能夠在看相關書籍的時候做爲一種總結性的筆記邊看邊把他們加入到字典. 這種方法比較系統, 也能夠幫助咱們學習. 總之, 這些字典是日月累起來的分散到零散的工做時間中去以後, 你會發現製做他們基本上沒有額外的時間開銷.

  在個人vimrc中利用"jj"這個雙字映射中算是最容易操做的映射來觸發字典補全, 另外還設置了"JJ"來觸發路徑補全. "JK"來觸發頭文件補全(在<<vim之快算跳轉>>中曾經把"jj"和"kk"用於上下移動, 這裏更新爲補全觸發. 因爲在編碼中從成對的標點最後右移跳出標點的操做至關的頻繁,所以保留了"jk"右移和"kj"左移的功能). 綜上所述, 下面給個人vimrc相關映射配置片斷:
imap kj  <left>
imap jk  <right>
imap jj  <c-x><c-k>
imap kk  <c-x><c-]>
imap JJ  <c-x><c-f>
imap JK  <c-x><c-i>

  vim補全相關的內容最後還有一個小小問題須要討論一下, 這個問題是vimrc中completeopt的設置帶來的. 首先是completeopt用於控制補全列表的顯示方式, 主要是三個, menu方式表示展開補全列表, longset方式表示在補全列表中存在公共的最長字串時將其直接上屏, preview表示打開預覽窗口. 第一個menu通常是必選的, 第三個preview由於沒有多少苦實質的用處,使用後反而會在的補全不時的給你在窗口上方彈出個"草稿"窗口而打亂了咱們輸入節奏, 所以建議不要使用. 問題出在第二個longest上面, 這是一個比較糾結的補全顯示方式, 他的優勢是,若是你輸入向上面擁有公共字串的pthred_類型的補全時, longset開啓以後pthread_會在
你觸發補全時就上屏, 而且因爲這時沒有選擇任何一個補全列表中選項, 所以當咱們繼續輸入以後子字段時補全列表會很天然的更新到更加精確的補全列表上來. 若是longset關閉, 那麼觸發後會默認選擇第一個選項, 若是上面的列表中第一個詞pthread_t修改成pthread_ 那麼會在出現pthread_以後很天然的繼續輸入mu等來繼續精確選擇諸如pthread_mutix_init的選擇但是問題出在繼續輸入mu等子字段後補全列表會自動關閉, 咱們必須經過再次使用"jj"來從新彈出補全列表. 這個樣每一個具備子字段的補全必須使用至少四個j才輸入完畢. 這在輸入上徹底沒有longest開啓時那麼天然. 但是若是真的設置longest方式, 若是咱們輸入諸如struct這樣
徹底沒有公共字符串的單詞時又會變得麻煩, 由於他不會默認給你選擇補全列表中的第一個選項. 這在輸入時又變得的不那麼天然了, 這麼一折騰longest變得至關蛋疼. 開也不是, 關也不是. 這個問題我酷似冥想了好幾天無果...以後只想出了一個能夠稍微方便一點的辦法就是將上面字典中ptheard_這樣的公共字串寫成pthread_t這樣的多一個單詞的關鍵詞而且關閉longest, 這樣一來在輸入pth觸發字典補全以後會選中第一選項pthread_t, 若是咱們想輸入phread_mutix_init就先刪除一個單詞t, 這個時候補全列表上不會選擇任何一個選項, 以後當咱們再輸入mu時補全列表是不會關閉的, 咱們就能夠省去一次"jj"的觸發輸入. 固然, 這種輸入只能稍微的讓補全變得更加平滑一點, 並非解決的根本辦法. 若是那位讀者有更好的解決辦法但願能夠給予回覆或發郵件告訴我, 我的將不甚感激.

  個人郵箱以下:pangchol@163.com

  好了, vim補全相關的內容我暫時就研究到這裏, 終於寫完了, 最後來作一個總結:
  咱們擁有本身的補全字典, 在寫項目代碼時首先在vimrc指定正確的補全字典. 將前輩的代碼和本身的函數庫等加入本身的項目中. 利用f12鍵隨時創建或更新tags和cscope. 咱們須要最學會UltiSnips的代碼塊補全定製方式, 在必要的時候修改~/.vim/vunder/UltiSnips/UltiSnips目錄下相關的代碼塊補全模板來定製符合項目和我的需求的代碼塊補全. 咱們須要認真定製和記憶這些代碼塊補全的觸發關鍵詞, 在任什麼時候候均可以經過輸入這些觸發關鍵詞後輸入Tab鍵來觸發代碼塊補全功能. 任什麼時候候若是須要補全一個上下文或其餘打開的緩衝區中出現過的單詞, 咱們均可以經過Tab鍵觸發就近補全(只要注意不要輸入了和代碼塊補全觸發關鍵詞相同的內容來觸發便可). 這個單詞在上下文中離光標越近越容易實現盲補.若是一個函數或者變量名等存在於前輩的代碼或者函數庫中, 咱們能夠經過"kk"鍵來觸發tags補全來比較精確的找到他們. 任什麼時候候若是你想輸入語法中的關鍵字或者編程語言中的標準庫接口等均可以經過"jj"來觸發字典補全(已經定製好的)高速而精確的實現,標準接口函數名每每在第一次使用時經過字典補全觸發,以後大多使用就近補全更加快速高效. 而數量很少詞組簡單但又出現頻率極高的語法關鍵字(諸如: struct static等)咱們最好老是採用字典補全, 認真設計你補全字典儘可能保證越高頻的語法關鍵在字典補全的越前面. 你將發現發多時候你輸入他們都是在盲補!若是你須要輸入系統中的路徑你能夠試着使用"JJ"觸發路徑補全. 若是你肯定一個關鍵子存在於當前文件包含的某個頭文件中, 你也能夠試着經過"JK"來觸發頭文件補全. 最後, 任什麼時候候clang能夠支持時時編譯的編程語言中(C,C++,object-c等), 在咱們輸入".","->","::"後clang_complete會自動經過clang的編譯分析來獲得補全精度至關高的結構體成員或類成員的補全.若是咱們但願查看一下當前編輯的程序有沒有語法錯誤,你也使用alt+w來保存後自定觸發clang_complete的語法錯誤分析和高亮功能,clang_complete的語法錯誤高亮功能只在類型爲c或cpp的文件中被觸發.


後記:

2013-1214

最近幾天在使用vim跳轉的時候發現ctrl+]的跳轉有些詭異, 不少時候都不會跳轉的關鍵字的定義上. ctrl+]在默認狀況下被用做ctags三跳轉. 經過:h CTRL+]查看相關的幫助文檔才知道ctrl+鼠標左鍵和ctrl+]的功能相同ctrl+鼠標右鍵和ctrl+t的功能相同(哎, vim到底還有多少好東西我尚未知道呢?), 這時再測試ctrl+左鍵的跳轉, 詭異的現象出現了, ctrl+左鍵居然和ctrl+]的跳轉結果不相同! 我來個去, vim幫助文檔寫錯了?? 仔細想了想幫助文檔應該不會有錯, 這樣可能的問題應該是ctrl+]被某個插件替換了. 想一想本身的全部插件中能夠實現跳轉的功能的除了cscope就是剩下clang_complete了, cscope以前沒有問題, 因此目標首先鎖定在clang_complete上, 經過:h clang_complete查看它的幫助文檔後緣由就找到了, clang_complete默認將ctrl+]和ctrl+t做爲跳轉到聲明的快捷映射了. ctrl+]原本的功能是跳轉到定義! 緣由找到以後就很容易解決了, 在vimrc添加若是內容將clang_complete的跳轉映射修改到不用的鍵位上(鍵盤上的映射組合都快用完了, 想再找一個好用的快捷鍵不容易啊, 最後只能用ctrl+P和ctrl+T了):

let g:clang_jumpto_back_key="<C-T>"
let g:clang_jumpto_declaration_key="<C-P>"

這樣映射以後, ctrl+]將保持原有的經過tags跳轉到定義位置的功能. 若是cscope存在的狀況下,vim的ctrl+]默認會先搜索cscope中的數據庫.在定義跳轉上tags的跳轉要比cscope準確一點(tags幾乎用做定義跳轉). 爲了上vim的ctrl+]默認先搜索tags文件. 咱們須要在vimrc添加以下配置:

set nocst

咱們能夠在vimrc添加專門用於cscope的定義跳轉映射以便在ctrl+]跳轉失敗的狀況下使用cscope試試.關於這方面的討論, 更具體的內容能夠在個人<<vim之tags>>中找到.

若是鼠標就在身邊, 其實ctrl+鼠標左鍵和ctrl+鼠標右鍵的組合要比ctrl+]和ctrl+t更加方便一點.

若是你真的須要跳轉的一個關鍵字聲明的地方能夠通ctrl+P(注意是大寫的P)來實現. ctrl+t 和ctrl+T均可以實現遞歸的跳回到以前位置的功能.

 

在此次ctrl+]功能修正的過程當中還發現了一個坑爹的問題, 好久以前我就發現vim中有些快捷鍵組合是絕對不能用來作映射, 若是用了後果就是vim完全凌亂. 這樣的組合鍵典型例子有: ctrl+[, alt+[, alt+] . 一直以來知道的他們不能使用, 但具體緣由並不明瞭. 今天在配置ctrl+]的時候意外的留意到vim若是直接輸入ctrl+[ 輸入提示中出現的^[符號, 而這個^[符號是特殊的組合鍵的轉譯起始字符而且<esc>鍵也被vim看成^[來處理. 同時alt鍵的組合鍵因爲在gnome-terminal中會轉譯成<esc>開頭的特殊組合鍵,所以又會用^[來代替, 我來個去, 這麼多的鍵位重合, vim不凌亂纔怪哦...

2013-1216

這幾天使用vim發現即使經過alt+w來在保存以後調用ClangUpdateQuickFix()函數來手動觸發語法錯誤檢測. vim仍是出現頻繁崩潰的問題. 實在受不了了只能再次求助百度谷歌. 在網上海搜了一翻以後在clang_complete做者的github上找到了一些相關的問題討論. 不過惋惜的是沒有找到具體的解決方法. 仔細觀察討論的內容發現彷佛最新的clang_complete修復了很多容易崩潰的問題. 在看看本身vimrc中vunder對clang_complete的下載源設置:

Bunder 'vim-scripts/clang_complete'

vim-scripts在github上是一個專門存放vim.org下插件拷貝鏡像的地方, 也就是指我當前的clang_complete是發佈在vim.org上的最後的一個版本. 仔細看看clang_complete做者的github發如今Rip-Rip/clang_complete目錄下,也就是指這裏的版本可能要比vim.org上最新的版本要新. 因而將上面的源配置修改成:

Bundle 'Rip-Rip/clang_complete'

從新清理和更新了clang_complete以後崩潰的問題暫時尚未遇到了, 但願的真的是版本的問題吧.

最後在做者git的討論中彷佛還看到若是開啓libclang功能會致使崩潰的可能增長. 所以將 let g:clang_use_library=1 這句刪除來關閉libclang的使用可能會好一點, 我暫時沒有關閉, 先用着觀察一段時間吧.

 2014-0105

通過較長時間的測試這裏得出的最新結論是clang_complete的語法錯誤高亮功能的確很是容易致使vim的忽然崩潰, 最近終於絕對將這個功能完全從vim的經常使用功能中剔除, 保持他的默認關閉,而且分配一個不適很好用的快捷鍵給它. 如今想一想其實代碼的語法錯誤檢查功能並非一個很是必要的功能, 由於在編碼的過程當中語法錯誤幾乎是沒法避免的, 編碼時不關注這些臨時的語法錯誤其實不會下降編碼效率. 如今vimrc中和clang_compelte相關的設置若是以下(關閉的libclang支持和自動語法檢測):

"clang_complete
let g:clang_snippets=1
let g:clang_close_preview=1
let g:clang_complete_macros=1

"避免和ctrl+],ctrl+t原有的功能衝突
let g:clang_jumpto_back_key="<a-t>"
let g:clang_jumpto_declaration_key="<a-d>"

ino <a-s> <esc>:call Show_error()<cr>a
nno <a-s> <esc>:call Show_error()<cr>

func! Show_error()   wall   if &filetype == 'c' || &filetype == 'cpp'      call g:ClangUpdateQuickFix()   endifendfunc

相關文章
相關標籤/搜索