auto-completeを使おう
====================

auto-completeとは
—————–

今回は手前味噌ながら拙作のauto-completeという補完パッケージの紹介と使い方の説明をしたいと思います。auto-completeはEmacsの貧弱な補完インターフェースを補完する目的で2008年に開発されました。従来のEmacsの補完インターフェースというのは良くも悪くもEmacs流でした。例えばカーソル直下のLispシンボルを補完するlisp-complete-symbol(M-TAB)を実行すると、現在のウィンドウが分割されて新しいウィンドウに補完候補が一覧されます。そして、最新のEmacsでもそうなのですが、その新しいウィンドウは自分で閉じない限り永遠に存在しつづけるのです。

長年Emacsを使っている人にとってはこの挙動はむしろ自然なのかもしれませんが、Emacsをそこそこに使う初中級者にとってはこの挙動はどうにも扱える気がしないのです。auto-completeを開発した動機として、このような不満によるところが非常に大きいのです。

auto-completeが提供している補完インターフェースは一言で言えば現代的で、Visual StudioのIntelliSenseやEclipseのCodeAssistに近いインターフェースになっています。適当に文字を打てば補完が開始されて、次のようになります。ここから追加で文字を入力しても良いですし、カーソルキーで候補を選択してRETで補完しても良いです。

auto-completeは補完中に特定のキー入力のみをハンドリングして操作を可能にしています。それ以外のキー入力はそのまま処理されるので、ユーザーの作業プロセスをauto-completeが邪魔するということはありません。auto-completeはまさに影の役者なのです。名前のauto-はそのことを含意しています。

IntelliSenseやCodeAssistと大きく異なるのは、ユーザーが簡単にauto-completeを拡張できるという点です。auto-completeの拡張方法は次回に詳しく説明します。

インストールの手順
—————

少し前まではauto-completeはクローズな開発をしていました。現在はGithub(*)にGitリポジトリを作り、その上で開発を行っています。Githubのアカウントを持っておられる方は次のURLから私をフォローするなりauto-completeをウォッチするなりしていただけると嬉しいです。また、Issue Tracking Systemがついているのでバグ報告もここから行えます。できるだけ早く対応するつもりなので、どうぞご利用ください。

http://github.com/m2ym/auto-complete

(*) GithubはGitリポジトリをホスティングしてくれるサービスです。ソーシャルネットワーク機能もついていて楽しく開発が行えるのが特徴です。

雑誌に掲載するにあたってauto-completeの安定版(v1.0)をリリースしました。雑誌に掲載されている内容と過度な相違が発生しないためですが、あまり意味はありません。記念のようなものだと思ってください。この安定板は次のURLから手に入ります。

http://github.com/m2ym/auto-complete/tree/v1.0

今後はこのバージョンがインストールされているという前提で説明を行います。

さて、インストール方法ですが、基本的に次の4つのElispファイルをロードパスの通ったディレクトリに置けばそれで終わりです。

– expander.el
– pulldown.el
– auto-complete.el
– auto-complete-config.el

ブラウザで一つ一つダウンロードしてインストールするのも良いですが、Gitを使える環境なら次のコマンドでインストールするほうが楽でしょう。

貧弱な環境をお使いの方のためにアーカイブファイルを提供しておきます。ただしバグ修正などが即座に反映される保証はないのでご注意ください。

http://cx4a.org/pub/auto-complete-1.0.zip

インストールできたら次のコードを.emacsに書いてEmacsを再起動してください(*)。

(*) 理想はC-x C-eなどでそのコードを評価して再起動を避けることです。

それでは、auto-completeが有効なバッファ(モードラインにACと出ている)で、適当な単語を入力して、違う場所でその単語を入力しようとしてみてください。次のようになれば成功です。

auto-completeはM-x auto-complete-modeで適宜オン/オフできます。デフォルトではメジャーなプログラミング言語モードで自動的にオンになるようになっています(ac-modesで設定可能)。

基本的な使い方
————

上記したようにauto-completeは極力ユーザーの邪魔にならないように設計されています。特に設定しなければ、いかなるキーバインドも上書きしません。ただし例外があって、補完メニューが出ている状況では特定のキー入力が特別にハンドリングされます。

その際のキーの対応表は次のようになります。

| キー | コマンド | 説明 |
|——+————-+——————————–|
| TAB | ac-expand | 共通部分展開、補完・次候補選択 |
| RET | ac-complete | 補完完了(アクション実行) |
| down | ac-next | 次候補選択 |
| up | ac-previous | 前候補選択 |

これらのコマンドについて簡単に説明します。

ac-expand
~~~~~~~~~

ac-expandは次に述べる三つの動作を必要に応じて行います。

1. 共通部分展開
全ての候補に共通部分がある場合、ac-expandはその共通部分を展開し、補完を続行します。共通部分は補完中にカーソル直後にハイライトされて表示されます。

