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


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

最近では IntelliCode のようないい感じの補完機構が開発されています。
Emacs でも頭のいい補完ができないかなーと思っていたら TabNine を教えてもらったので、紹介させてください。

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

TabNine とは

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

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 に Repository は存在しますが、基本的にクローズドな開発のようで、主に issue 管理やリリースノートのために利用されているようです。

補完機能

Context-aware Suggestion

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

例1: 少数の前例から類推・生成される補完候補

例2: name パラメータには、変数名と同じ文字列が用いられる

例3: すべての struct 宣言は unsigned long long で行われている

Semantic Completion

Semantic Completion と呼ばれる「言語ごとに特化した補完」を実現しています。
これについては Language Server Protocol との連携が必要になります(後述)。

例: ある言語における String クラスの補完

高速 fuzzy な補完

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

  • 例1: fbb と入力することで(補完候補として存在すれば)foo_bar_baz が補完されます
  • 例2: fBB と入力することで(補完候補として存在すれば)fooBarBaz が補完されます

セットアップ

基本的に公式サイトの通りにやれば大丈夫です。
company-tabnine という package が MELPA に登録されているので、そちらを利用します。

  1. MELPA から install する(いつも通り package-installuse-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 を活用してみる」などをご参考頂ければ設定できると思います。LSP 設定後は公式サイトの通りにすればよいのですが、ちょっとわかりにくいので解説します。

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

"By typing TabNine::version" と書いてありますが、これは文字通り「TabNine::version」という文字列を打つということです。Emacs で適当な buffer を開いて、「TabNine::version」と どこでもいいから 書いてださい。バージョンが見えます。

2. Semantic Completion を有効化する

同じく "Type TabNine::sem" と書いてありますが、同じく「TabNine::sem」という文字列を どこでもいいから 打ちます。
すると、以下のように有効化されたことがわかります。

使い方

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

Autocompletion with Deep Learning

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

Deep code completion on your laptop

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

その他

ライセンスを $49 で購入することで、インデックス容量が増えます(400 KB から 100 MB)。
公式サイト曰く、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

.....たしかに!?!?