搭建基於 Vim 的 C++和 Python 開發環境[持續更新]

最近 vscode 在技術圈火了一陣子,天天均可以在掘金上看到安利文章和奇葩的插件,什麼"楊超越鼓勵師",還有上班摸魚系列,"看小說插件","看股票插件",讓我愈加以爲 vscode 的功能愈來愈強大,強大到能夠作任何事情,就像操做系統,而這有沒有很像神之編輯器 emacs。最近臺灣 emacs 圈中出了一個叛徒,最後這個維護人叛逃到 vscode 陣營並將這一消息發佈到了臺灣官方 emacs 推特。html

編輯器之爭,在語言還在蓬勃發展的今天仍在持續,Vim 和 Emacs 誰是最好的編輯器,在程序員的圈子裏是一個經久不衰的話題,不論在哪一個地方都能垂手可得的引發一場聖戰。在公司裏使用的開發語言主要是 C++ 和 python,小組同事使用的開發環境也是各類各樣,有 NetBean,vscode,C++ eclipse,pycharm 以及 vim。編輯器或 IDE 始終都只是工具,工具的價值不是看它功能有多強大,有多豐富,要看它能給咱們產生多少價值,因此同個工具的價值沒辦法放在不一樣的人上去比較。個人觀點是若是你在開發過程當中會常用兩到三個語言,開發過程當中習慣的銜接很重要,我會推薦使用 vim;可是IDE是一個通過高度封裝的工具,它對開發流程,開發方式等有必定的假設,因此在不少時候特別是實際項目中,也會爲咱們節約了大量寶貴的時間。python

每種 IDE 都有本身的配置和使用習慣,數量一多,切換來切換去學習成本也很高。除了 vim,平時我也會在 windows 下使用 sublime 看看代碼,由於輕快且在 windows 下能夠快速編輯剪切複製。用過 pycharm 開發過 python,用過一段時間 eclipse 進行 C++ 開發,結合 beyond compare 方便把 windows 下代碼同步到遠程 linux 上,而後再進行 make 編譯,但最後都統一切到了 vim。linux

說說我選擇 vim 做爲主力開發環境的緣由,IDE 不少,學習成本同樣很高,使用 N 種語言就可能會有 N 種 IDE。IDE 有它本身的好處,它已經針對某種語言進行集成優化,用戶須要配置的東西其實不會不少。但其實越高度固化的東西可能越很差用,缺乏必定的靈活性。vim 插件多,支持各類語言,同時也解決了 linux 同步運行問題,著名的插件在 github 和 stackoverflow 都很活躍,一個 vim 解決全部 ide。c++

我使用的 vim 進行 python 和 C++ 進行後臺開發,最主要的功能仍是不能沒有,提示補全,定義跳轉,關鍵詞搜索,語法高亮,語法檢查,縮進摺疊,函數展現大綱,文件模板,目錄樹等等,而個人 vim 如今也能夠方便完成這些功能。git

下面開始說說 2019,我使用的 vim 插件,主要是簡單的介紹,每個我都會簡單介紹插件和使用操做,以及最重要的文檔,由於裏面有更詳細的使用信息。程序員

學習資源

在 github 上有一個不錯的 vim 學習資源,從最簡單的介紹起:github

Vim 從入門到精通github.com/wsdjeg/vim-… 笨方法學 vimscriptwww.treelib.com/book-detail…正則表達式

另外,不少 vim 插件我還在知乎上關注一些 Vimer,好比:shell

  1. 韋易笑(www.zhihu.com/people/skyw…)
  2. 趙啓明(www.zhihu.com/people/zhao…)
  3. Vim專欄(zhuanlan.zhihu.com/hack-vim)

通常都會介紹如何搭建 Vim IDE 和插件。數據庫

另外,我還喜歡在 github 上經過查找 vim 相關的插件,按照 Most Star 降序瀏覽。

個人 .vimrc 參考:github.com/cposture/my…

插件管理

插件

vim 8 已經支持異步執行功能了,而且在大多數插件中獲得了支持,異步插件管理器,好比 plug.vim,在更新插件不再用等那麼久了,再也不推薦老牌的 vundle。

