0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何在Linux環(huán)境下使用Vim搭建C語言開發(fā)

Wildesbeast ? 來源:今日頭條 ? 作者:開心玩技術(shù) ? 2020-05-05 14:39 ? 次閱讀

2020年了,不要再看網(wǎng)上那些老舊的文章還在教你使用手工生成 tags 的,請使用自動(dòng)代碼索引生成工具,比如 vim-gutentags,現(xiàn)在網(wǎng)上好像就沒有一篇能正確討論 Vim C/C++ 環(huán)境搭建的,都在談些十年前的東西,所以我寫了篇關(guān)于 Vim 8 和 C/C++ 相關(guān)插件的介紹:

假設(shè)你已經(jīng)有一定 Vim 使用經(jīng)驗(yàn),并且折騰過 Vim 配置,能夠相對舒適的在 Vim 中編寫其他代碼的時(shí)候,準(zhǔn)備在 Vim 開始 C/C++ 項(xiàng)目開發(fā),或者你已經(jīng)用 Vim 編寫了幾年 C/C++ 代碼,想要更進(jìn)一步,讓自己的工作更加順暢的話,本文就是為你準(zhǔn)備的:

插件管理

為什么把插件管理放在第一個(gè)來講呢?這是比較基本的一個(gè)東西,如今 Vim 下熟練開發(fā)的人,基本上手都有 20-50 個(gè)插件,遙想十年前,Vim里常用的插件一只手都數(shù)得過來。過去我一直使用老牌的 Vundle 來管理插件,但是隨著插件越來越多,更新越來越頻繁,Vundle 這種每次更新就要好幾分鐘的東西實(shí)在是不堪重負(fù)了。

在我逐步對 Vundle 失去耐心之后,我試用了 vim-plug ,用了兩天以后就再也回不去 Vundle了,它支持全異步的插件安裝,安裝50個(gè)插件只需要一分鐘不到的時(shí)間,這在 Vundle 下面根本不可想像的事情,插件更新也很快,不像原來每次更新都可以去喝杯茶去,最重要的是它支持插件延遲加載:

“ 定義插件,默認(rèn)用法,和 Vundle 的語法差不多Plug ‘junegunn/vim-easy-align’Plug ‘skywind3000/quickmenu.vim’” 延遲按需加載,使用到命令的時(shí)候再加載或者打開對應(yīng)文件類型才加載Plug ‘scrooloose/nerdtree’, { ‘on’: ‘NERDTreeToggle’ }Plug ‘tpope/vim-fireplace’, { ‘for’: ‘clojure’ }“ 確定插件倉庫中的分支或者 tagPlug ‘rdnetto/YCM-Generator’, { ‘branch’: ‘stable’ }Plug ‘nsf/gocode’, { ‘tag’: ‘v.20150303’, ‘rtp’: ‘vim’ }

定義好插件以后一個(gè) :PlugInstall 命令就并行安裝所有插件了,比 Vundle 快捷不少,關(guān)鍵是 vim-plug 只有單個(gè)文件,正好可以放在我 github 上的 vim 配置倉庫中,每次需要更新 vim-plug 時(shí)只需要 :PlugUpgrade,即可自我更新。使用時(shí)建議給插件分組,同類別插件放一個(gè)組里,vimrc 里面只需要確定下啟用哪些組就行了。

拋棄 Vundle 切換到 vim-plug 以后,不僅插件安裝和更新快了一個(gè)數(shù)量級(jí),大量的插件我都配置成了延遲加載,Vim 啟動(dòng)速度比 Vundle 時(shí)候提高了不少。使用 Vundle 的時(shí)候一旦插件數(shù)量超過30個(gè),管理是一件很痛苦的事情,而用了 vim-plug 以后,50-60個(gè)插件都輕輕松松。

符號(hào)索引

現(xiàn)在有好多 ctags 的代替品,比如 gtags, etags 和 cquery。然而我并不排斥 ctags,因?yàn)樗С?50+ 種語言,沒有任何一個(gè)符號(hào)索引工具有它支持的語言多。同時(shí) Vim 和 ctags 集成的相當(dāng)好,用它依賴最少,大量基礎(chǔ)工作可以直接通過 ctags 進(jìn)行,然而到現(xiàn)在為止,我就沒見過幾個(gè)人把 ctags 用對了的。

就連配置文件他們都沒寫對,正確的 ctags 配置應(yīng)該是:

set tags=。/.tags;,.tags

這里解釋一下,首先我把 tag 文件的名字從“tags” 換成了 “.tags”,前面多加了一個(gè)點(diǎn),這樣即便放到項(xiàng)目中也不容易污染當(dāng)前項(xiàng)目的文件,刪除時(shí)也好刪除,gitignore 也好寫,默認(rèn)忽略點(diǎn)開頭的文件名即可。

前半部分 “。/.tags; ”代表在文件的所在目錄下(不是 “:pwd”返回的 Vim 當(dāng)前目錄)查找名字為 “.tags”的符號(hào)文件,后面一個(gè)分號(hào)代表查找不到的話向上遞歸到父目錄,直到找到 .tags 文件或者遞歸到了根目錄還沒找到,這樣對于復(fù)雜工程很友好,源代碼都是分布在不同子目錄中,而只需要在項(xiàng)目頂層目錄放一個(gè) .tags文件即可;逗號(hào)分隔的后半部分 .tags 是指同時(shí)在 Vim 的當(dāng)前目錄(“:pwd”命令返回的目錄,可以用 :cd 。.命令改變)下面查找 .tags 文件。

