インターネットのスケッチ

Done is better than perfect.

NeovimでGo言語の開発環境作ってみた

blog.craftz.dog

こういうかっこいいエディター作りたいなと思って、上の記事の設定を取り入れつつ、適当にしていたVimの設定を見直してみた(普段はVSCode使ってた)。

環境はmacなので、Windowsでは検証してない。
あと最終的な設定内容はこちらを参照。GitHub - khanamoto/dotfiles

ざっくり環境

Neovimの導入

のっけからVimでなくNeovim(以下nvim)に乗り換える。
元々Vim+NeoBundleを使ってたけど、調べてみるとVimはNeovimが、NeoBundleはdein.vimがモダンみたいなので。

  • homebrewでneovimをインストール
$ brew update
$ brew upgrade
$ brew install neovim
  • ~/.config/nvimディレクトリを作成して、その中にinit.vimファイルを作る(~/.config/nvim/init.vim)。これがVimの.vimrcに当たる。nvim起動時に読み込まれる。 まずは基本設定
"---------------------
" 文字
"---------------------
" 読み込み時の文字コード
set encoding=utf-8
" Vim Script内でマルチバイトを使う場合
scriptencoding utf-8
" 保存時の文字コード
set fileencoding=utf-8
" 読み込み時の文字コードの自動判別. 左側が優先される
set fileencodings=ucs-boms,utf-8,euc-jp,cp932
" 改行コードの自動判別. 左側が優先される
set fileformats=unix,dos,mac

"---------------------
" 行
"---------------------
" 行数表示
set number
" 折り返し
set wrap

"---------------------
" インデント(Go向け)
"---------------------
set noexpandtab
set tabstop=4
set shiftwidth=4
set autoindent

"---------------------
" 作らない系
"---------------------
"スワップファイルを作らない
set noswapfile
"バックアップファイルを作らない
set nobackup
"undoファイルを作らない
set noundofile

"---------------------
" その他
"---------------------
" クリップボードの共有
set clipboard=unnamed
" イントロダクション非表示
set shortmess+=I

dein.vimの導入

  • deinをインストールするためにinit.vimに以下を追記。
"---------------------
" dein
"---------------------
" プラグインが実際にインストールされるディレクトリ
let s:dein_dir = expand('~/.cache/dein')
" dein.vim 本体
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

" dein.vim がなければ github から落としてくる
if !isdirectory(s:dein_repo_dir)
  execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
endif
execute 'set runtimepath^=' . s:dein_repo_dir

" 設定開始
if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)

  " プラグインリストを収めた TOML ファイル
  " 予め TOML ファイルを用意しておく
  let s:toml      = s:dein_dir . '/.dein.toml'
  let s:lazy_toml = s:dein_dir . '/.dein_lazy.toml'

  " TOML を読み込み、キャッシュしておく
  call dein#load_toml(s:toml,      {'lazy': 0})
  call dein#load_toml(s:lazy_toml, {'lazy': 1})

  " 設定終了
  call dein#end()
  call dein#save_state()
endif

" もし、未インストールものものがあったらインストール
if dein#check_install()
  call dein#install()
endif
  • さらに~/.cache/dein直下に.dein.tomlファイルと.dein_lazy.tomlファイルを作りそれぞれ以下を記述(dein.tomlとdein_lazy.tomlの先頭のドットはつけなくてもOK。僕は設定系をドットファイルでまとめて管理しているのでドットファイルにしています)。

.dein.toml

[[plugins]]
repo = 'Shougo/dein.vim'

.dein_lazy.toml

[[plugins]] # TOMLのシンタックスハイライト
repo  = 'cespare/vim-toml'
on_ft = 'toml'

[[plugins]] # ステータス行を見やすく
repo = 'itchyny/lightline.vim'

追記した後、

$ nvim

とiTerm2でたたくと ~/.cache/deinのreposディレクトリ配下にdein.vimと関連プラグインがインストールされる。

作り込み

ここから冒頭の記事の設定を作り込んでいく。

  • tmuxをhomebrewで入れる。tmuxの使い方は他の方の記事を見てください。
$ brew install tmux

セッションの確認
$ tmux ls 
  • nvimの画面分割・ファイラ・エラー表示設定追加

init.vim

"---------------------
" vim側の画面分割
"---------------------
" 画面分割
nmap ss :split<Return><C-w>w
nmap sv :vsplit<Return><C-w>w
" 画面移動
nmap <Space> <C-w>w
map s<left> <C-w>h
map s<up> <C-w>k
map s<down> <C-w>j
map s<right> <C-w>l
map sh <C-w>h
map sk <C-w>k
map sj <C-w>j
map sl <C-w>l
" 画面リサイズ
nmap <C-w><left> <C-w><
nmap <C-w><right> <C-w>>
nmap <C-w><up> <C-w>+
nmap <C-w><down> <C-w>-

"---------------------
" vimfilerの設定(ファイル表示)
"---------------------
nmap sf :VimFilerBufferDir<Return>
nmap sF :VimFilerExplorer -find<Return>
nmap sb :Unite buffer<Return>
let g:vimfiler_as_default_explorer = 1
let g:vimfiler_safe_mode_by_default = 0
let g:vimfiler_enable_auto_cd = 0
let g:vimfiler_tree_leaf_icon = ''
let g:vimfiler_tree_opened_icon = '▾'
let g:vimfiler_tree_closed_icon = '▸'
let g:vimfiler_marked_file_icon = '✓'