vim-plug 不只支持異步更新功能,還支持針對文件類型和啓動命令的延遲加載功能,讓 vim 的啓動速度再提升不少。

文檔

  1. 安裝和使用參考:blog.jobbole.com/114132/
  2. 延遲加載插件的技術:segmentfault.com/a/119000001…
  3. vim 啓動速度慢分析:segmentfault.com/a/119000001…

配置

延遲加載插件

plug.vim 支持插件延遲加載,不至於不相關的插件一開始都啓動;plug.vim 支持按命令(command)或文件類型(file_type)這兩種配置。

" 在第一次執行 NERDTreeToggle 命令時,NERD tree 插件纔開始加載 Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } " on 支持多命令
Plug 'junegunn/vim-github-dashboard', { 'on': ['GHDashboard', 'GHActivity'] }
" 打開 clojure 類型的文件時,vim-fireplace' 纔開始加載 Plug 'tpope/vim-fireplace', { 'for': 'clojure' } " for 支持多文件類型
Plug 'kovisoft/paredit', { 'for': ['clojure', 'scheme'] }
複製代碼

使用 on 延遲加載 YouCompleteMe 方法:

  1. 先把 on 命令列表置空,默認不啓動
  2. 咱們使用自動命令,可讓Vim自動執行指定的命令,指定的命令會在指定事件發生的時候執行;進入 insert 模式時,手動調用 call plug#load('YouCompleteMe')
  3. 刪除自動命令組
# on 爲空,後面手動加載
Plug '~/YouCompleteMe', {'on': []}
augroup load_ycm
    autocmd!
    "延遲加載,在 insert 模式手動加載插件 autocmd InsertEnter * call plug#load('YouCompleteMe') | autocmd! load_ycm augroup END 複製代碼

延遲加載不是銀彈,最終要看是否是有這個需求;因此咱們通常在出現啓動比較慢的狀況下才去嘗試使用延遲加載。另外,通常插件的做者都要考慮自己延遲加載功能,而不是依靠等待外部插件去實現延遲加載。

那麼如何啓動速度慢的狀況下分析插件問題呢?

vim 啓動時能夠指定選項,vim --startuptime vim.log -c q,啓動時把計時信息寫入文件,用於分析載入 .vimrc、插件和打開首個文件的過程當中時哪一步最耗時。

times in msec
 clock self+sourced self: sourced script
 clock elapsed: other lines
...
003.691 002.008 002.008: sourcing /home/luffichen/.vim/autoload/plug.vim
021.676 000.021 000.021: sourcing /usr/local/share/vim/vim81/filetype.vim
021.869 000.017 000.017: sourcing /usr/local/share/vim/vim81/filetype.vim
...
複製代碼

其中第一列是時間點,第二列和第三列都是時長(區別:第二個是self+sourced,第三個是self),咱們主要關注第三列,腳本自己的執行時間。

由於同一個插件會有多行數據,咱們要手動把同一插件的第三列統計一個總和,這樣很繁瑣,因此 github 上有人寫了一個插件,專門用於分析每一個插件的執行耗時,並輸出直線圖,具體能夠看看:github.com/hyiltiz/vim…

還有其餘分析方法,具體可見: VIM加速:segmentfault.com/a/119000001…

簡明操做

  1. :PlugInstall,安裝已添加到 .vimrc 的插件
  2. :PlugStatus,查看安裝進度
  3. :PlugClean,刪除不在配置文件裏的插件

離線安裝插件

由於公司的 Linux 開發環境通常沒法鏈接到外網,因此不能直接使用 plug 從 github 上安裝插件,個人方法是:

以 auto-pairs 爲例,

  1. 在能夠訪問外網的環境,git clone https://github.com/jiangmiao/auto-pairs
  2. 打包壓縮 auto-pairs.zip
  3. 上傳壓縮包到服務器,並解壓,rz -byeunzip auto-pairs.zip
  4. 統一拷貝到自定義的插件目錄,我這裏都放在目錄 ~/vim-plugin 下,cp -rf auto-pairs ~/vim-plugin/
  5. 配置 .vimrc,指定插件的本地目錄,Plug '~/vim-plugin/auto-pairs'
  6. 運行 vim,並執行 :PlugInstall
  7. 查看安裝狀況,:PlugStatus