最后請更新你的 ctags,不要再使用老舊的 Exuberant Ctags,這貨停止更新快十年了,請使用最新的 Universal CTags 代替之,它在 Exuberant Ctags 的基礎(chǔ)上繼續(xù)更新迭代了近十年,如今任然活躍的維護(hù)著,功能更強(qiáng)大,語言支持更多。

(注意最新版 universal ctags 調(diào)用時(shí)需要加一個(gè) --output-format=e-ctags,輸出格式才和老的 exuberant ctags 兼容否則會(huì)有 windows 下路徑名等小問題)。

自動(dòng)索引

過去寫幾行代碼又需要運(yùn)行一下 ctags 來生成索引,每次生成耗費(fèi)不少時(shí)間。如今 Vim 8 下面自動(dòng)異步生成 tags 的工具有很多,這里推薦最好的一個(gè):vim-gutentags,這個(gè)插件主要做兩件事情:

- 確定文件所屬的工程目錄,即文件當(dāng)前路徑向上遞歸查找是否有 `.git`, `.svn`, `.project` 等標(biāo)志性文件(可以自定義)來確定當(dāng)前文檔所屬的工程目錄。

- 檢測同一個(gè)工程下面的文件改動(dòng),能會(huì)自動(dòng)增量更新對應(yīng)工程的 `.tags` 文件。每次改了幾行不用全部重新生成,并且這個(gè)增量更新能夠保證 `.tags` 文件的符號(hào)排序,方便 Vim 中用二分查找快速搜索符號(hào)。

vim-gutentags 需要簡單配置一下:

” gutentags 搜索工程目錄的標(biāo)志,碰到這些文件/目錄名就停止向上一級(jí)目錄遞歸let g:gutentags_project_root = [‘.root’, ‘.svn’, ‘.git’, ‘.hg’, ‘.project’]“ 所生成的數(shù)據(jù)文件的名稱let g:gutentags_ctags_tagfile = ‘.tags’” 將自動(dòng)生成的 tags 文件全部放入 ~/.cache/tags 目錄中,避免污染工程目錄let s:vim_tags = expand(‘~/.cache/tags’)let g:gutentags_cache_dir = s:vim_tags“ 配置 ctags 的參數(shù)let g:gutentags_ctags_extra_args = [‘--fields=+niazS’, ‘--extra=+q’]let g:gutentags_ctags_extra_args += [‘--c++-kinds=+px’]let g:gutentags_ctags_extra_args += [‘--c-kinds=+px’]” 檢測 ~/.cache/tags 不存在就新建if !isdirectory(s:vim_tags) silent! call mkdir(s:vim_tags, ‘p’)endif

有了上面的設(shè)置,你平時(shí)基本感覺不到 tags 文件的生成過程了,只要文件修改過,gutentags 都在后臺(tái)為你默默打點(diǎn)是否需要更新數(shù)據(jù)文件,你根本不用管,還會(huì)幫你:setlocal tags+=。.. 添加到局部 tags 搜索列表中。

為當(dāng)前文件添加上對應(yīng)的 tags 文件的路勁而不影響其他文件。得益于 Vim 8 的異步機(jī)制,你可以任意隨時(shí)使用 ctags 相關(guān)功能,并且數(shù)據(jù)庫都是最新的。需要注意的是,gutentags 需要靠上面定義的 project_root 里的標(biāo)志,判斷文件所在的工程,如果一個(gè)文件沒有托管在 .git/.svn 中,gutentags 找不到工程目錄的話,就不會(huì)為該野文件生成 tags,這也很合理。想要避免的話,你可以在你的野文件目錄中放一個(gè)名字為 .root 的空白文件,主動(dòng)告訴 gutentags 這里就是工程目錄。

最后啰嗦兩句,少用 CTRL-] 直接在當(dāng)前窗口里跳轉(zhuǎn)到定義,多使用 CTRL-W ] 用新窗口打開并查看光標(biāo)下符號(hào)的定義,或者 CTRL-W } 使用 preview 窗口預(yù)覽光標(biāo)下符號(hào)的定義。

我自己還寫過不少關(guān)于 ctags 的 vimscript,例如在最下面命令行顯示函數(shù)的原型而不用急著跳轉(zhuǎn),或者重復(fù)按 `ALT+;` 在 preview 窗口中輪流查看多個(gè)定義,不切走當(dāng)前窗口,不會(huì)出一個(gè)很長的列表讓你選擇,有興趣可以刨我的 vim dotfiles。

編譯運(yùn)行

再 Vim 8 以前,編譯和運(yùn)行程序要么就讓 vim 傻等著結(jié)束,不能做其他事情,要么切到一個(gè)新的終端下面去單獨(dú)運(yùn)行編譯命令和執(zhí)行命令,要么開個(gè) tmux 左右切換。如今新版本的異步模式可以讓這個(gè)流程更加簡化,這里我們使用 AsyncRun 插件,簡單設(shè)置下:

Plug ‘skywind3000/asyncrun.vim’“ 自動(dòng)打開 quickfix window ,高度為 6let g:asyncrun_open = 6” 任務(wù)結(jié)束時(shí)候響鈴提醒let g:asyncrun_bell = 1“ 設(shè)置 F10 打開/關(guān)閉 Quickfix 窗口nnoremap 《F10》 :call asyncrun#quickfix_toggle(6)《cr》

