這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
雖說sublimetext3+gosublime+gocode是目前較為 流行的Golang開發環境組合,但作為一名VIMer,沒有一套得心應手的Vim for Golang dev心裡總是過不去的。Golang雖然年輕,但即便是從Go 1版本發布(2012年3月28日)算起,掐指算來也有小三年了。全世界的開發人員已經為Golang貢獻了較為成熟的Vim外掛程式了。有了這些外掛程式,搭建出 一套高效的Golang開發環境還是不難的,網上也有大量的資料可以參考,其中就有vim-go作者自己發表的一篇文章《Go development environment for Vim》。不過看別人 寫的與自己搭建體驗的還是有大不同的,於是想來想去還是把整個過程記錄下來。
一、一個乾淨的環境
找個乾淨的基礎環境,方便確認每個搭建步驟後的效果:
Ubuntu 14.04 x86_64
vim version 7.4.52
go version go1.4beta1 linux/amd64
再準備一個編輯Go源碼的測試源檔案:
//hellogolang.go
package main
import "fmt"
func main() {
fmt.Println("Hello Golang!")
}
用於驗證每個搭建步驟後的變化。
二、嚴格按照vim-go的官方說明逐一搭建
Vim-go是當前使用最為廣泛的用於搭建Golang開發環境的vim外掛程式,這裡我同樣使用vim-go作為核心和基礎進行環境搭建的。vim-go利 用開源Vim外掛程式管理器安裝,gmarik/Vundle.vim是目前被推薦次數更多的Vim外掛程式管理器,超過了pathogen。這裡我們 就用vundle來作為Vim的外掛程式管理工具。
1、安裝Vundle.vim
Vundle.vim的安裝步驟如下:
mkdir ~/.vim/bundle
git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
建立~/.vimrc檔案(如果你沒有這個檔案的話),在檔案頂部添加有關Vundle.vim的配置:
set nocompatible " be iMproved, required
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
此時Vim僅安裝了Vundle.vim這一個外掛程式。編輯hellogolang.go時與編輯普通文字檔無異,一切都還是Vim的預設屬性。
2、安裝Vim-go
編輯~/.vimrc,在vundle#begin和vundle#end間增加一行:
Plugin 'fatih/vim-go'
在Vim內執行 luginInstall,
Vundle.vim會在左側開啟一個Vundle Installer Preview子視窗,視窗下方會提示:“Processing 'fatih/vim-go'”,待安裝完畢後,提示資訊變 成“Done!”。
這時,我們可以看到.vim/bundle下多了一個vim-go檔案夾:
$ ls .vim/bundle/
vim-go/ Vundle.vim/
此時,再次編輯hellogolang.go,文法高亮有了, 儲存時自動format(利用$GOBIN/gofmt)也有了,但其他進階功能,比如自動import缺失的 package、自動補齊仍然沒有,我們還要繼續安裝一些東東。
3、安裝go.tools Binaries
vim-go安裝說明中提到所有必要的binary需要先安裝好,比如gocode、godef、goimports等。
通過:GoInstallBinaries,這些vim-go依賴的二進位工具將會自動被下載,並被安裝到$GOBIN下或$GOPATH/bin下。(這個工具需要依賴git或hg,需要提前安裝到你的OS中。)
:GoInstallBinaries的執行是互動,你需要斷行符號確認:
vim-go: gocode not found. Installing github.com/nsf/gocode to folder /home/tonybai/go/bin
vim-go: goimports not found. Installing code.google.com/p/go.tools/cmd/goimports to folder /home/tonybai/go/bin/
vim-go: godef not found. Installing code.google.com/p/rog-go/exp/cmd/godef to folder /home/tonybai/go/bin/
vim-go: oracle not found. Installing code.google.com/p/go.tools/cmd/oracle to folder /home/tonybai/go/bin/
vim-go: gorename not found. Installing code.google.com/p/go.tools/cmd/gorename to folder /home/tonybai/go/bin/
vim-go: golint not found. Installing github.com/golang/lint/golint to folder /home/tonybai/go/bin/
vim-go: errcheck not found. Installing github.com/kisielk/errcheck to folder /home/tonybai/go/bin/
不過這些代碼多在code.google.com上託管,因此由於眾所周知的原因,vim-go的自動安裝很可能以失敗告終,這樣就需要你根據上 面日誌中提到的各個工具的源碼地址逐一去下載並本地安裝。無法搭梯子的,可以通過http://gopm.io 下載相關包。
安裝後,$GOBIN下的新增Binaries如下:
-rwxr-xr-x 1 tonybai tonybai 5735552 11?? 7 11:03 errcheck*
-rwxr-xr-x 1 tonybai tonybai 9951008 11?? 7 10:33 gocode*
-rwxr-xr-x 1 tonybai tonybai 5742800 11?? 7 11:07 godef*
-rwxr-xr-x 1 tonybai tonybai 4994120 11?? 7 11:00 goimports*
-rwxr-xr-x 1 tonybai tonybai 5750152 11?? 7 11:03 golint*
-rwxr-xr-x 1 tonybai tonybai 6381832 11?? 7 11:01 gorename*
-rwxr-xr-x 1 tonybai tonybai 2954392 11?? 7 10:38 gotags*
-rwxr-xr-x 1 tonybai tonybai 9222856 11?? 7 11:01 oracle*
安裝好這些Binaries後,我們來看看哪些特性被支援了。
再次編輯hellogolang.go:
- 新起一行輸入fmt.,然後ctrl+x, ctrl+o,Vim 會彈出補齊提示下拉框,不過並非即時跟隨的那種補齊,這個補齊是由gocode提供的。
– 輸入一行代碼:time.Sleep(time.Second),執行:GoImports,Vim會自動匯入time包。
– 將游標移到Sleep函數上,執行:GoDef或命令模式下敲入gd,Vim會開啟$GOROOT/src/time/sleep.go中 的Sleep函數的定義。執行:b 1返回到hellogolang.go。
– 執行:GoLint,運行golint在當前Go源檔案上。
– 執行:GoDoc,開啟當前游標對應符號的Go文檔。
– 執行:GoVet,在目前的目錄下運行go vet在當前Go源檔案上。
– 執行:GoRun,編譯運行當前main package。
– 執行:GoBuild,編譯當前包,這取決於你的源檔案,GoBuild不產生結果檔案。
– 執行:GoInstall,安裝當前包。
– 執行:GoTest,測試你當前路徑下地_test.go檔案。
– 執行:GoCoverage,建立一個測試覆蓋結果檔案,並開啟瀏覽器展示當前包的情況。
– 執行:GoErrCheck,檢查當前包種可能的未捕獲的errors。
– 執行:GoFiles,顯示當前包對應的源檔案清單。
– 執行:GoDeps,顯示當前包的依賴包列表。
– 執行:GoImplements,顯示當前類型實現的interface列表。
– 執行:GoRename [to],將當前游標下的符號替換為[to]。
三、其他外掛程式
到目前為止,我們還有若干特性沒能實現,重點是:
– 即時跟隨的代碼補齊
– Code Snippet support
1、安裝YCM(Your Complete Me)
在~/.vimrc中添加一行:
Plugin 'Valloric/YouCompleteMe'
儲存退出後,再開啟~/.vimrc並執行 luginInstall。
安裝完後,下面的提示欄提示:
ycm_client_support.[so|pyd|dll] and ycm_core.[so|pyd|dll] not detected; you need to compile YCM before using it. Read the docs!
似乎YCM是用了C++編寫的模組對效能進行最佳化了,於是需要手工編譯YCM的support庫。步驟如下:
sudo apt-get install build-essential cmake python-dev
cd ~/.vim/bundle/YouCompleteMe
./install.sh
構建(編譯C++很慢,需要耐心的等一會)ok後,再開啟hellogolang.go,逐字的即時補全功能就具備了!Cool!
2、安裝 UltiSnips
Vim-go預設是用ultisnips引擎外掛程式,但這個外掛程式需要單獨安裝。
同樣,我們利用vundle來安裝它,在~/.vimrc中添加一行:
Plugin 'SirVer/ultisnips'
snippet和snippet引擎是分開的。ultisnips是引擎,vim-go的go snippet定義在這裡
https://github.com/fatih/vim-go/blob/master/gosnippets/snippets/go.snip
編輯hellogolang.go,按照go.snip中的說明,我們輸入func後敲擊tab鍵,我們發現期待的:
func name(params) type {
}
並沒有出現。反倒是YCM的下拉提示顯示在那裡讓你選擇。似乎是ultisnips和YCM的鍵組合衝突了。ultisnips官方說明也的確如 此。ultisnips預設是用Tab展開snippet的,而YCM中的Tab用來選擇補齊項,我們可以通過設定來避免這些。
我們在.vimrc中添加如下setting:
" YCM settings
let g:ycm_key_list_select_completion = ['', '']
let g:ycm_key_list_previous_completion = ['']
let g:ycm_key_invoke_completion = ''
" UltiSnips setting
let g:UltiSnipsExpandTrigger=""
let g:UltiSnipsJumpForwardTrigger=""
let g:UltiSnipsJumpBackwardTrigger=""
這樣讓YCM通過斷行符號和向下的箭頭來做list item正向選擇,通過向上箭頭做反向選擇。通過ctrl+space來原地觸發補齊提示。
而ultisnips則是用tab做snippet展開,ctrl+b正向切換預留位置,ctrl+z反向切換預留位置。
3、安裝molokai theme
Molokai theme是TextMate的theme的vim port,看著挺不錯的,於是也安裝了一下。
mkdir ~/.vim/colors
下載或copy https://github.com /fatih/molokai/blob/master/colors/molokai.vim到~/.vim /colors目錄下
在.vimrc添加一行:colorscheme molokai
四、.vimrc
前面講到了vim-go有許多命令,在:xx模式下執行多顯不便,於是你可以定義一些Mappings,比如:
" set mapleader
let mapleader = ","
" vim-go custom mappings
au FileType go nmap s (go-implements)
au FileType go nmap i (go-info)
au FileType go nmap gd (go-doc)
au FileType go nmap gv (go-doc-vertical)
au FileType go nmap r (go-run)
au FileType go nmap b (go-build)
au FileType go nmap t (go-test)
au FileType go nmap c (go-coverage)
au FileType go nmap ds (go-def-split)
au FileType go nmap dv (go-def-vertical)
au FileType go nmap dt (go-def-tab)
au FileType go nmap e (go-rename)
這樣我們在命令模式下,輸入<,>+就是運行 當前main包,以此類推。
另外下面這個配置使得我們在save file時既可以格式化代碼,又可以自動插入包匯入語句(或刪除不用的包匯入語句)。
" vim-go settings
let g:go_fmt_command = "goimports"
到這裡,我們的Vim Golang開發環境就基本搭建好了。snippet+即時補齊讓你Coding如飛!
五、附錄:.vimrc檔案
下面是截至目前為止全量.vimrc檔案的內容:
set nocompatible " be iMproved, required
filetype off " required
colorscheme molokai
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
Plugin 'fatih/vim-go'
Plugin 'Valloric/YouCompleteMe'
Plugin 'SirVer/ultisnips'
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
" set mapleader
let mapleader = ","
" vim-go custom mappings
au FileType go nmap s (go-implements)
au FileType go nmap i (go-info)
au FileType go nmap gd (go-doc)
au FileType go nmap gv (go-doc-vertical)
au FileType go nmap r (go-run)
au FileType go nmap b (go-build)
au FileType go nmap t (go-test)
au FileType go nmap c (go-coverage)
au FileType go nmap ds (go-def-split)
au FileType go nmap dv (go-def-vertical)
au FileType go nmap dt (go-def-tab)
au FileType go nmap e (go-rename)
" vim-go settings
let g:go_fmt_command = "goimports"
" YCM settings
let g:ycm_key_list_select_completion = ['', '']
let g:ycm_key_list_previous_completion = ['', '']
let g:ycm_key_invoke_completion = ''
" UltiSnips settings
let g:UltiSnipsExpandTrigger=""
let g:UltiSnipsJumpForwardTrigger=""
let g:UltiSnipsJumpBackwardTrigger=""
2014, bigwhite. 著作權.