將 VIM 打造成 go 語言的 ide

broqiang發表於2019-03-04

前段時間太忙了,太忙太忙了,好久都沒有更新了,最近配置了下 vim , 打算用 vim 來寫 go ,將配置過程記錄下來,也希望能夠幫助到發現這個文章的你,通過配置,使得 vim 可以看起來像 ide 一樣來開發 Go 。

github 地址

說實在的,如果喜好折騰,喜好自己來配置環境,可以配置一下,如果不是很熟練 vi/vim,還是踏踏實實使用 IDE 吧,比如 VSCode(我也會用) 、 GoLand 還都是不錯的,不過你要是看到了我的這篇文件,就證明還是想要折騰一下,下面就是我折騰後的結果。

預覽

本配置是在 Ubuntu 18.04 下完成的, vim 版本是 VIM - Vi IMproved 8.0 ,開啟 lantern (不考慮網路不通暢的情況)

配置 Go 環境

既然是 Go 的開發環境,第一步當前就是準備好 。

安裝 Go

golang.org 將安裝包下載,並配置好環境, 推薦使用二進位制版本,下載完成後直接解壓縮就可以使用。如果無法訪問 go 官網,可以考慮去 golang.google.cn 去下載。

wget https://dl.google.com/go/go1.12.linux-amd64.tar.gz
sudo tar xzvf go1.12.linux-amd64.tar.gz -C /usr/local/

配置 PATH 及 GOPATH

建立 Go 的工作空間(目錄)

# 這是預設的位置,也可以按照需求指定到其他目錄
mkdir -p $HOME/go/{bin,pkg,src}

配置環境變數

使用者 vim 建立一個配置文 vim /etc/profile.d/go.sh ,寫入下面內容

export GOPATH=$HOME/go
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

Vim 基本配置

開啟 vimrc 檔案 vim ~/.vimrc ,寫入下面配置


"==============================================================================
" vim 內建配置 
"==============================================================================

" 設定 vimrc 修改儲存後立刻生效,不用在重新開啟
" 建議配置完成後將這個關閉
autocmd BufWritePost $MYVIMRC source $MYVIMRC

" 關閉相容模式
set nocompatible

set nu " 設定行號
set cursorline "突出顯示當前行
" set cursorcolumn " 突出顯示當前列
set showmatch " 顯示括號匹配

" tab 縮排
set tabstop=4 " 設定Tab長度為4空格
set shiftwidth=4 " 設定自動縮排長度為4空格
set autoindent " 繼承前一行的縮排方式,適用於多行註釋

" 定義快捷鍵的字首,即<Leader>
let mapleader=";" 

" ==== 系統剪下板複製貼上 ====
" v 模式下複製內容到系統剪下板
vmap <Leader>c "+yy
" n 模式下複製一行到系統剪下板
nmap <Leader>c "+yy
" n 模式下貼上系統剪下板的內容
nmap <Leader>v "+p

" 開啟實時搜尋
set incsearch
" 搜尋時大小寫不敏感
set ignorecase
syntax enable
syntax on                    " 開啟檔案型別偵測
filetype plugin indent on    " 啟用自動補全

" 退出插入模式指定型別的檔案自動儲存
au InsertLeave *.go,*.sh,*.php write

外掛管理

外掛的用途就是可以很方便的管理 vim 的各種外掛,快速安裝配置以及清除,網上現在的帖子多數都是使用的 Vundle 這個外掛,不過個人覺得這個管理工具在外掛安裝多了的時候不是很流暢,更喜好使用 vim-plug 這個外掛,兩個外掛都是很清除的安裝文件,這裡是介紹 vim-plug 。

安裝外掛

在 Linux 下非常簡單,直接通過 curl 下載即可(也可以手動下載,見官方文件)

curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

配置外掛

外掛的配置也非常簡單,只要將所有的外掛配置在 call plug#begin('~/.vim/plugged')call plug#end() 之間即可,常見的外掛基本上都可以從 github 中找到,如果 github 找不到的話基本上 vim.org 的指令碼都可以在 vim-script 中找到備份

在剛剛的 ~/.vimrc 下面繼續新增外掛相關的配置

" 外掛開始的位置
call plug#begin('~/.vim/plugged')

" Shorthand notation; fetches https://github.com/junegunn/vim-easy-align
" 可以快速對齊的外掛
Plug 'junegunn/vim-easy-align'

" 用來提供一個導航目錄的側邊欄
Plug 'scrooloose/nerdtree'