該插件可以在后臺(tái)運(yùn)行 shell 命令,并且把結(jié)果輸出到 quickfix 窗口:

最簡單的編譯單個(gè)文件,和 sublime 的默認(rèn) build system 差不多,我們定義 F9 為編譯單文件:

nnoremap 《silent》 《F9》 :AsyncRun gcc -Wall -O2 “$(VIM_FILEPATH)” -o “$(VIM_FILEDIR)/$(VIM_FILENOEXT)” 《cr》

其中 $(。..) 形式的宏在執(zhí)行時(shí)會(huì)被替換成實(shí)際的文件名或者文件目錄,這樣按 F9 就可以編譯當(dāng)前文件,同時(shí)按 F5 運(yùn)行:

nnoremap 《silent》 《F5》 :AsyncRun -raw -cwd=$(VIM_FILEDIR) “$(VIM_FILEDIR)/$(VIM_FILENOEXT)” 《cr》

用雙引號(hào)引起來避免文件名包含空格,“-cwd=$(VIM_FILEDIR)” 的意思時(shí)在文件文件的所在目錄運(yùn)行可執(zhí)行,后面可執(zhí)行使用了全路徑,避免 linux 下面當(dāng)前路徑加 “。/” 而 windows 不需要的跨平臺(tái)問題。

參數(shù) `-raw` 表示輸出不用匹配錯(cuò)誤檢測模板 (errorformat) ,直接原始內(nèi)容輸出到 quickfix 窗口。這樣你可以一邊編輯一邊 F9 編譯,出錯(cuò)了可以在 quickfix 窗口中按回車直接跳轉(zhuǎn)到錯(cuò)誤的位置,編譯正確就接著執(zhí)行。

接下來是項(xiàng)目的編譯,不管你直接使用 make 還是 cmake,都是對一群文件做點(diǎn)什么,都需要定位到文件所屬項(xiàng)目的目錄,AsyncRun 識(shí)別當(dāng)前文件的項(xiàng)目目錄方式和 gutentags相同,從文件所在目錄向上遞歸,直到找到名為 “.git”, “.svn”, “.hg”或者 “.root”文件或者目錄,如果遞歸到根目錄還沒找到,那么文件所在目錄就被當(dāng)作項(xiàng)目目錄,你重新定義項(xiàng)目標(biāo)志:

let g:asyncrun_rootmarks = [‘.svn’, ‘.git’, ‘.root’, ‘_darcs’, ‘build.xml’]

然后在 AsyncRun 命令行中,用 “《root》” 或者 “$(VIM_ROOT)”來表示項(xiàng)目所在路徑,于是我們可以定義按 F7 編譯整個(gè)項(xiàng)目:

nnoremap 《silent》 《F7》 :AsyncRun -cwd=《root》 make 《cr》

那么如果你有一個(gè)項(xiàng)目不在 svn 也不在 git 中怎么查找 《root》 呢?很簡單,放一個(gè)空的 .root 文件到你的項(xiàng)目目錄下就行了,前面配置過,識(shí)別名為 .root 的文件。

繼續(xù)配置用 F8 運(yùn)行當(dāng)前項(xiàng)目:

nnoremap 《silent》 《F8》 :AsyncRun -cwd=《root》 -raw make run 《cr》

當(dāng)然,你的 makefile 中需要定義怎么 run ,接著按 F6 執(zhí)行測試:

nnoremap 《silent》 《F6》 :AsyncRun -cwd=《root》 -raw make test 《cr》

如果你使用了 cmake 的話,還可以照葫蘆畫瓢,定義 F4 為更新 Makefile 文件,如果不用 cmake 可以忽略:

nnoremap 《silent》 《F4》 :AsyncRun -cwd=《root》 cmake 。 《cr》

由于 C/C++ 標(biāo)準(zhǔn)庫的實(shí)現(xiàn)方式是發(fā)現(xiàn)在后臺(tái)運(yùn)行時(shí)會(huì)緩存標(biāo)準(zhǔn)輸出直到程序退出,你想實(shí)時(shí)看到 printf 輸出的話需要 fflush(stdout) 一下,或者程序開頭關(guān)閉緩存:“setbuf(stdout, NULL);” 即可。

同時(shí),如果你開發(fā) C++ 程序使用 std::cout 的話,后面直接加一個(gè) std::endl 就強(qiáng)制刷新緩存了,不需要弄其他。而如果你在 Windows 下使用 GVim 的話,可以彈出新的 cmd.exe 窗口來運(yùn)行剛才的程序:

nnoremap 《silent》 《F5》 :AsyncRun -cwd=$(VIM_FILEDIR) -mode=4 “$(VIM_FILEDIR)/$(VIM_FILENOEXT)” 《cr》nnoremap 《silent》 《F8》 :AsyncRun -cwd=《root》 -mode=4 make run 《cr》

在 Windows 下使用 -mode=4 選項(xiàng)可以跟 Visual Studio 執(zhí)行命令行工具一樣,彈出一個(gè)新的 cmd.exe窗口來運(yùn)行程序或者項(xiàng)目,于是我們有了下面的快捷鍵:

F4:使用 cmake 生成 Makefile

F5:單文件:運(yùn)行

F6:項(xiàng)目:測試

F7:項(xiàng)目:編譯

F8:項(xiàng)目:運(yùn)行

F9:單文件:編譯