提示補全

插件

這幾個插件完美的解決了 C++ 和 python 的代碼補全和提示,其餘語言能夠參考其餘的介紹。

隨着 vscode lsp 協議的推廣,vim 語法補全也出現了相應的插件,好比 coc.nvim,主要是異步而且支持不少 vscode 上的語法補全插件,能夠試用一下(ps:公司的系統版本比較老而且網絡不通,因此一直沒去折騰這插件,後面據說出現了一個打包版本,能夠不用安裝,後面有需求能夠試用一下)。

coc.nvim 具體的介紹:zhuanlan.zhihu.com/p/39302327 coc.nvim:github.com/neoclide/co…

目前,C/C++ 的補全的話,請直接使用YouCompleteMe,沒有之一;另外 YCM-Generator 主要用於解決 YouCompleteMe 配置文件生成麻煩問題。

原本最新版本的 YCM 也支持 python 的補全,只要安裝一個 jedi 就能夠了,可是公司開發環境系統版本不是很高,編譯不了最新版本的 YCM,因此安裝一個之後端 jedi 爲補全客戶端的插件 jedi-vim

原本還想介紹一下 SuperTab(github.com/ervandew/su…),它實現的功能簡單的說就是用 tab 來調用 vim 的補全功能,這和 linux 操做習慣徹底一致,而且方便而合理,可是 YCM 自己就包含了 SuperTab 的功能,因此再也不多餘的安裝 SuperTab 插件了,以避免衝突。另外 YCM 文檔還說了包含其餘插件的功能,具體以下:

clang_complete
AutoComplPop
Supertab
neocomplcache
複製代碼

最後補充下 omnicomple,有時 YCM 和 jedi-vim 沒辦法在某些狀況下進行補全,好比我常常遇到,我只想補全我以前寫過的一個 word,這個 word 可能只是註釋裏的一個單詞,YCM 沒辦法找出它;這個時候我會使用 omnicomple 命令系列。

文檔

  1. jedi-vim 插件安裝參考文檔安裝部分:xmfbit.github.io/2018/10/02/…
  2. omnicomplete,vim 萬能補全,:help ins-completion
  3. YCM 操做詳細參考:github.com/Valloric/Yo…
  4. YCM 配置:zhuanlan.zhihu.com/p/33046090

配置

YCM

YCM 的補全須要對文件進行語法分析,因此須要依賴 .ycm_extra_conf.py 配置文件,生成 .ycm_extra_conf.py 配置文件在 google 上有詳細的介紹,咱們這裏使用 YCM-Generator 插件,能夠對 make 編譯系統生成須要的配置文件。

"=========================================
" YCM-Generator 插件配置
"=========================================
" ctrl-I 自動生成 .ycm_extra_conf.py 文件
noremap <C-I> :YcmGenerateConfig -c g++ -v -x c++ -f -b make .<CR>
複製代碼

上面的配置加到 .vimrc 後,只要在項目根目錄打開後執行快捷鍵 Ctrl - i 後就會自動在當前目錄生成配置文件

  1. ctrl + I,自動生成 .ycm_extra_conf.py 文件
  2. Ctrl + Space,在任何地方觸發完成建議,即便沒有字符串前綴也是如此。這對於查看哪些頂級函數可供使用頗有用。
  3. :YcmRestartServer,從新啓動
  4. :YcmDiags:YcmDebugInfo,查詢信息
  5. :YcmCompleter 命令,配合其餘子選項完成功能,例如,GoToDeclaration 跳轉到聲明處

omnicomple

  1. Ctrl-X Ctrl-L:整行補全
  2. Ctrl-X Ctrl-N:當前文件內關鍵字補全
  3. Ctrl-X Ctrl-i:當前文件及其頭文件內的關鍵字
  4. Ctrl-X Ctrl-]:tags補全
  5. Ctrl-X Ctrl-F:文件名補全
  6. Ctrl-X Ctrl-O:全能 (omni) 補全

有了 YCM 補全爲何須要 omni,YCM 沒辦法補全 buffer 內的字符串,這個時候就要用 Ctrl-X Ctrl-N

