TabNine で Emacs の入力補完を当意即妙にする

Emacs でコードを書いている時、サジェストされる補完候補が当意即妙だったら嬉しいですよね。  

最近では [IntelliCode](https://visualstudio.microsoft.com/services/intellicode/) のようないい感じの補完機構が開発されています。
Emacs でも頭のいい補完ができないかなーと思っていたら [TabNine](https://tabnine.com/) を教えてもらったので、紹介させてください。

+ **2019/08/20: 「Deep code completion on your laptop」を追記しました**
+ **2019/07/18: 「Autocompletion with Deep Learning」を追記しました**

## TabNine とは

[TabNine](https://tabnine.com/) は、公式サイトによれば「機械学習を使用して、応答性と信頼性が高く、適切な補完候補を提供する」自動補完のエンジンです。最近流行りの機械学習ですね、わかります。
導入が手軽で、補完も **いい感じに** 効くのでオススメです。

|Feature|Premium|Free|
|:---:|:---:|:---:|
|Semantic Completion|Yes|Yes|
|Whole project indexing|Yes|Yes|
|.gitignore awareness|Yes|Yes|
|Fuzzy matching|Yes|Yes|
|No configuration necessary|Yes|Yes|
|~20 millisecond response time|Yes|Yes|
|Context-aware suggestions|Yes|Yes|
|Vim support|Yes|Yes|
|Sublime Text support|Yes|Yes|
|VS Code support|Yes|Yes|
|Atom support|Yes|Yes|
|Up to 400 KB indexed|Yes|Yes|
|Up to 100 MB indexed|Yes|-|

※ [GitHub](https://github.com/zxqfl/TabNine) に Repository は存在しますが、基本的にクローズドな開発のようで、主に issue 管理やリリースノートのために利用されているようです。

## 補完機能

### Context-aware Suggestion

まわりのコードの雰囲気を読んで、いい感じに補完候補をサジェストしてくれます。
※ 画像は公式サイトからいただいてます（Emacsの画面ではなさそう）

**例1: 少数の前例から類推・生成される補完候補**
<img width="620" alt="gallery8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144707/0868deed-abe6-b65a-c637-527cb0e13eb1.png">

**例2: `name` パラメータには、変数名と同じ文字列が用いられる**
<img width="620" alt="gallery2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144707/bcacbd63-eb5c-827b-5972-70cdd1b50885.png">

**例3: すべての struct 宣言は `unsigned long long` で行われている**
<img width="620" alt="gallery3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144707/4dadb297-482c-6182-a255-f82b8381a91b.png">

### Semantic Completion

_Semantic_ _Completion_ と呼ばれる「言語ごとに特化した補完」を実現しています。
これについては [Language Server Protocol](https://github.com/microsoft/language-server-protocol) との連携が必要になります（後述）。

**例: ある言語における String クラスの補完**
<img width="420" alt="gallery12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144707/5f6ad8b5-31f4-7bc6-875a-14ee3b0fae75.png">

### 高速 fuzzy な補完

一般に Emacs の fuzzy な補完はあまり高速ではないのですが、 TabNine は高速に補完できます。

+ 例1: `fbb` と入力することで（補完候補として存在すれば）`foo_bar_baz` が補完されます
+ 例2: `fBB` と入力することで（補完候補として存在すれば）`fooBarBaz` が補完されます

## セットアップ

基本的に[公式サイト](https://tabnine.com/install)の通りにやれば大丈夫です。
[company-tabnine](https://github.com/TommyX12/company-tabnine) という package が MELPA に登録されているので、そちらを利用します。

1. MELPA から install する（いつも通り `package-install` や `use-package` でお好みで）
2. `(add-to-list 'company-backends #'company-tabnine)` を init.el に追記
3. `M-x company-tabnine-install-binary` を実行して TabNine のバイナリをインストールする

とても簡単ですが、3 が少し特殊です（TabNine は Web サーバと通信するわけではないんですね）。

### Semantic Completion

前提として、LSP を使える環境を構築している必要があります。[「Qiita/Emacs で LSP を活用してみる」](https://qiita.com/blue0513/items/acc962738c7f4da26656)などをご参考頂ければ設定できると思います。LSP 設定後は[公式サイト](https://tabnine.com/semantic)の通りにすればよいのですが、ちょっとわかりにくいので解説します。

#### 1. TabNine のバージョンが 1.0.5 以上か確認する

"By typing `TabNine::version`" と書いてありますが、これは文字通り「TabNine::version」という文字列を打つということです。Emacs で適当な buffer を開いて、「TabNine::version」と **どこでもいいから** 書いてださい。バージョンが見えます。
<img width="420" alt="Screen Shot 2019-05-18 at 19.38.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144707/b88e2995-763a-47e4-20b9-cf616411e8ef.png">

#### 2. Semantic Completion を有効化する

同じく "Type `TabNine::sem`" と書いてありますが、同じく「TabNine::sem」という文字列を **どこでもいいから** 打ちます。
すると、以下のように有効化されたことがわかります。
<img width="420" alt="Screen Shot 2019-05-18 at 19.40.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144707/9359a0b6-158d-fd80-fd29-325c2ec13a94.png">

## 使い方

いつも通りコーディングしてください！
当意即妙な補完候補がサジェストされます！
嬉しい！

## Autocompletion with Deep Learning

「[Autocompletion with deep learning](https://tabnine.com/blog/deep)」というタイトルで開発ブログが更新されていました。 
まだベータ版ですが、GPUパワーで強化されたサーバにリクエストを送ることで、より精度の高い自動補完機能を提供するというものらしいです。これは期待大ですね。

## Deep code completion on your laptop

「[Deep code completion on your laptop](https://tabnine.com/blog/local)」ということで、ついにローカル環境で Deep TabNine を利用できるようになりました。Cloud 版 TabNine では、コードをサーバに送らなくてはなりませんでした。そのため、企業などでコードを書いている方は利用が少し難しかったですが、ローカル版が出たことでその問題も解決されました。

## その他

ライセンスを $49 で購入することで、インデックス容量が増えます（400 KB から 100 MB）。
[公式サイト](https://tabnine.com/buy)曰く、TabNine は以下の前提と仮定の元では、ライセンス購入をする価値があるとしています。

+ 前提条件: TabNine は、1分 あたり 1秒 の時間節約になる
+ 仮定1: 自分の時間の価値が $1.4/hour 以上である
+ 仮定2: 1年あたり2087時間の作業時間がある

```
val 1時間の作業で節約可能な時間 = 1/60
val 1年で節約可能な時間の合計 = 2087 * 1時間の作業で節約可能な時間
val 1年で節約可能なお金 = 1.4 * 1年で節約可能な時間の合計
>> print 1年で節約可能なお金 
>> 48.6966666667
```
.....たしかに！？！？