F10:打開/關(guān)閉底部的 quickfix 窗口

恩,編譯和運(yùn)行基本和 NotePad++ / GEdit 的體驗(yàn)差不多了。如果你重度使用 cmake 的話,你還可以寫點(diǎn)小腳本,將 F4 和 F7 的功能合并,檢測 CMakeLists.txt 文件改變的話先執(zhí)行 cmake 更新一下 Makefile,然后再執(zhí)行 make,否則直接執(zhí)行 make,這樣更自動(dòng)化些。

動(dòng)態(tài)檢查

代碼檢查是個(gè)好東西,讓你在編輯文字的同時(shí)就幫你把潛在錯(cuò)誤標(biāo)注出來,不用等到編譯或者運(yùn)行了才發(fā)現(xiàn)。我很奇怪 2018 年了,為啥網(wǎng)上還在到處介紹老舊的 syntastic,但凡見到介紹這個(gè)插件的文章基本都可以不看了。老的 syntastic 基本沒法用,不能實(shí)時(shí)檢查,一保存文件就運(yùn)行檢查器并且等待半天,所以請用實(shí)時(shí) linting 工具 ALE:

大概長這個(gè)樣子,隨著你不斷的編輯新代碼,有語法錯(cuò)誤的地方會(huì)實(shí)時(shí)幫你標(biāo)注出來,側(cè)邊會(huì)標(biāo)注本行有錯(cuò),光標(biāo)移動(dòng)過去的時(shí)候下面會(huì)顯示錯(cuò)誤原因,而具體錯(cuò)誤的符號(hào)下面會(huì)有紅色波浪線提醒。Ale 支持多種語言的各種代碼分析器,就 C/C++ 而言,就支持:gcc, clang, cppcheck 以及 clang-format 等,需要另行安裝并放入 PATH下面,ALE能在你修改了文本后自動(dòng)調(diào)用這些 linter 來分析最新代碼,然后將各種 linter 的結(jié)果進(jìn)行匯總并顯示再界面上。

同樣,我們也需要簡單配置一下:

let g:ale_linters_explicit = 1let g:ale_completion_delay = 500let g:ale_echo_delay = 20let g:ale_lint_delay = 500let g:ale_echo_msg_format = ‘[%linter%] %code: %%s’let g:ale_lint_on_text_changed = ‘normal’let g:ale_lint_on_insert_leave = 1let g:airline#extensions#ale#enabled = 1let g:ale_c_gcc_options = ‘-Wall -O2 -std=c99’let g:ale_cpp_gcc_options = ‘-Wall -O2 -std=c++14’let g:ale_c_cppcheck_options = ‘’let g:ale_cpp_cppcheck_options = ‘’

基本上就是定義了一下運(yùn)行規(guī)則,信息顯示格式以及幾個(gè) linter 的運(yùn)行參數(shù),其中 6,7 兩行比較重要,它規(guī)定了如果 normal 模式下文字改變以及離開 insert 模式的時(shí)候運(yùn)行 linter,這是相對保守的做法,如果沒有的話,會(huì)導(dǎo)致 YouCompleteMe 的補(bǔ)全對話框頻繁刷新。

記得設(shè)置一下各個(gè) linter 的參數(shù),忽略一些你覺得沒問題的規(guī)則,不然錯(cuò)誤太多沒法看。默認(rèn)錯(cuò)誤和警告的風(fēng)格都太難看了,你需要修改一下,比如我使用 GVim,就重新定義了警告和錯(cuò)誤的樣式,去除默認(rèn)難看的紅色背景,代碼正文使用干凈的波浪下劃線表示:

let g:ale_sign_error = “\\ue009\\ue009”hi! clear SpellBadhi! clear SpellCaphi! clear SpellRarehi! SpellBad gui=undercurl guisp=redhi! SpellCap gui=undercurl guisp=bluehi! SpellRare gui=undercurl guisp=magenta

不同項(xiàng)目之間如果評測標(biāo)準(zhǔn)不一樣還可以具體單獨(dú)制定 linter 的參數(shù),具體見 ALE 幫助文檔了。我基本使用兩個(gè)檢查器:gcc 和 cppcheck,都可以在 ALE 中進(jìn)行詳細(xì)配置,前者主要檢查有無語法錯(cuò)誤,后者主要會(huì)給出一些編碼建議,和對危險(xiǎn)寫法的警告。

我之前用 syntastic 時(shí)就用了兩天就徹底刪除了,而開始用 ALE 后,一用上就停不下來,頭兩天我還一度覺得它就是個(gè)可有可無的點(diǎn)綴,但是第三天它幫我找出兩個(gè)潛在的 bug 的時(shí)候,我開始覺得沒白安裝,比如:

即便你使用各類 C/C++ IDE,也只能給實(shí)時(shí)你標(biāo)注一些編譯錯(cuò)誤或者警告,而使用 ALE + cppcheck/gcc,連上面類似的潛在錯(cuò)誤都能幫你自動(dòng)找出來,并且當(dāng)你光標(biāo)移動(dòng)過去時(shí)在最下面命令行提示你錯(cuò)誤原因。

用上一段時(shí)間以后,讓你寫 C/C++ 有一種安心和舒適的感覺。

修改比較