最初のac-expandでは、上の画像の青くハイライトされた部分(共通部分)が展開されます。二回目以降のac-expandは(2)あるいは(3)の動作をします。

2. 補完
選択された候補を展開します。アクションは実行されません(*)。

3. 選択された候補がすでに展開されている場合は、次の候補を選択して展開します。つまり連続してTABを押すことで、次々と候補を選択していくことができます。

ac-dwimがt(デフォルトはnil)で、なおかつ候補が一つしかない場合、ac-expandは選択された候補を補完して補完を終了します。

(*) アクションは補完完了時に実行される動作で、候補ごとに設定可能です。詳しくは次回に説明します。

ac-complete
~~~~~~~~~~~

ac-completeは選択された候補を展開して補完(アクション)を実行します。アクションについては次回に説明するので、ここではac-expandの違いとして、共通部分展開がないことと、即座に補完が終了することだけ理解しておいてください。

ac-next/ac-previous
~~~~~~~~~~~~~~~~~~~

ac-next/ac-previousは次候補/前候補を選択するコマンドです。特に説明する必要はないでしょう。

基本的な流れ
~~~~~~~~~~

auto-completeを使うにあたっての基本的な流れをまとめます。

1. 適当な文字列を入力する
2. 補完メニューが出現する
3. 追加で文字を入力したり、上記したキーを駆使して補完する(しなくてもOK)
4. 補完メニューが消える
5. 1に戻る

応用的な使い方
————

前節ではauto-completeの基本的な使い方を説明しました。auto-completeの本来の目的は「自動的」に補完が実行されることなので、前節の内容が「基本的」であるのはおそらく正しいことです。ただ、十人十色と言うように、世の中には物事を他の人とは違った方法で処理する人がいるものです。ここでは、そのような方法を「応用的」と名付けて説明したいと思います。

auto-completeでおそらく一番善し悪しの意見が分かれるのは、補完を自動的に開始すべきかどうかという点です。私は次に述べる理由で自動的に開始する派なので、auto-completeのデフォルトの動作もそのようになっています。

1. 即時フィードバックが得られる
2. 初心者に分かりやすい
3. かっこいい

もちろんメリットはあるのですが、補完メニューがぴょこぴょこ出てうるさいというデメリットもあります。そしてEmacs上級者になればなるほどそのように考える傾向が強いようです。

auto-completeはこの点を考えて自動的に開始するかどうかを制御するac-auto-startというオプションを提供しています。

ac-auto-startはt、nil、整数値のいずれかの値を取ります(デフォルトはt)。

ac-auto-startがtの場合、文字を入力すると自動的に補完が開始されます。これは前節で説明した挙動になります。

ac-auto-startが整数値の場合、自動的に補完が開始されるのは同じですが、補完対象となる文字列の長さがac-auto-start以上にならなければ、開始されません。ごく短い単語はそのまま入力したほうが早いので、必要ならac-auto-startを2や3に設定することをお勧めします。

ac-auto-startがnilの場合、補完が自動的に開始されることはありません。そのため、なんらかの手段を用いて手動で補完を開始しなければなりません。一番簡単なのはdefine-keyでauto-completeのモードマップにauto-completeコマンドを割り当てることです。

(define-key ac-mode-map (kbd “M-TAB”) ‘auto-complete)

あるいはglobal-set-keyでauto-completeコマンドを割り当てても良いでしょう。

(global-set-key (kbd “M-i”) ‘auto-complete)

上記のコードを評価した後に、適当な文字の直後でM-TABあるいはM-iすると補完が開始されるはずです。補完は頻繁に行うため、押しやすいキーに割り当てるべきです。押しやすいキーが空いてない場合は、auto-completeのトリガーキーの機構を使うことをお勧めします。この機構を使えば任意のキーをコンテキストに応じて補完用のキーに置きかえることができます。例えばTABをトリガーキーとして使うには、次のコードを評価するか、M-x customize-variableでac-trigger-keyを”TAB”にします。

(ac-set-trigger-key “TAB”)

これで、コンテキストに応じてTABが補完用のキーになったり、従来の動作(インデント)になったりします。コンテキストに応じてというのは次のことを意味します。

1. prefix付きでトリガーキーが実行された場合(例: C-u TAB)
2. 前回のコマンドが挿入(self-insert-command)や削除(delete-backward-char)である場合((ac-trigger-command-p last-command)がt)

簡単に言えば、何らかの挿入や削除の後でTABを押せば補完が開始され、それ以外の場合でTABを押せば従来の動作(インデント)になります。またC-u TABのようにprefix付きの場合は強制的に補完を開始します。


def の直後でTABを押した図

設定例
~~~~~

以上のことを踏まえて、手動で補完を行う設定例を示します。自動的に補完が開始されるのがイヤな方はこの設定を.emacsに書いてご利用ください。