jedi-vim

  1. leader + d:定義跳轉,包括語句和 import 模塊
  2. leader + n:查看用法
  3. leader + r:重命名
  4. :Pyimport os:打開模塊 os
  5. Ctrl + space:補全

說明

  1. centos 系統比較老,使用 YCM 版本不是最新的,我這裏爲 github.com/Valloric/Yo… 版本爲 clang+llvm-3.3-amd64-Ubuntu-10.04.4.tar.gz

語法高亮

插件

vim-polyglot 是一個開箱即用型的語法高亮包,還有對齊功能,支持134 種語言;同時所有語言文件都是針對文件類型進行延遲加載的,不會影響到 vim 的啓動速度。

具體的支持語言能夠參考 github 上的介紹:github.com/sheerun/vim…

配置

幾乎不用加載配置,只須要 vim 打開 syntax 功能。

syntax on
複製代碼

縮進線

插件

indentLine 是一個顯示豎直對齊線的插件 ,習慣讓代碼整齊,可是插件只支持空格對齊的代碼,因此對於 tab 對齊的不會顯示對齊線;由於不一樣的編輯器對 tab 的展現不太同樣,有的展現 4 個空格,有的展現 8 個;個人習慣是讓 vim 將輸入的 tab 自動轉化爲 4 個空格,這樣的代碼在全部的編輯器的展現都是同樣的。

tab 自動轉化爲 4 個空格:

"將輸入的TAB自動展開成空格。開啓後要輸入TAB,須要Ctrl-V<TAB> set expandtab "使用每層縮進的空格數
set shiftwidth=4
"編輯時一個TAB字符佔多少個空格的位置 set tabstop=4 "方便在開啓了et後使用退格(backspace)鍵,每次退格將刪除X個空格
set softtabstop=4
" 使回格鍵(backspace)正常處理indent(縮進位置), eol(行結束符), start(段首), 很奇怪 Vim 默認居然不容許在這些地方使用 backspace set backspace=indent,eol,start "開啓時,在行首按TAB將加入 shiftwidth 個空格,不然加入 tabstop 個空格
set smarttab
複製代碼

indentLine 配置:

"打開縮進線 let g:indentLine_enabled = 1 let g:indentLine_char='¦' 複製代碼

操做

  1. :IndentLinesToggle,打開縮進線

語法高亮+縮進線圖

語法檢查

插件

ale 是一款語法檢查的插件,與syntastic相似,但有一個明顯的優點,一個是語法檢查是異步執行的,所以基本上不會出現卡頓的狀況,但它只支持Vim 8.0以上的版本。

Ale 支持多種語言的各類代碼分析器,就 C/C++ 而言,就支持:gcc, clang, cppcheck 以及 clang-format 等,須要另行安裝並放入 PATH下面,ALE能在你修改了文本後自動調用這些 linter 來分析最新代碼,而後將各類 linter 的結果進行彙總並顯示再界面上。

由於 LSP 協議支持語法檢查,因此 ALE 後面又支持 LSP,又順便支持了 LSP 語法補全功能,致使 ALE 愈來愈龐大,後面我基本只將它做爲語法檢查插件來使用。

ALE 和 clang 的工具集集合起來使用應該很不錯,https://github.com/w0rp/ale/blob/master/doc/ale-c.txt 在這裏有不少關於 clang 的配置選項,支持 compile_commands.json,免去頭文件查找問題,惋惜公司的系統版本較老。

文檔

  1. ale 官方文檔:github.com/w0rp/ale/tr…
  2. Vim插件之ale:www.cnblogs.com/awakenedy/a…

配置

ale

ale 的配置通常都要指定語言的特定 linter 和 linter 選項;我這裏只配置了 C++,C 和 python 的語法檢查,C++ 和 C 使用 cppcheck,python 使用 pylint;因此這裏須要額外安裝 cppcheckpylint 外部程序。

g:ale_linters 用於指定 linter,同時我配置了只在修改 normal 和離開 insert 時纔會進行語法檢查,避免影響速度。

let g:ale_linters = {
            \ 'cpp': ['cppcheck'],
            \ 'c': ['cppcheck'],
            \ 'python': ['pylint'],
            \}