" 可以使 nerdtree 的 tab 更加友好些
Plug 'jistr/vim-nerdtree-tabs'

" 可以在導航目錄中看到 git 版本資訊
Plug 'Xuyuanp/nerdtree-git-plugin'

" 檢視當前程式碼檔案中的變數和函式列表的外掛,
" 可以切換和跳轉到程式碼中對應的變數和函式的位置
" 大綱式導航, Go 需要 https://github.com/jstemmer/gotags 支援
Plug 'majutsushi/tagbar'

" 自動補全括號的外掛,包括小括號,中括號,以及花括號
Plug 'jiangmiao/auto-pairs'

" Vim狀態列外掛,包括顯示行號,列號,檔案型別,檔名,以及Git狀態
Plug 'vim-airline/vim-airline'

" 有道詞典線上翻譯
Plug 'ianva/vim-youdao-translater'

" 程式碼自動完成,安裝完外掛還需要額外配置才可以使用
Plug 'Valloric/YouCompleteMe'

" 可以在文件中顯示 git 資訊
Plug 'airblade/vim-gitgutter'

" 下面兩個外掛要配合使用,可以自動生成程式碼塊
Plug 'SirVer/ultisnips'
Plug 'honza/vim-snippets'

" 可以在 vim 中使用 tab 補全
"Plug 'vim-scripts/SuperTab'

" 可以在 vim 中自動完成
"Plug 'Shougo/neocomplete.vim'

" 配色方案
" colorscheme neodark
Plug 'KeitaNakamura/neodark.vim'
" colorscheme monokai
Plug 'crusoexia/vim-monokai'
" colorscheme github 
Plug 'acarapetis/vim-colors-github'
" colorscheme one 
Plug 'rakr/vim-one'

" go 主要外掛
Plug 'fatih/vim-go', { 'tag': '*' }
" go 中的程式碼追蹤,輸入 gd 就可以自動跳轉
Plug 'dgryski/vim-godef'

" markdown 外掛
Plug 'iamcco/mathjax-support-for-mkdp'
Plug 'iamcco/markdown-preview.vim'

" 外掛結束的位置,外掛全部放在此行上面
call plug#end()

然後輸入 :w 儲存配置,在輸入 :PlugInstall ,如下:

:w
:PlugInstall

外掛會自動下載安裝,看見上面顯示 Finishing ... Done 的內容,外掛安裝成功

外掛刪除

如果想要刪除外掛,只要將不需要的外掛註釋或者刪除,執行 :PlugClean 就可以自動清理了

外掛配置

上面一起安裝了很多個外掛,有些外掛要單獨配置,記錄到下面

vim-go

這個是 go 語言支援外掛,上面外掛完成後還需要安裝很多個 Go 的包才能正常工作,在 vim 中執行下面命令:

:GoInstallBinaries

出現 vim-go: installing finished! 安裝成功,可以使用 Go 包的相關功能了

需要注意前面的 PATH 要配置正確,並且已經生效,如果配置正確沒有生效,可以登出再登入檢視

YouCompleteMe

這個外掛是用來自動完成的,不過需要手動做一些額外的配置

a. 安裝以來關係

sudo apt install build-essential cmake python3-dev

b. 編譯

cd ~/.vim/plugged/YouCompleteMe
# 編譯,並加入 go 的支援
python3 install.py --go-completer 

c. 配置和 SirVer/ultisnips 衝突的快捷鍵

let g:ycm_key_list_select_completion = ['<C-n>', '<space>']
let g:ycm_key_list_previous_completion = ['<C-p>', '<Up>']
let g:SuperTabDefaultCompletionType = '<C-n>'

" better key bindings for UltiSnipsExpandTrigger
let g:UltiSnipsExpandTrigger = "<tab>"
let g:UltiSnipsJumpForwardTrigger = "<tab>"
let g:UltiSnipsJumpBackwardTrigger = "<s-tab>"

其他外掛

其他的外掛配置不多,直接看配置檔案的註釋即可,下面將所有的配置全部貼出來

下面是全部的 ~/.vimrc 中的配置, 也可以直接下載我配置好的 vimrc 檔案


"==============================================================================
" vim 內建配置 
"==============================================================================

" 設定 vimrc 修改儲存後立刻生效,不用在重新開啟
" 建議配置完成後將這個關閉,否則配置多了之後會很卡
" autocmd BufWritePost $MYVIMRC source $MYVIMRC

" 關閉相容模式
set nocompatible