(setq ac-auto-start nil) ; 自動的に開始しない
(ac-set-trigger-key “TAB”) ; コンテキストに応じてTABで補完

情報源の設定
———-

さて、補完を自動的に開始するか手動で開始するかを決めたら、次は情報源の設定を行いましょう。情報源とは補完候補を生成する独立した個々の機能のことで、C言語の関数一覧を生成する情報源や、Lispシンボルの一覧を生成する情報源など様々存在します。Anythingをご存知の方は、Anythingの情報源と同じ概念だと考えていただいて問題ありません。

ユーザーは様々な情報源を好きに組み合わせて設定することにより、自分の作業に適した補完環境を作りあげることができます。情報源の設定はac-sources変数に情報源のリストを与えることで行います。例えば、Lispシンボルを補完するには、Lispシンボルの一覧を生成するac-source-symbolsという情報源をac-sourcesに追加します。

(push ‘ac-source-symbols ac-sources)

実際に動きを確認するには、適当なバッファで上記のコードを評価してください(M-:で評価できます)。というのも、ac-sourcesは全てのバッファでバッファローカルになるので、特定のバッファでac-sourcesを変更しても、他のバッファに適用されないのです。もし全てのバッファで共通の設定を書きたいのなら(おそらく.emacsに書く)、setqの変わりにsetq-defaultを使ってac-sourcesを設定してください。

;; 全てのバッファで共通の設定
;; * 同じメジャーモード間での単語補完
;; * Lispシンボルの補完
(setq-default ac-sources ‘(ac-source-words-in-same-mode-buffers ac-source-symbols))

また、特定のモードでのみある情報源を利用にする場合は、add-hookを使って次のように書いてください。

;; ruby-modeの場合はabbrev補完を使う
(add-hook ‘ruby-mode-hook (lambda () (add-to-list ‘ac-sources ‘ac-source-abbrev)))

情報源はac-sourcesの先頭にあるものほど優先的に使用されます。これはほとんどの場合では問題になりませんが、先に挙げたac-source-filenameというファイル名を補完する情報源は、オムニ補完(*)という機構を利用しているため、もし汎用的に単語を補完する情報源より後にac-source-filenameが出現する場合、単語を補完する情報源がac-source-filenameのオムニ補完の発生条件を飲み込んでしまって、うまくファイル名補完が開始されないことがあります。そのような場合にはac-source-filenameをできるだけac-sourcesの先頭にもってきてやる必要があります。通常は次のようにadd-hookを使ってできるだけ最後にpushされるようにすれば解決できます。

(*) オムニ補完という語はVimから来ています。意味は「書式・構文を解析することにより実現する賢い補完機能」です

;; ac-source-filenameはできるだけ先頭に
(add-hook ‘auto-complete-mode-hook (lambda () (add-to-list ‘ac-sources ‘ac-source-filename)))

標準情報源
~~~~~~~~

次に標準的な情報源の名前と説明を列挙します。それぞれ利用したいものをピックアップしてac-sourcesに設定してください。

| 名前 | 説明 |
|————————————–+——————————————————————|
| ac-source-words-in-buffer | 現在のバッファ内の単語を補完 |
| ac-source-words-in-all-buffer | 全てのバッファ内の単語を補完 |
| ac-source-words-in-same-mode-buffers | 同じメジャーモードのバッファ内の単語を補完。プログラミングに便利 |
| ac-source-symbols | Lispのシンボルを補完。Emacs Lispを書く人向け |
| ac-source-abbrev | abbrevを補完 |
| ac-source-filename | ファイル名補完 |
| ac-source-imenu | imenuの補完 |
| ac-source-yasnippet | yasnippetの補完 |

その他の設定
———-

次候補/前候補の選択をC-n/C-pで行う
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ac-completing-mapは補完中のキーマップです。これを変更することで望み通りの動作にすることができます。

(define-key ac-completing-map (kbd “C-n”) ‘ac-next)
(define-key ac-completing-map (kbd “C-p”) ‘ac-previous)

TABで補完を完了する
~~~~~~~~~~~~~~~~~

(define-key ac-completing-map (kbd “TAB”) ‘ac-complete)

空気を読んでほしい
~~~~~~~~~~~~~~~~

ac-dwimをtにすると次のような挙動になります。

1. 一つしか候補がない時にTAB(ac-expand)すると補完を完了(ac-complete)する
2. 次候補/前候補を選んだ後にTAB(ac-expand)すると補完を完了(ac-complete)する
3. 補完後にメニューを自動的に非表示にする

ac-dwimはデフォルトはnilですが、tにしたほうが色々便利だと思います。今後のバージョンでデフォルトが変わるかもしれません。

(setq ac-dwim t)

まとめ
—–

今回はauto-completeの基本的な使い方および簡単な設定方法を説明しました。次回はauto-completeをもっと深く拡張する方法について説明したいと思います。

最後に全体的な設定例を示します。是非ご利用ください。