続 auto-complete-clang
どもです。
風邪がだいぶ楽になってきて幸せをかみしめています。
てか,明日の最高気温と最低気温が6度って(東京ね)。
また風邪ひくんちゃうかぁ。
最初に言っておきますが,以下のことをしてもそれほど実用的にはならんと思います。
自分でやっておいてなんですが。
過程が大事なんです,過程が。と,自分に言い聞かせています。
ちょっと頑張ってみた
人生初の YouTube への投稿。gif アニメを作成するのが面倒だったし。。。
まず,pch を作成した。
stl.hh というファイルを,下記の内容で作成。
#include <algorithm> #include <bitset> #include <deque> #include <fstream> #include <functional> #include <iomanip> #include <iostream> #include <iterator> #include <list> #include <map> #include <queue> #include <set> #include <stack> #include <string> #include <typeinfo> #include <utility> #include <vector>
ほいで,プリコンパイルヘッダ(日本語はこれであってるのだろうか?) を作成します。
% clang -cc1 -x c++-header ./stl.hh -emit-pch -o stl.hh.pch
brianjcj さん作成の auto-complete-clang.el を使用するという前提で話を進めます。
ac-clang-set-prefix-header という interactive な関数が用意されているので,
M-x ac-clang-set-prefix-header して,先ほど作成した pch を指定します。
これで,pch を使えるなら使って補完してくれるはずです。
けど,複数の pch を使用したい場合とかは困るので,リストで管理してくれるとうれしいな。
etags みたいに。
だが,しかし・・・。
自動補完にしておくと,1文字入力しただけで,ac-source-clang による補完が
始まります。(デフォルトのままだとね)
これは困ります。
なので,ソースに手を入れて,下記の条件の時に ac-source-clang による補完が
発動するようにしてみた。
その条件は,現在のポイントと backward な方向にある最初のスペース(ない場合は,行頭)
の間に「<」,「.」,「->」,「::」,がある,もしくは,
入力文字が,「.」,「->」,「::」である,というもの。
こうして,発動条件を絞ることで,自動補完にしておいても,くるしゅーない。
以下,diff。
--- auto-complete-clang.el 2011/03/06 04:04:52 1.1 +++ auto-complete-clang.el 2011/03/06 12:57:09 @@ -243,8 +243,20 @@ (unless (cdr candidates) ;; unless length > 1 (message (replace-regexp-in-string "\n" " ; " help)))))) +(defun ac-clang-prefix-symbol () + "Return the result of (ac-prefix-symbol) if there is a `<' or `.' or +`->' or `::' between current point and the nearest space or tab +backward." + (let ((p (or (save-excursion + (re-search-backward "[ \t]" + (save-excursion (beginning-of-line) (point)) + t)) + (save-excursion (beginning-of-line) (point))))) + (when (save-excursion (re-search-backward "<\\|\\.\\|->\\|::" p t)) + (ac-prefix-symbol)))) + (defun ac-clang-prefix () - (or (ac-prefix-symbol) + (or (ac-clang-prefix-symbol) (let ((c (char-before))) (when (or (eq ?\. c) ;; ->
あと,ソースがかなり読みやすかった気がします。
勉強になります。
ほいで,以上2つのことを使ったデモが,最初の動画です。
まとめ
ぶっちゃけ,これでも,デカイソースとかだと使い物にならんと思います。
というわけで,まとめると,やっぱりトリガーキーを設定して,
補完するのがいいかなぁというオチです。
その他。
vim の clang_complete が,libclang をどうやって使っているのか知りたくて,
ソースを眺めてみた。前回よりは少し分かった気がする。
どうやら,libclang を python から使えるのがあって,
そいつを使って,補完をしている感じ?
そうすると,毎回 clang を呼ばなくて,自前でキャッシュとか管理すればいいので,
早くなるという感じかな?
確かに,補完目的で,毎回ヘッダなりをパースするのは,変更が加わらない限り無駄だしね。
ほいで,最初から用意されているヘッダ,例えば,vector とかは,外部から使う分には,
変更するこたーないと。
いや,書いていて思ったが,そんなことはないのか。入力は刻一刻と変わるので,
補完対象を決めるのには毎回パースする必要があるのか。
とすると,どうして早くなるんだろう。。。
ま,いいや。
あれ? ということはさぁ,emacs からでも使えるんじゃね?
誰か作ってくれないかなぁ。
細かい設定(色とか,候補数の制限とか)をやっていないので,
それらをやる必要があるわけで,たぶん続く。はず。きっと。おそらく。もしかしたら。
最後に作者の人達にありがとう!