" normal 模式下文字改變運行 linter let g:ale_lint_on_text_changed = 'normal' " 離開 insert 模式的時候運行 linter
let g:ale_lint_on_insert_leave = 1
let g:ale_c_cppcheck_options = '--enable=all'
let g:ale_cpp_cppcheck_options = '--enable=all'
複製代碼

以一小段有代碼展現 cppcheck 和 ale 的語法檢查結果:

int *ptr_list = NULL;
*ptr_list = 1;
複製代碼

最下面的狀態欄和左邊欄都會提示錯誤:Null pointer dereference,以下:

關鍵詞搜索

插件

FlyGrep 是從 SpaceVim(spacevim.org/cn/)中移植出來的實時代碼檢索工具,並且支持正則表達式,配置一個快捷鍵 Ctrl-F 後就和其餘 IDE 的搜索沒有什麼區別了。

FlyGrep 只能搜索當前目錄下的文件,因此若是想搜索整個項目,須要先切換到項目根目錄。

文檔

  1. FlyGrep 具體介紹和使用方法能夠參考官方文檔:github.com/wsdjeg/FlyG…

配置

FlyGrep

綁定快捷鍵 Ctrl-F:

"=========================================
" FlyGrep 插件配置
"=========================================
nnoremap <C-F> :FlyGrep<CR>
複製代碼

操做

FlyGrep

  1. Ctrl-F,在當前目錄下搜索關鍵詞,這裏我通常是在項目根目錄下搜索,因此先移動收到根目錄
  2. <Esc>,退出搜索
  3. <Enter>,進入選中的搜索結果
  4. <Tab>,下一個搜索結果
  5. <S-Tab>,上一個搜索結果
  6. <Home>,第一個開始結果
  7. <End>,最後一個搜索結果

vim 自帶