這是個(gè)小功能,在側(cè)邊欄顯示一個(gè)修改狀態(tài),對比當(dāng)前文本和 git/svn 倉庫里的版本,在側(cè)邊欄顯示修改情況,以前 Vim 做不到實(shí)時(shí)顯示修改狀態(tài),如今推薦使用 vim-signify 來實(shí)時(shí)顯示修改狀態(tài),它比 gitgutter 強(qiáng),除了 git 外還支持 svn/mercurial/cvs 等十多種主流版本管理系統(tǒng)。

沒注意到它時(shí),你可能覺得它不存在,當(dāng)你有時(shí)真的看上兩眼時(shí),你會(huì)發(fā)現(xiàn)這個(gè)功能很貼心。最新版 signify 還有一個(gè)命令`:SignifyDiff`,可以左右分屏對比提交前后記錄,比你命令行 svn/git diff 半天直觀多了。并且對我這種同時(shí)工作在 subversion 和 git 環(huán)境下的情況契合的比較好。

Signify 和前面的 ALE 都會(huì)在側(cè)邊欄顯示一些標(biāo)記,默認(rèn)側(cè)邊欄會(huì)自動(dòng)隱藏,有內(nèi)容才會(huì)顯示,不喜歡側(cè)邊欄時(shí)有時(shí)無的行為可設(shè)置強(qiáng)制顯示側(cè)邊欄:“set signcolumn=yes” 。

文本對象

相信大家用 Vim 進(jìn)行編輯時(shí)都很喜歡文本對象這個(gè)概念,diw 刪除光標(biāo)所在單詞,ciw 改寫單詞,vip 選中段落等,ci“/ci( 改寫引號(hào)/括號(hào)中的內(nèi)容。而編寫 C/C++ 代碼時(shí)我推薦大家補(bǔ)充幾個(gè)十分有用的文本對象,可以使用 textobj-user 全家桶:

Plug ‘kana/vim-textobj-user’Plug ‘kana/vim-textobj-indent’Plug ‘kana/vim-textobj-syntax’Plug ‘kana/vim-textobj-function’, { ‘for’:[‘c’, ‘cpp’, ‘vim’, ‘java’] }Plug ‘sgur/vim-textobj-parameter’

它新定義的文本對象主要有:

i, 和 a, :參數(shù)對象,寫代碼一半在修改,現(xiàn)在可以用 di, 或 ci, 一次性刪除/改寫當(dāng)前參數(shù)

ii 和 ai :縮進(jìn)對象,同一個(gè)縮進(jìn)層次的代碼,可以用 vii 選中,dii / cii 刪除或改寫

if 和 af :函數(shù)對象,可以用 vif / dif / cif 來選中/刪除/改寫函數(shù)的內(nèi)容

最開始我不太想用額外的文本對象,一直在堅(jiān)持 Vim 固有的幾個(gè)默認(rèn)對象,生怕手練習(xí)慣了肌肉形成記憶到遠(yuǎn)端沒有環(huán)境的 vim 下形成依賴改不過來,后來我慢慢發(fā)現(xiàn)挺有用的,比如改寫參數(shù),以前是比較麻煩的事情,這下流暢了很多,當(dāng)我發(fā)現(xiàn)自己編碼效率得到比較大的提升時(shí),才發(fā)現(xiàn)習(xí)慣依賴不重要,行云流水才是真重要。以前看到過無數(shù)次都選擇性忽略的東西,有時(shí)候試試可能會(huì)有新的發(fā)現(xiàn)。

編輯輔助

大家都知道 color 文件定義了眾多不同語法元素的色彩,還有一個(gè)關(guān)鍵因素就是語法文件本身能否識(shí)別并標(biāo)記得出眾多不同的內(nèi)容來?語法文件對某些東西沒標(biāo)注,你 color 文件確定了顏色也沒用。因此 Vim 下面寫 C/C++ 代碼,語法高亮準(zhǔn)確豐富的話能讓你編碼的心情好很多,這里推薦 vim-cpp-enhanced-highlight 插件,提供比 Vim 自帶語法文件更好的 C/C++ 語法標(biāo)注,支持 標(biāo)準(zhǔn) 11/14/17。

前面編譯運(yùn)行時(shí)需要頻繁的操作 quickfix 窗口,ale查錯(cuò)時(shí)也需要快速再錯(cuò)誤間跳轉(zhuǎn)(location list),就連文件比較也會(huì)用到快速跳轉(zhuǎn)到上/下一個(gè)差異處,unimpaired 插件幫你定義了一系列方括號(hào)開頭的快捷鍵,被稱為官方 Vim 中丟失的快捷鍵。

我們好些地方用到了 quickfix / location 窗口,你在 quickfix 中回車選中一條錯(cuò)誤的話,默認(rèn)會(huì)把你當(dāng)前窗口給切走,變成新文件,雖然按 CTRL+O 可以返回,但是如果不太喜歡這樣切走當(dāng)前文件的做法,可以設(shè)置 switchbuf,發(fā)現(xiàn)文件已在 Vim 中打開就跳過去,沒打開過就新建窗口/標(biāo)簽打開,具體見幫助。

Vim最爽的地方是把所有 ALT 鍵映射全部留給用戶了,盡量使用 Vim 的 ALT鍵映射,可以讓冗長的快捷鍵縮短很多,請參考:《Vim和終端軟件中支持ALT映射》。

代碼補(bǔ)全

傳統(tǒng)的 Vim 代碼補(bǔ)全基本以 omni 系列補(bǔ)全和符號(hào)補(bǔ)全為主,omni 補(bǔ)全系統(tǒng)是 Vim 自帶的針對不同文件類型編寫不同的補(bǔ)全函數(shù)的基礎(chǔ)語義補(bǔ)全系統(tǒng),搭配 neocomplete 可以很方便的對所有補(bǔ)全結(jié)果(omni補(bǔ)全/符號(hào)補(bǔ)全/字典補(bǔ)全)進(jìn)行一個(gè)合成并且自動(dòng)彈出補(bǔ)全框,雖然趕不上 IDE 的補(bǔ)全,但是已經(jīng)比大部分編輯器補(bǔ)全好用很多了。然而傳統(tǒng) Vim 補(bǔ)全還是有兩個(gè)邁不過去的坎:語義補(bǔ)全太弱,其次是補(bǔ)全分析無法再后臺(tái)運(yùn)行,對大項(xiàng)目而言,某些復(fù)雜符號(hào)的補(bǔ)全會(huì)拖慢你的打字速度。

新一代的 Vim 補(bǔ)全系統(tǒng),YouCompleteMe 和 Deoplete,都支持異步補(bǔ)全和基于 clang 的語義補(bǔ)全,前者集成度高,后者擴(kuò)展方便。對于 C/C++ 的話,我推薦 YCM,因?yàn)?deoplete 的 clang 補(bǔ)全插件不夠穩(wěn)定,太吃內(nèi)存,并且反應(yīng)比較慢,它的代碼量和代碼質(zhì)量和 YCM完全不是一個(gè)量級(jí)的。所以 C/C++ 的補(bǔ)全的話,請直接使用 YCM,沒有之一,而使用 YCM的話,需要進(jìn)行一些簡單的調(diào)教:

