gina.vimとGitHubの連携を向上させる
September 15, 2020
久しぶりに書きます. 最近研究に忙殺されていて、あんまり技術書やら本が読めてなくて、ブログも書く時間がないです。 今日はgina.vimで便利な設定ができたのでブログにまとめていきたいと思います.
ところでGina.vimとは?
gina.vimはVim上で使うGitの便利なプラグインになります。 作者はlamdalisueaさんという方で、この他にもfern.vimやsuda.vim等、様々なVimのプラグインを作ってらっしゃります。
gina.vimはその中でも、Gitの操作をVim上で行うためのプラグインで以下のようなメソッドが使えます。
- Gina status
- Gina commit
- Gina blame
- Gina browse …
詳しくはgina.vimのdocを見てください。 このブログでは多機能なgina.vimの中でもGitHubとの連携に絞ったことについて書いていきたいと思います。
Gina browseの基本機能について
Gina browseはOSのデフォルトブラウザで該当のリンクを開いてくれる機能になります。 これだけ聞くと、それならhub browseで十分じゃないかと思われるかもしれません。 しかし、ただこれだけではなく色々な応用を効かせることができます。
例えば、:Gina browse :
と入力すると現在のファイルの場所を選択した状態でURLを開いてくれます。
また行単位のビジュアルモードで行を複数選択し、その状態で:Gina browse :
を入力するとその行を選択した状態でリンクを開いてくれます。
Gina browse —exact
Gina browse --exact
はbranchではなくcommitのハッシュ値をもとにリンクを開いてくれます。
例えば、issueやPRで参照したいコードがある場合は参照したい場所を行単位のビジュアルモードで選択し、:Gina browse --exact :
を入力します。
すると、先ほどと同じようなページが表示されますが、URLが絶妙に変わっていることに気が付くと思います。
これは先ほどとは違ってbranchではなく、commitのハッシュ値からページを開いてくれるためです。
そのページのURLをissueなどのコメントに貼ると以下の用に表示することが出来ます。
また、わざわざブラウザを開かなくても、:Gina browse --exact --yank :
と入力することで、ブラウザを開くことなくヤンクしてくれるので、clipboardの設定をしているならこのコマンドでも十分でしょう。
--exact
を使用するには、現在のcommitをリモートのリポジトリにプッシュしている必要があります。
Gina browse --scheme
Gina browse
には --scheme
というオプションが用意されています。
用意されているオプションは_
, root
, blame
, compare
の4種類です。
僕は全てを理解しているわけではないですが、例えば:Gina browse --scheme=blame :
と入力すると以下のようなblame
ページが表示されます。
Gina blameとの連携
もちろん上の--scheme=blame
オプションをつけなくても、Gina blame
というコマンドがあり、各行についてどのコミットで追加されたものかというのが分かりやすくなってます。
gina#command#blame#formatter#format
を変更することによって自分なりに表示するものを変えることができます。
詳しくは:help gina#command#blame#formatter#format
を入力してください。
これでこんなひどいコードを書いたのは誰だ!と糾弾するのに役立ちます。(大体こう思うときの犯人は自分ですが..) しかし、こういうひどいコードを書いてるときはcommitメッセージも適当になってしまいがちです。 自分の場合は、「fix」とか使いがちですね。。
こういう意図が分かりにくいコードやcommitメッセージでは、プルリクを見る以外に有効な手段がありません。 そこでこのblame画面から直接該当のプルリクを見に行くことができれば便利だと考て作成しました。
このコマンドは依存ツールとして、hubが必要になるので、あらかじめインストールしておいてください。
まずはcommitハッシュ値からブラウザで該当プルリクを開くAliasを作成します。 このAliasについてはCommit Hash から、該当 Pull Request を見つける方法という記事を参考にしました。 まずは準備としてコマンドラインに以下のようなコマンドを打ち込みます。
$ git config --global alias.openpr \!"f() { hub browse -- \`git log --merges --oneline --reverse --ancestry-path \$1...master | grep 'Merge pull request #' | head -n 1 | cut -f5 -d' ' | sed -e 's%#%pull/%'\`; }; f"
これで、
$ git openpr [ハッシュ値]
と打ち込むことで該当PRを開くことができます。
詳しくは元の記事を読んでください。
次に:Gina blame
を開いているときに、カーソル下の行のcommitハッシュ値を取得し、上のコマンドに渡すことができればOKです。
以下のコマンドを.vimrc
等に入力すると出来上がりです。
function! GinaOpenPR() abort
redir => s:messages
call gina#action#call('blame:echo')
redir END
let s:lastmsg = get(split(s:messages, "\n"), -1, "")
let s:commit_hash = matchstr(s:lastmsg, '\[.*\]$')
if strlen(s:commit_hash) < 2
return
endif
let s:commit_hash = s:commit_hash[1:strlen(s:commit_hash)-2]
call system(printf("git openpr %s", s:commit_hash))
endfunction
command! GinaOpenPR call GinaOpenPR()
あとは、:Gina blame
を打った後に気になる行にカーソルを移動し、おもむろに:GinaOpenPR
を入力すると該当のPRを開くことができます。
これで終わるのも微妙なのでコードについて、説明します。
まず最初のこの部分はgina.vimのactionであるblame:echoを読んでいます。(詳しくは:h gina-actions-blame
)
そして、次のget(...)
ではechoされたメッセージで最新のものを取得しています
本当はカーソルの下commitハッシュ値を取得したかったのですが、gina.vimのAPIを探しても見つからないためこのような荒療治を行いました。
redir => s:messages
call gina#action#call('blame:echo')
redir END
let s:lastmsg = get(split(s:messages, "\n"), -1, "")
続いての以下のコードでは、blame:echo
の内容からcommitを抜き出してきています。
もしcommitが取得できない場合はreturnしています。
let s:commit_hash = matchstr(s:lastmsg, '\[.*\]$')
if strlen(s:commit_hash) < 2
return
endif
let s:commit_hash = s:commit_hash[1:strlen(s:commit_hash)-2]
最後のこの部分ではgit openpr
で先ほど取得したcommitの紐づいたPRを開くようにしているという感じです。
call system(printf("git openpr %s", s:commit_hash))
これでblameを使い、そのあと該当のPRを開くことが出来ます! これで意味不明なコードが入っていたとしても安心ですね!
まとめ
GinaとGitHub間の連携をうまく行うことが出来るメソッドを紹介したり、作成したりしていきました。
最後の:GinaOpenPR
は、わざわざblame:echo
をしていたり、Gina browse
ではなく外部コマンドであるhub
を使っていたりと自分的には不満な点がいくつかありますが、普通に使いやすくなったのではないでしょうか?
これで必要なコマンドをそろえてPRを出したい! と思ったりもしましたが、この方法だと
- squashマージの場合にうまくいかない
- GitHub以外で上手くいくかわからない
- masterに直接マージをしていたら無意味になる
等々、どうすればいいか分からない点がいろいろあったのでブログを書くにとどまっておきました。 もし、便利だなと思ったらぜひ使ってください。