git-gutter.elの紹介

拙作の git-gutter.elを紹介します. 作り始めたのは 2年前ぐらいでしたが, 今年当初から問題となっていた高速化の課題など取り組んだので改めて紹介しようと思います.


## リポジトリ
https://github.com/syohex/emacs-git-gutter


## 今年行った改良点
- hook-pointでの処理を同期的に行っていたものを非同期に変更
- 不要な更新を極力行わないように修正
- Git以外の対応(Mercurial, Bazzar)

大きな変更は軽量化です. 重いということがいろいろ問題視されていて, [git-gutter-plus](https://github.com/nonsequitur/git-gutter-plus)という fork版ができたりしていました. 自分でもそのあたりを認識していたんですが, よくわからないし, 我慢すれば使えるということで放置していました. しかし今年はスキルも高まってきたし, そろそろできるだろということで取り組んでなんとか対応出来ました. Linux Kernelソースで使うこともありますが, 不満を感じることは今のところないです. 1年前とか 2年前に使って, 重いから使えないと感じた人はぜひ新しい版を試して欲しいと思います.


## インストール
MELPA, MELPA-stable, marmaladeからインストールすることができます.
`package.el`を使っている人は, リポジトリの設定を行い `M-x list-packages`からインストールしてください.

[Cask](https://github.com/cask/cask)を利用している人は以下を Caskファイルに追加してください.

```el
(depends-on "git-gutter")
```

## git-gutterとは
Sublime Textの [GitGutter](https://github.com/jisaacks/GitGutter)を Emacsに移植したものです. 前回(変更可)のコミットからの変更を編集しながら視覚的に確認することができます. `git diff`等でどこを変更したっけとする必要がなくなります.


![git-gutter1.png](https://qiita-image-store.s3.amazonaws.com/0/12235/11b79fb3-b4c4-cded-8787-a2db05e68224.png)

上記の画像のように, 追加した箇所, 変更を行ったを箇所というのが一目でわかるツールです. 視覚的にわかるだけではなく, 変更箇所間の移動, 特定の箇所のみ変更を捨てるといったことができます.


## サポートしている VCS
- Git
- Mercurial
- Bazzar

`git-gutter`という名前ですが, Mercurialと Bazzarもサポートしています. 機能は一部制限されますが, 本質的な部分はサポートしているので, Git以外でも 用いることができます.

### Mercurial or Bazzarで git-gutterを使う

`git-gutter:handled-backends`で利用する VCSを指定します.
設定例を下記に示します.

```el
(custom-set-variables
 '(git-gutter:handled-backends '(git hg bzr)))
```

## 変更点を確認する
変更箇所には **added**, **deleted**, **modified**の3つのタイプがあります. それぞれ gutter部に表示される記号や色が異なります. 記号や faceを変更したい場合は以下に示した変数, faceを変更してください.

| Type    | Sign Variable | Face Name                    |
|:--------|:----------------|:----------------------------|
| added   | git-gutter:added-sign(Default "+")   | git-gutter:added     |
| deleted | git-gutter:deleted-sign(Default "-") | git-gutter:deleted  |
| modified| git-gutter:modified-sign(Default "=")| git-gutter:modified |


## 変更点の移動
`git-gutter.el`は変更点を視覚的に確認するツールですが, 変更箇所に移動できるツールとしても使えます. これは大変便利な機能(だと思う)のでぜひ利用して欲しいです.

移動コマンドはそれぞれ
- `git-gutter:next-hunk`(次の更新箇所に移動)
- `git-gutter:pervious-hunk`(前の更新箇所に移動)

です. 実行例を以下に示します.

![git-gutter-move.gif](https://qiita-image-store.s3.amazonaws.com/0/12235/5b709d10-c4ca-6f3c-557e-e1e724211c09.gif)

私はこのコマンドを多用するので, [smartrep](https://github.com/myuhe/smartrep.el)と組み合わせて利用しています.

```el
(smartrep-define-key
    global-map  "C-x" '(("p" . 'git-gutter:previous-hunk)
                        ("n" . 'git-gutter:next-hunk)))
```

### 変更点を表示した場合での移動
`git-gutter:popup-hunk`で変更箇所の diffを見ることができます. これを表示した状態で `git-gutter:next-hunk` or `git-gutter:previous-hunk`を実行すると diffが現在の更新箇所のものに更新されます.


![git-gutter-move-with-diff.gif](https://qiita-image-store.s3.amazonaws.com/0/12235/ad3e282c-870b-dd75-7e83-d5cd3184a800.gif)


### hunkの変更取り消し
他の変更箇所はそのままにしたいけど, このブロックだけは前のに戻したいということは結構あると思います. それを実現するのが `git-gutter:revert-hunk`です.


![git-gutter-revert.gif](https://qiita-image-store.s3.amazonaws.com/0/12235/20b23386-88c3-bd44-2222-7daced6db136.gif)


## おわりに
他にもいろいろあるのですが, 長くなってしまうので, もっと知りたい方は[ドキュメント](https://github.com/syohex/emacs-git-gutter/blob/master/README.md)を参照してください. またわからないことなどがあれば遠慮無く Twitter([@syohex](https://twitter.com/syohex))等で聞いてください.


git-gutter.elは自分で使ったツールの中でかなり大好きで重宝しているツールです(他は anzu, helm-gtags). なんでよくできるところは積極的に良くしたいと思っていますので, 改良点, 不満点があればぜひ教えていただきたいと思います. その際は githubの [issues](https://github.com/syohex/emacs-git-gutter/issues)までお願いします. 日本語で全然構わないので何かあればぜひお知らせください.


明日は @tadsanです. お楽しみに.