let g:ycm_add_preview_to_completeopt = 0let g:ycm_show_diagnostics_ui = 0let g:ycm_server_log_level = ‘info’let g:ycm_min_num_identifier_candidate_chars = 2let g:ycm_collect_identifiers_from_comments_and_strings = 1let g:ycm_complete_in_strings=1let g:ycm_key_invoke_completion = ‘《c-z》’set completeopt=menu,menuonenoremap 《c-z》 《NOP》let g:ycm_semantic_triggers = { \ ‘c,cpp,python,java,go,erlang,perl’: [‘re!\w{2}’], \ ‘cs,lua,javascript’: [‘re!\w{2}’], \ }

這樣可以輸入兩個(gè)字符就自動(dòng)彈出語義補(bǔ)全,不用等到輸入句號(hào) 。 或者 -》 才觸發(fā),同時(shí)關(guān)閉了預(yù)覽窗口和代碼診斷這些 YCM 花邊功能,保持清靜,對于原型預(yù)覽和診斷我們后面有更好的解決方法,YCM這兩項(xiàng)功能干擾太大。

上面這幾行配置具體每行的含義,可以見:《YouCompleteMe 中容易忽略的配置》。另外我在 Windows 下編譯了一個(gè)版本,你用 Windows 的話無需下載VS編譯,點(diǎn)擊 [這里]。我日常開發(fā)使用 YCM 輔助編寫 C/C++, Python 和 Go 代碼,基本能提供 IDE 級(jí)別的補(bǔ)全。

函數(shù)列表

不再建議使用 tagbar, 它會(huì)在你保存文件的時(shí)候以同步等待的方式運(yùn)行 ctags (即便你沒有打開 tagbar),導(dǎo)致vim操作變卡,特別是 windows下開了反病毒軟件掃描的話,有時(shí)候保存文件卡5-6秒。2018年了,我們有更好的選擇,比如使用

@Yggdroot

開發(fā)的 LeaderF 來顯示函數(shù)列表:

全異步顯示文件函數(shù)列表,不用的時(shí)候不會(huì)占用你任何屏幕空間,將 ALT+P 綁定到 `:LeaderfFunction!` 這個(gè)命令上,按 ALT+P 就彈出當(dāng)前文件的函數(shù)列表,然后可以進(jìn)行模糊匹配搜索,除了上下鍵移動(dòng)選擇外,各種vim的跳轉(zhuǎn)和搜索命令都可以始用,回車跳轉(zhuǎn)然后關(guān)閉函數(shù)列表,除此之外按 i 進(jìn)入模糊匹配,按TAB切換回列表選擇。

Leaderf 的函數(shù)功能屬于你想要它的時(shí)候它才會(huì)出來,不想要它的時(shí)候不會(huì)給你搗亂。

文件切換

文件/buffer模糊匹配快速切換的方式,比你打開一個(gè)對話框選擇文件便捷不少,過去我們常用的 CtrlP 可以光榮下崗了,如今有更多速度更快,匹配更精準(zhǔn)以及完美支持后臺(tái)運(yùn)行方式的文件模糊匹配工具。我自己用的是上面提到的 LeaderF,除了提供函數(shù)列表外,還支持文件,MRU,Buffer名稱搜索,完美代替 CtrlP,使用時(shí)需要簡單調(diào)教下:

let g:Lf_ShortcutF = ‘《c-p》’let g:Lf_ShortcutB = ‘《m-n》’noremap 《c-n》 :LeaderfMru《cr》noremap 《m-p》 :LeaderfFunction!《cr》noremap 《m-n》 :LeaderfBuffer《cr》noremap 《m-m》 :LeaderfTag《cr》let g:Lf_StlSeparator = { ‘left’: ‘’, ‘right’: ‘’, ‘font’: ‘’ }let g:Lf_RootMarkers = [‘.project’, ‘.root’, ‘.svn’, ‘.git’]let g:Lf_WorkingDirectoryMode = ‘Ac’let g:Lf_WindowHeight = 0.30let g:Lf_CacheDirectory = expand(‘~/.vim/cache’)let g:Lf_ShowRelativePath = 0let g:Lf_HideHelp = 1let g:Lf_StlColorscheme = ‘powerline’let g:Lf_PreviewResult = {‘Function’:0, ‘BufTag’:0}

