はじめに
Vimといえば、みなさんご存じテキストエディタですが、テキストエディタである以前に一つのCLIコマンドでもあります。そんなCLIコマンドの利点一つにThe UNIX philosophyの定理として提唱されている『7. Use shell scripts to increase leverage and portability. (シェルスクリプトによって梃子(てこ)の効果と移植性を高める)』というものがあります。
今回は私も普段の仕事で利用しているVimの梃子としての側面をご紹介できればと思います。
GitコマンドとVim
今回Vimと組み合わせるのはシステム開発で避けては通れぬバージョン管理システムGitです。私は普段Gitを使用するときにはSourcetreeやGitKrakenなどのGUIクライアントを利用せずにCLIで操作をしています。
皆さんこう思われるかもしれません。「またCLI狂信者か。あんな簡素なインタフェースで、Gitなんて複雑なものを素早く操作できる訳無いだろう。おとなしくGUIクライアントを使えばいいじゃないか。」
ちょっとまってください。私もなにも素のGitコマンドだけですべてを操作することが効率が良いという気はないのです。CLIコマンドだからこそ簡単に他のツールと連携できることこそが魅力だと言いたいのです。
コミットメッセージをVimで入力する
まずは基本のキ、コミットメッセージの入力です。Git管理ファイルを変更し、差分をaddしてstagedにします。そしたらさあコミットの時間です。
皆さんは普段GitのCLIコマンドでコミットするときにどうされるでしょうか?私はそのまま単純にgit commit
と入力します。オプションなしで実行するとそのままデフォルトのエディタ(環境変数$EDITORに設定されたコマンド)でGitのメッセージ入力用の一時ファイルを開き、ファイルを閉じたときにファイル入力内容を読み取ってコミットします。
補足すると、このとき最優先で開くエディタは.gitconfig
ファイルに設定されているコマンドなので、明示的に指定したいときは以下のコマンドで指定すると良いでしょう。
git config --global core.editor ${editor}
ここからが面白いところです。素のVimを立ち上げただけだとそれなりに便利ではありますが少し物足りません。そこでいくつかの機能を追加してあげましょう。まずスペルチェックをGitのメッセージ編集時のみ有効にしてあげましょう。
augroup GitSpellCheck
autocmd!
autocmd FileType gitcommit setlocal spell
augroup END
スペルチェックだけだと、タイポはわかっても正しいスペルがわからないってときもありますよね。そんなときは辞書を引けばいいのです。deoplete.nvimとneco-lookを導入すれば、英単語が自動補完されるので、つまらないタイポとはオサラバです。
Plug 'Shougo/deoplete.nvim'
Plug 'ujihisa/neco-look'
let g:deoplete#enable_at_startup = 1
call deoplete#custom#option('sources', {
\ 'gitcommit': ['look'],
\})
更にcommittia.vimというプラグインを導入することで、変更したファイル内容などのコミットに付属する各種情報を一目で確認することができます。Vimでコミットメッセージをいじるなら是非入れたいプラグインです。
Plug 'rhysd/committia.vim'
function! g:committia_hooks.edit_open(info)
" Additional settings
setlocal spell
setlocal spelllang+=cjk
" If no commit message, start with insert mode
if a:info.vcs ==# 'git' && getline(1) ==# ''
startinsert
end
" Scroll the diff window from insert mode
" Map <C-n> and <C-p>
imap <buffer><C-n> <Plug>(committia-scroll-diff-down-half)
imap <buffer><C-p> <Plug>(committia-scroll-diff-up-half)
endfunction
いかがでしょうか?Gitのコミット時に英単語のスペルチェックと自動補完と各種差分情報を見れてVimキーバインドでテキスト編集できる環境というのはなかなかないと思います。コミットメッセージを書くというVimが最も得意な行為をVimに任せる。それだけでGitコマンド単体と比べ格段に便利になるのです。
Gitの差分をVimで見る
Gitで差分の確認もよくやる作業です。Gitコマンドで差分を見るなら以下のような流れですね。
# 差分を確認するハッシュをログから確認
git log
# 該当のハッシュの差分を見る
git diff ${hash}
上記を実行すると、だいたいの環境ではless
コマンドなどのページャが起動してスクロールすると思います。少量ならばこれでもいいですが、多量のdiffを確認するには心もとありません。そこで登場するのがVimです。皆さんVimのことをただのエディタだと思ってますよね?実はVimは差分比較ツールとしても優秀なのです。もし使ったことがないのならば一度でいいからdiffのかわりにvimdiffを使ってみて欲しいです。
Gitは先程のコミットメッセージのように、差分についても別コマンドに連携することができるのです。例えばWindowsで有名な差分ツールのWinMergeでGitの差分を表示したり。なんてこともできます。
このような外部ツールをGitコマンドから起動するときはdiff
ではなくdifftool
を利用するのですが、このとき起動する外部ツールをeditorの変更をしたとき同様に設定で変更できます。
git config --global diff.tool vimdiff
設定を変更したらあとはコマンドを実行するだけです。
git difftool ${hash}
いかがでしょうか。とても見やすくなったのではないでしょうか?
差分以外の部分は折り畳まれてたりと、いい感じに気を利かせてくれていますね。
なお上記のGIF動画ではファイルごとに確認のプロンプトが表示されていますが、こちらについては設定で有無を選択できます。
git config --global difftool.prompt false
さて差分を確認できるとなると、少し欲が出てきますね。この見やすい差分の画面で、コンフリクト解消ができたらとっても便利なのに。そう思いませんか?
できます!!!!以下の記事に自分が以前参考にした内容が記載されているので見てみてください。
またvimdiffというのは本家Vim側が用意しているコマンドであって、NeoVimのコマンドではありません。そのため、NeoVimで同じことをやろうとするとまた別の設定が必要になります。こちらについては以下の参照ください。
さてここまでくるとだいぶGitとVimの組み合わせのパワーを感じてきたのではないでしょうか?
TigとVim組み合わせてインタラクティブにGit操作しよう
最後に組み合わせの要素をもう一つ追加します。それがTigです。俗に言うインタラクティブなGitコマンドです。
類似のコマンドにGolang製のLazyGitやRust製のGitUIなんかがあります。これらのほうがパフォーマンス面で優れていたりしているのですが、コマンドを形作る思想やカスタマイズ性が自分にマッチしすぎていて、tigを手放す気にはなりません。
tig単体でもかなり強力なツールなのですが、tigとVimを組み合わせることでもっと強力になります。
今回基本的な使い方については解説しないのでマニュアルをご参照ください。
Tigでみた差分からVimを開く
私が多様するのがこれで、TigのDiff View
からe
を押すことで、カーソル位置のファイルをgit editor
で開くというものです。シンプルが故にいくらでも応用が効きます。開いた後は普通にエディタとして操作が可能です。私はこれをプロジェクト編集の起点にしたりします。
Tigで差分を見てからrebaseしよう
皆さんチームメンバーに「このコミットとこのコミット粒度が小さすぎるからsquash
しておいて、git rebase -i
でできるから。」と言われて、ナンノコッチャと調べて悪銭苦闘し、一時間ぐらいかけて2つのコミットをsquash
したことはありませんか?私はあります。
git log
で該当のハッシュと差分を調べつつ、恐る恐るgit rebase -i
を実行する。そして次回やる頃にはどうやるかを忘れている。そしてrebaseなんかもう二度とやらないと思う。そんなことありませんか?私はあります。
そんな私はTigとたった一行の.tigrc
(Tigの設定ファイル)でこの悩みから開放されました。それがこの$HOME/.tigrc
です。
bind main R !git rebase -i %(commit)
やってることは単純でTigのmain view
閲覧時のR
でカーソル配下のcommitを起点にrebase -i
を実行するだけです。
なお豆知識なんですが、このrebase -i
で起動したファイル上だとcommit hash
をカーソル下においてK
を押すとdiffが見れます。これはVimにビルドインされているプラグインの機能です。
Tigの差分をVimで見る
自分で紹介しといてなんですがGitの差分をVimで見る
を更に便利にしたものをご紹介しましょう。.tigrc
に以下を追加することで、その機能を利用できます。なおgit difftool
の設定ができていることを前提とします。
bind main D !sh -c "git difftool %(commit)~ %(commit)"
これはTigでカーソル配下のcommitとその前のcommitの差分をvimdiffで表示できます。Gitコマンドでやっていたことをインタラクティブにできるようにしたと考えれば良いでしょう。
これはmain view
だけではなくref view
(ブランチの一覧)でも使えるため、ブランチの差分なんかを確認するのにも使えます。
bind refs D !sh -c "git difftool %(branch)"
最後に
Vimというコマンドの中だけでも面白いですが、Vimとて一つのCLIコマンドです。その特色を活かして、他のコマンドからVimへ、Vimから他のコマンドへの組み合わせることで、相乗効果が生まれるということが少しでもわかっていただけたなら幸いです。
もし皆さんのオススメの組み合わせなどあれば、ぜひ私に教えてください。