set nu " 設定行號
set cursorline "突出顯示當前行
" set cursorcolumn " 突出顯示當前列
set showmatch " 顯示括號匹配

" tab 縮排
set tabstop=4 " 設定Tab長度為4空格
set shiftwidth=4 " 設定自動縮排長度為4空格
set autoindent " 繼承前一行的縮排方式,適用於多行註釋

" 定義快捷鍵的字首,即<Leader>
let mapleader=";" 

" ==== 系統剪下板複製貼上 ====
" v 模式下複製內容到系統剪下板
vmap <Leader>c "+yy
" n 模式下複製一行到系統剪下板
nmap <Leader>c "+yy
" n 模式下貼上系統剪下板的內容
nmap <Leader>v "+p

" 開啟實時搜尋
set incsearch
" 搜尋時大小寫不敏感
set ignorecase
syntax enable
syntax on                    " 開啟檔案型別偵測
filetype plugin indent on    " 啟用自動補全

" 退出插入模式指定型別的檔案自動儲存
au InsertLeave *.go,*.sh,*.php write

"==============================================================================
" 外掛配置 
"==============================================================================

" 外掛開始的位置
call plug#begin('~/.vim/plugged')

" Shorthand notation; fetches https://github.com/junegunn/vim-easy-align
" 可以快速對齊的外掛
Plug 'junegunn/vim-easy-align'

" 用來提供一個導航目錄的側邊欄
Plug 'scrooloose/nerdtree'

" 可以使 nerdtree Tab 標籤的名稱更友好些
Plug 'jistr/vim-nerdtree-tabs'

" 可以在導航目錄中看到 git 版本資訊
Plug 'Xuyuanp/nerdtree-git-plugin'

" 檢視當前程式碼檔案中的變數和函式列表的外掛,
" 可以切換和跳轉到程式碼中對應的變數和函式的位置
" 大綱式導航, Go 需要 https://github.com/jstemmer/gotags 支援
Plug 'majutsushi/tagbar'

" 自動補全括號的外掛,包括小括號,中括號,以及花括號
Plug 'jiangmiao/auto-pairs'

" Vim狀態列外掛,包括顯示行號,列號,檔案型別,檔名,以及Git狀態
Plug 'vim-airline/vim-airline'

" 有道詞典線上翻譯
Plug 'ianva/vim-youdao-translater'

" 程式碼自動完成,安裝完外掛還需要額外配置才可以使用
Plug 'Valloric/YouCompleteMe'

" 可以在文件中顯示 git 資訊
Plug 'airblade/vim-gitgutter'

" 下面兩個外掛要配合使用,可以自動生成程式碼塊
Plug 'SirVer/ultisnips'
Plug 'honza/vim-snippets'

" 配色方案
" colorscheme neodark
Plug 'KeitaNakamura/neodark.vim'
" colorscheme monokai
Plug 'crusoexia/vim-monokai'
" colorscheme github 
Plug 'acarapetis/vim-colors-github'
" colorscheme one 
Plug 'rakr/vim-one'

" go 主要外掛
Plug 'fatih/vim-go', { 'tag': '*' }
" go 中的程式碼追蹤,輸入 gd 就可以自動跳轉
Plug 'dgryski/vim-godef'

" markdown 外掛
Plug 'iamcco/mathjax-support-for-mkdp'
Plug 'iamcco/markdown-preview.vim'

" 外掛結束的位置,外掛全部放在此行上面
call plug#end()

"==============================================================================
" 主題配色 
"==============================================================================

" 開啟24bit的顏色,開啟這個顏色會更漂亮一些
set termguicolors
" 配色方案, 可以從上面外掛安裝中的選擇一個使用 
colorscheme one " 主題
set background=dark " 主題背景 dark-深色; light-淺色

"==============================================================================
" vim-go 外掛
"==============================================================================
let g:go_fmt_command = "goimports" " 格式化將預設的 gofmt 替換
let g:go_autodetect_gopath = 1
let g:go_list_type = "quickfix"

let g:go_version_warning = 1
let g:go_highlight_types = 1
let g:go_highlight_fields = 1
let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_operators = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_methods = 1
let g:go_highlight_generate_tags = 1

let g:godef_split=2

"==============================================================================
" NERDTree 外掛
"==============================================================================