這里定義了 CTRL+P 在當(dāng)前項(xiàng)目目錄打開文件搜索,CTRL+N 打開 MRU搜索,搜索你最近打開的文件,這兩項(xiàng)是我用的最頻繁的功能。接著 ALT+P 打開函數(shù)搜索,ALT+N 打開 Buffer 搜索:

LeaderF 是目前匹配效率最高的,高過 CtrlP/Fzf 不少,敲更少的字母就能把文件找出來,同時(shí)搜索很迅速,使用 Python 后臺(tái)線程進(jìn)行搜索匹配,還有一個(gè) C模塊可以加速匹配性能,需要手工編譯下。LeaderF在模糊匹配模式下按 TAB 可以切換到匹配結(jié)果窗口用光標(biāo)或者 Vim 搜索命令進(jìn)一步篩選,這是 CtrlP/Fzf 不具備的,更多方便的功能見它的官方文檔。

文件/MRU 模糊匹配對于熟悉的項(xiàng)目效率是最高的,但對于一個(gè)新的項(xiàng)目,通常我們都不知道它有些什么文件,那就談不上根據(jù)文件名匹配什么了,我們需要文件瀏覽功能。如果你喜歡把 Vim 偽裝成 NotePad++ 之類的,那你該繼續(xù)使用 NERDTree 進(jìn)行文件瀏覽,但你想按照 Vim 的方式來,推薦閱讀這篇文章:

Oil and vinegar - split windows and project drawer

然后像我一樣開始使用 vim-dirvish,進(jìn)行一些配置,比如當(dāng)前文檔按“-”號(hào)就能不切窗口的情況下在當(dāng)前窗口直接返回當(dāng)前文檔所在的目錄,再按一次減號(hào)就返回上一級(jí)目錄,按回車進(jìn)入下一級(jí)目錄或者再當(dāng)前窗口打開光標(biāo)下的文件。進(jìn)一步映射 “《tab》7” , “《tab》8” 和 “《tab》9” 分別用于在新的 split, vsplit 和新標(biāo)簽打開當(dāng)前文件所在目錄,這樣從一個(gè)文件如手,很容易找到和該文件相關(guān)的其他項(xiàng)目文件。

最后一個(gè)是 C/C++ 的頭文件/源文件快速切換功能,有現(xiàn)成的插件做這事情,比如 a.vim,我自己沒用,因?yàn)檫@事情太簡單,再我發(fā)現(xiàn) a.vim 前我就覺得需要這個(gè)功能,然后自己兩行 vim 腳本就搞定了。

參數(shù)提示

這個(gè)功能應(yīng)人而異,有人覺得不需要,有人覺得管用。寫 C/C++ 時(shí)函數(shù)忘了可以用上面的 YCM 補(bǔ)全,但很多時(shí)候是參數(shù)忘記了怎么辦?YCM的參數(shù)提示很蛋疼,要打開個(gè) Preview 窗口,實(shí)在是太影響我的視線了,我自己寫過一些參數(shù)提醒功能,可以在最下面的命令行顯示當(dāng)前函數(shù)的參數(shù),不過這是基于 tags 的,搭配前面的 gutentags,對其他語言很管用,但對 C/C++ 我們還可以使用更好的 echodoc 插件:

它可以無縫的和前面的 YCM 搭配,用 libclang 給你生成參數(shù)提示,當(dāng)你用 YCM 的 tab 補(bǔ)全了一個(gè)函數(shù)名后,只要輸入左括號(hào),下面命令行就會(huì)里面顯示出該函數(shù)的參數(shù)信息,隨著光標(biāo)移動(dòng),下面還會(huì)高亮出來你正在處于哪個(gè)參數(shù)位置。

唯一需要設(shè)置的是使用 “set noshowmode”關(guān)閉模式提示,就是底部 ---INSERT--- 那個(gè),我們一般都用 airline / lightline 之類的顯示當(dāng)前模式了,所以默認(rèn)模式提示可以關(guān)閉,INSERT 模式下的命令行,完全留給 echodoc 顯示參數(shù)使用。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11182

    瀏覽量

    208518
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7581

    瀏覽量

    135632
  • C++
    C++
    +關(guān)注

    關(guān)注

    21

    文章

    2090

    瀏覽量

    73419