以搜索關鍵詞 "main" 爲例:

  1. :vim /main/ % | copen:只搜索當前文件

  2. vim /main/ * | copen:只搜索當前目錄

  3. vim /main/ ../** | copen:搜索上級目錄下,並遞歸

  4. vim /main path1/** path2/** | copen:能夠在多個路徑中搜索

說明:

  1. % 表示當前文件
  2. copen 用於打開一個窗口,存放搜索結果,方便跳轉

搜索圖

源文件頭文件切換

插件

C++ 項目常常須要在 header 和對應的 source 文件以前切換;CurtineIncSw 就提供了這樣的功能,不過它的切換是有必定的前提的:

  1. 頭文件和源文件除了後綴名和目錄不同,文件名應該是同樣的;好比 foo.c 對應 foo.h
  2. 兩個文件要麼在同級目錄,要麼將要打開的文件在已打開文件的子目錄

操做:

  1. leader-R:從頭文件和源文件互切換

跳轉

python 的跳轉,我這邊使用的是 jedi-vim 插件;C++ 的跳轉我使用 vim + ctags 工具;標籤的跳轉使用 vim-matchup。

ctags 須要本身安裝。

過去寫幾行代碼又須要運行一下 ctags 來生成索引,每次生成耗費很多時間。

現在 Vim 8 下面自動異步生成 tags 的工具備不少,這裏推薦:vim-gutentags,這個插件主要作兩件事情:

  1. 肯定文件所屬的工程目錄,即文件當前路徑向上遞歸查找是否有 .git, .svn, .project 等標誌性文件(能夠自定義)來肯定當前文檔所屬的工程目錄。
  2. 檢測同一個工程下面的文件改動,能會自動增量更新對應工程的 .tags 文件。每次改了幾行不用所有從新生成,而且這個增量更新可以保證 .tags 文件的符號排序,方便 Vim 中用二分查找快速搜索符號。

配置

vim-gutentags

" gutentags 搜索工程目錄的標誌,碰到這些文件/目錄名就中止向上一級目錄遞歸 let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project'] " 所生成的數據文件的名稱
let g:gutentags_ctags_tagfile = '.tags'

" 將自動生成的 tags 文件所有放入 ~/.cache/tags 目錄中,避免污染工程目錄 let s:vim_tags = expand('~/.cache/tags') let g:gutentags_cache_dir = s:vim_tags " 配置 ctags 的參數
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']
複製代碼

有了上面的設置,你平時基本感受不到 tags 文件的生成過程了,只要文件修改過,gutentags 都在後臺爲你默默打點是否須要更新數據文件,你根本不用管,還會幫你:setlocal tags+=...

爲當前文件添加上對應的 tags 文件的路勁而不影響其餘文件。得益於 Vim 8 的異步機制,你能夠任意隨時使用 ctags 相關功能,而且數據庫都是最新的。須要注意的是,gutentags 須要靠上面定義的 project_root 裏的標誌,判斷文件所在的工程,若是一個文件沒有託管在 .git/.svn 中,gutentags 找不到工程目錄的話,就不會爲該野文件生成 tags,這也很合理。想要避免的話,你能夠在你的野文件目錄中放一個名字爲 .root 的空白文件,主動告訴 gutentags 這裏就是工程目錄。

操做

  • 操做:
  1. ctrl+]:跳進
  2. ctrl+o:跳回
  3. %:跳轉到下一個標籤

文檔

  1. stackoverflow.com/questions/1…
  2. vim.wikia.com/wiki/Single…
  3. blog.csdn.net/gangyanlian…
  4. releases.llvm.org/3.7.0/tools…
  5. www.skywind.me/blog/archiv…

文件模版

vim模板插件 segmentfault.com/a/119000000… Vim爲特定文件載入模板 blog.csdn.net/demorngel/a…

狀態欄

插件

vim-airline 是 powerline 的替代品,而且可以和 tarbar 一塊兒工做。這兩個插件裝完,狀態欄,大綱預覽以及任務欄都齊了。

文檔

  1. vim-airline 官方文檔:github.com/vim-airline…
  2. tarbar 安裝文檔:www.wklken.me/posts/2015/…

窗口

類/方法/變量相關側邊欄

  • 操做:
  1. F9 打開
  • 插件:
  1. majutsushi/tagbar

上方 Tab 欄

  • 操做:
  1. ctrl+left,打開文件列表右邊文件
  2. ctrl+right,打開文件列表左邊文件
  3. ctrl+n,打開下一個 tab
  4. ctrl+p,打開上一個 tab

C/C++ 格式化

  1. F4,在 normal 模式,格式化文件代碼;在 visual 模式,格式化選中的代碼

摺疊

插件:github.com/tmhedberg/S… 操做:zc關閉摺疊並zo打開摺疊

縮進

操做:<<>>,==命令來縮進當前行,可視化模式選擇多行,使用=命令縮進選中的行 文檔:yyq123.blogspot.com/2010/10/vim…

複製粘貼

vim 複製到 windows

  • 安裝 x11:yum install libX11 libX11-devel libXtst-devel libXtst libXt-devel libXt libSM-devel libSM libXpm libXpm-devel
  • 下載 vim 8 源碼,編譯:
  1. ./configure --prefix=/data/luffichen/bin/vim-8.1 --with-features=huge --with-luajit --enable-luainterp=yes --enable-fail-if-missing --enable-pythoninterp=yes --with-x=yes --enable-gui=auto
  2. 查看是否支持 X11:grep X11 src/auto/config.h 若是有 #define HAVE_X11 1 #define HAVE_X11_XPM_H 1 #define HAVE_X11_SM_SMLIB_H 1 即表示依賴成功
  3. make -j4 && make install
  4. vim --version | grep clipboard 查看是否支持
  5. Run Xshell and connect to the server using the SSH protocol with X11 forwarding,具體的操做:文件-默認會話屬性-隧道-X11轉移,選擇 X Display
  6. 配置ssh,vi /etc/ssh/sshd_config 確認有配置 X11Forwrding yes,容許SSH的X轉發
  7. 安裝VcXsrv X11 Server,sourceforge.net/projects/vc… 的剪切板功能貌似對中文支持很差,因此這裏使用 VcXsrv)
  8. 打開 XLaunch,選擇 multiple windows,和 display number 爲 0,start no client,勾選 clipbord
  • 操做:
  1. visual 模式,選擇要複製的內容後執行 +y,便可 安裝luajit :blog.csdn.net/tao_627/art…
相關文章
相關標籤/搜索