" 開啟和關閉NERDTree快捷鍵
map <F10> :NERDTreeToggle<CR>
" 顯示行號
let NERDTreeShowLineNumbers=1
" 開啟檔案時是否顯示目錄
let NERDTreeAutoCenter=1
" 是否顯示隱藏檔案
let NERDTreeShowHidden=0
" 設定寬度
" let NERDTreeWinSize=31
" 忽略一下檔案的顯示
let NERDTreeIgnore=['\.pyc','\~$','\.swp']
" 開啟 vim 檔案及顯示書籤列表
let NERDTreeShowBookmarks=2

" 在終端啟動vim時,共享NERDTree
let g:nerdtree_tabs_open_on_console_startup=1

"==============================================================================
"  majutsushi/tagbar 外掛
"==============================================================================

" majutsushi/tagbar 外掛開啟關閉快捷鍵
nmap <F9> :TagbarToggle<CR>

let g:tagbar_type_go = {
    \ 'ctagstype' : 'go',
    \ 'kinds'     : [
        \ 'p:package',
        \ 'i:imports:1',
        \ 'c:constants',
        \ 'v:variables',
        \ 't:types',
        \ 'n:interfaces',
        \ 'w:fields',
        \ 'e:embedded',
        \ 'm:methods',
        \ 'r:constructor',
        \ 'f:functions'
    \ ],
    \ 'sro' : '.',
    \ 'kind2scope' : {
        \ 't' : 'ctype',
        \ 'n' : 'ntype'
    \ },
    \ 'scope2kind' : {
        \ 'ctype' : 't',
        \ 'ntype' : 'n'
    \ },
    \ 'ctagsbin'  : 'gotags',
    \ 'ctagsargs' : '-sort -silent'
\ }

"==============================================================================
"  nerdtree-git-plugin 外掛
"==============================================================================
let g:NERDTreeIndicatorMapCustom = {
    \ "Modified"  : "✹",
    \ "Staged"    : "✚",
    \ "Untracked" : "✭",
    \ "Renamed"   : "➜",
    \ "Unmerged"  : "═",
    \ "Deleted"   : "✖",
    \ "Dirty"     : "✗",
    \ "Clean"     : "✔︎",
    \ 'Ignored'   : '☒',
    \ "Unknown"   : "?"
    \ }

let g:NERDTreeShowIgnoredStatus = 1

"==============================================================================
"  Valloric/YouCompleteMe 外掛
"==============================================================================

" make YCM compatible with UltiSnips (using supertab)
let g:ycm_key_list_select_completion = ['<C-n>', '<space>']
let g:ycm_key_list_previous_completion = ['<C-p>', '<Up>']
let g:SuperTabDefaultCompletionType = '<C-n>'

" better key bindings for UltiSnipsExpandTrigger
let g:UltiSnipsExpandTrigger = "<tab>"
let g:UltiSnipsJumpForwardTrigger = "<tab>"
let g:UltiSnipsJumpBackwardTrigger = "<s-tab>"

"==============================================================================
"  其他外掛配置
"==============================================================================

" markdwon 的快捷鍵
map <silent> <F5> <Plug>MarkdownPreview
map <silent> <F6> <Plug>StopMarkdownPreview

" tab 標籤頁切換快捷鍵
:nn <Leader>1 1gt
:nn <Leader>2 2gt
:nn <Leader>3 3gt
:nn <Leader>4 4gt
:nn <Leader>5 5gt
:nn <Leader>6 6gt
:nn <Leader>7 7gt
:nn <Leader>8 8gt
:nn <Leader>9 8gt
:nn <Leader>0 :tablast<CR>

"==============================================================================
" GVim 的配置
"==============================================================================
" 如果不使用 GVim ,可以不用配置下面的配置
if has('gui_running')
        colorscheme one
    " 設定啟動時視窗的大小
    set lines=999 columns=999 linespace=4

    " 設定字型及大小
        set guifont=Roboto\ Mono\ 13

    set guioptions-=m " 隱藏選單欄
    set guioptions-=T " 隱藏工具欄
    set guioptions-=L " 隱藏左側滾動條
    set guioptions-=r " 隱藏右側滾動條
    set guioptions-=b " 隱藏底部滾動條
            " 在 gvim 下不會和 terminal 的 alt+數字的快捷鍵衝突,
    " 所以將 tab 切換配置一份 alt+數字的快捷鍵
    :nn <M-1> 1gt
    :nn <M-2> 2gt
    :nn <M-3> 3gt
    :nn <M-4> 4gt
    :nn <M-5> 5gt
    :nn <M-6> 6gt
    :nn <M-7> 7gt
    :nn <M-8> 8gt
        :nn <M-9> 9gt
        :nn <M-0> :tablast<CR>
endif

相關文章