收藏 人收藏

    評論

    相關(guān)推薦

    【北京迅為】itop-龍芯2k1000開發(fā)指南Linux基礎(chǔ)入門vim 編輯器

    【北京迅為】itop-龍芯2k1000開發(fā)指南Linux基礎(chǔ)入門vim 編輯器
    的頭像 發(fā)表于 10-25 14:56 ?128次閱讀
    【北京迅為】itop-龍芯2k1000<b class='flag-5'>開發(fā)</b>指南<b class='flag-5'>Linux</b>基礎(chǔ)入門<b class='flag-5'>vim</b> 編輯器

    SemiDrive X9 AI 開發(fā)環(huán)境搭建

    :支持操作系統(tǒng):Android、Linux和QNX;支持推理后端:CPU、GPU、SlimAI和AIPU;支持開發(fā)及部署語言C++和Python;支持異構(gòu)和同構(gòu)
    的頭像 發(fā)表于 08-03 08:27 ?280次閱讀
    SemiDrive X9 AI <b class='flag-5'>開發(fā)</b><b class='flag-5'>環(huán)境</b><b class='flag-5'>搭建</b>

    PyTorch深度學(xué)習(xí)開發(fā)環(huán)境搭建指南

    PyTorch作為一種流行的深度學(xué)習(xí)框架,其開發(fā)環(huán)境搭建對于深度學(xué)習(xí)研究者和開發(fā)者來說至關(guān)重要。在Windows操作系統(tǒng)上搭建PyTorc
    的頭像 發(fā)表于 07-16 18:29 ?622次閱讀

    在WIN10怎么搭建CY7C68013的開發(fā)環(huán)境?

    如題, 1,在WIN10怎么搭建CY7C68013的開發(fā)環(huán)境? 2,我已經(jīng)安裝了CYUSB3014的
    發(fā)表于 02-27 08:14

    TLT507-Android開發(fā)環(huán)境搭建

    TLT507-Android開發(fā)環(huán)境搭建
    的頭像 發(fā)表于 01-26 17:03 ?539次閱讀
    TLT507-Android<b class='flag-5'>開發(fā)</b><b class='flag-5'>環(huán)境</b><b class='flag-5'>搭建</b>

    安信可Ai-M61/Ai-M62系列模組Linux開發(fā)環(huán)境搭建

    軟件燒錄(windows) 四、開發(fā)資料 01 Ubuntu安裝 在Linux編譯速度比windows快很多,一般推薦優(yōu)先使用linux環(huán)境
    的頭像 發(fā)表于 12-25 16:59 ?533次閱讀
    安信可Ai-M61/Ai-M62系列模組<b class='flag-5'>Linux</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>環(huán)境</b><b class='flag-5'>搭建</b>

    php運(yùn)行環(huán)境搭建方法

    搭建PHP運(yùn)行環(huán)境開發(fā)PHP應(yīng)用程序的基礎(chǔ),本文將詳盡、詳實(shí)、細(xì)致地介紹從零開始搭建PHP運(yùn)行環(huán)境的方法,包括選擇操作系統(tǒng)、安裝Web服務(wù)
    的頭像 發(fā)表于 12-04 14:56 ?1166次閱讀

    linux怎么執(zhí)行vim編輯的程序

    Linux系統(tǒng)中執(zhí)行vim編輯的程序非常簡單,只需要依次執(zhí)行以下步驟: 打開終端:在Linux系統(tǒng)中,按Ctrl+Alt+T組合鍵可以快速打開終端。 輸入
    的頭像 發(fā)表于 11-28 15:23 ?787次閱讀

    linux使用vim新建并編輯文件

    Linux系統(tǒng)Vim是一款功能強(qiáng)大的文本編輯器。它可以用于新建并編輯文件,具有很多高級(jí)功能和快捷鍵。下面是關(guān)于如何在Linux上使用
    的頭像 發(fā)表于 11-28 15:17 ?2839次閱讀

    常用的c語言開發(fā)環(huán)境有哪些

    C語言是一種廣泛應(yīng)用于系統(tǒng)編程、嵌入式開發(fā)和科學(xué)計(jì)算等領(lǐng)域的高級(jí)編程語言。為了能夠高效地開發(fā)C
    的頭像 發(fā)表于 11-27 16:14 ?5331次閱讀

    C語言運(yùn)行環(huán)境是什么

    C語言運(yùn)行環(huán)境C language runtime environment)是指在執(zhí)行C語言
    的頭像 發(fā)表于 11-27 16:13 ?3193次閱讀

    linux怎么保存退出vim

    Linux系統(tǒng)中,使用vim作為編輯器是非常常見的。vim是一個(gè)強(qiáng)大的文本編輯器,擁有豐富的功能和快捷鍵。保存并退出vim可以通過以下步驟完成: 打開
    的頭像 發(fā)表于 11-27 14:19 ?8924次閱讀

    linux怎么執(zhí)行vim編輯的程序

    Linux中,你可以通過以下步驟執(zhí)行Vim編輯器中編寫的程序: 打開終端或命令行界面。 使用Vim編輯器打開你的程序文件。假設(shè)你的程序文件名為"program.c",可以使用以下命令
    的頭像 發(fā)表于 11-26 15:45 ?1007次閱讀

    linux怎樣進(jìn)入vim編輯模式

    Linux中,要進(jìn)入Vim編輯器的編輯模式,可以按照以下步驟進(jìn)行操作: 打開終端或命令行界面。 輸入以下命令來啟動(dòng)Vim編輯器: vim 文件名 其中,文件名是要編輯的文件的名稱。如
    的頭像 發(fā)表于 11-26 15:43 ?4411次閱讀

    【先楫HPM5361EVK開發(fā)板試用體驗(yàn)】Linux系統(tǒng)搭建開發(fā)環(huán)境

    選擇“Apply”,\"Debug\"??梢钥吹秸{(diào)試結(jié)果,沒有報(bào)錯(cuò),如下圖: 至此Linux開發(fā)環(huán)境搭建完畢,整個(gè)工程結(jié)束。
    發(fā)表于 11-26 11:51