"---------------------
" aleの設定(Lintエラー)
"---------------------
nmap <silent> <C-k> <Plug>(ale_previous_wrap)
nmap <silent> <C-j> <Plug>(ale_next_wrap)

.dein.toml

[[plugins]] # Unite.vimが依存
repo = 'Shougo/vimproc.vim'
build = 'make'

[[plugins]] # vimfilerが依存
repo   = 'Shougo/unite.vim'

[[plugins]] # VSCodeっぽいファイラ(後継としてdefx.nvimが開発中)
repo = 'Shougo/vimfiler'

.dein_lazy.toml

[[plugins]] # VSCodeっぽい非同期のエラー表示
repo = 'w0rp/ale'

詳しい使い方は冒頭の記事を参照してもらうとして、必要なプラグインについて補足。

ファイラの設定でvimfilerプラグインを入れているが、これを動かすためにvimproc.vimとunite.vimが必要(unite.vimの後継でより高速なdenite.nvimもあるが、vimfilerと組み合わせられないので、今回はunite.vimを使う)。
vimproc.vimはインストールしたあとにビルドが必要だが、.dein.tomlに以下を書いてもなぜかビルドできなかった。

build = 'make'

もしくは

hook_post_source = '''
  call dein#add('Shougo/vimproc.vim', {'build': 'make'})
'''

ビルドしないでファイラを開くと、例えば「:sf」とたたいたときこんなエラーが出る。 f:id:khanamoto:20171217193323j:plain

結局調べても原因がわからなかったので、Makefileのあるところまで移動して手動でビルドした。

$ cd ~/.cache/dein/repos/github.com/Shougo/vimproc.vim
$ make

そうすると ~/.cache/dein/repos/github.com/Shougo/vimproc.vim/lib にvimproc_mac.soが作られて、ビルドできていることが確認でき、エラーも消える。

ちなみにvimfilerの後継としてdefx.nvimというプラグインが開発中らしい。

Go周り

あとはGoの環境作り。以下追記。

.dein_lazy.toml

[[plugins]] # goコマンド補完
repo = 'fatih/vim-go'
on_ft = 'go'

[[plugins]] # vim-go代替
repo = 'zchee/nvim-go'
build = 'make'
on_ft = 'go'

[[plugins]] # コード補完
repo = 'Shougo/deoplete.nvim'
# プラグインが dein.vim によって追加されたとき実行
hook_add = 'let g:deoplete#enable_at_startup = 1'

[[plugins]] # コード補完(Golang用)
repo = 'zchee/deoplete-go'
on_ft = 'go'

コード補完はdeoplete.nvimだけでもできるが、Goでより詳しい補完をするためにdeoplete-goを入れる。deoplete-goを入れるには、以下が必要。gocodeはgo getで入れた。

Neovim and neovim/python-client
deoplete.nvim
gocode

vim-go入れたけどなぜか動かない(「エディタのコマンドではありません: GoFmt」って出る)ので、nvim-go入れた。

最終的にこんな見た目に。 f:id:khanamoto:20171217192735j:plain

おまけ

macの標準キーバインディングだとコロンとセミコロンが同じキーで、コロンを打つときにShiftをおさないといけない。しかしこれだとnvimでExコマンド打ったりするときに不便なので、コロンとセミコロンのキーバインディングを入れ替える。

詳しくはこちらを参照。 qiita.com

まとめ

開発環境は調べてみると結構大変なことが多い。ハマりどころで意外と情報がなかったり、調べても調べても解決法がわからなかったり。今回は丸2日位かかった。
それでも出来上がるとエディターをいじるのが楽しくなる。これでより気持ちよくプログラミングできようになると思う。

参考

Neovim+dein

neovim 入門1 - replicityの日記

NeoVim と dein.vim を使ってみる! - Qiita

NeoBundle から dein.vim に乗り換えたら爆速だった話 - Qiita

Vim入門(1): Vimのプラグインを管理するdein.vimの使い方 | Simplie Post

[dein.vim] hook の便利な使い方 - Qiita

初心者向け vimrcの設定方法 - Qiita

VSCodeっぽい開発環境

vim + tmuxでVSCodeっぽい開発環境を作る – 週休7日で働きたい

tmuxの使い方 - Qiita

[Vim] シンプルなファイラー「Vaffle」をつくりました | ここぽんのーと

unite.vimより高速なdenite.nvimを使う - Qiita

Vimメモ : ALE(Asynchronous Lint Engine)で非同期コードチェック - もた日記

vim流tmuxチュートリアル - Qiita

[tmux] 端末起動時に自動で新規セッションを作成 or 既存セッションにアタッチ - Qiita

Vim のカスタマイズ 〜キー割り当て変更方法〜 - Vim のブログ

Denite Compatibility · Issue #380 · Shougo/vimfiler.vim · GitHub
補足:ここで「vimfilerはdenite.vimと一緒に使えるのか?」という質問が出ているが、作者のShougoさんが、vimfilerを拡張してdenite.vimに対応させるのは難しいからvimfilerの後継としてdefx.nvimを作ってると回答している。だからvimfilerを使いたいならunite.vimを使ってくれと。

Go周り

【Go × Vim】 VimでGoを書く - 2015 Spring - Qiita

NeovimでGo言語を快適に書きたい - whileD'iary

VimでGoの開発環境を設定する方法のまとめ - Qiita

おまけ

macOS Sierraでコロンとセミコロンを入れ替える - Qiita