Emacsでコード補完を利用するためにauto-complete-clang-asyncを導入してみた
OSX上のemacs-version "24.2.2"なEmacsでの話
auto-complete
まずは前提となるauto-completeがないと話にならないので, サイトのダウンロードから一式落として, 然るべき処(~/.emacs.d/site-lispなど)に必要な物一式コピーする.
cp *.el ~/.emacs.d/site-lisp/
mkdir ~/.emacs.d/ac-dict
cp dict/*-mode ~/.emacs.d/ac-dict
~/.emacs.d/init.elなどにauto-completeの設定を記述.
(require 'auto-complete) (require 'auto-complete-config) (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict") (ac-config-default) (setq ac-modes (append ac-modes '(objc-mode)))
ac-modesのdefaultにはobjc-modeは入っていないので別途追加している. ちなみにac-modesにdefaultで含まれている物は以下.
- emacs-lisp-mode
- lisp-interaction-mode
- c-mode
- cc-mode
- c++-mode
- java-mode
- clojure-mode
- scala-mode
- scheme-mode
- ocaml-mode
- tuareg-mode
- perl-mode
- cperl-mode
- python-mode
- ruby-mode
- ecmascript-mode
- javascript-mode
- js-mode
- js2-mode
- php-mode
- css-mode
- makefile-mode
- sh-mode
- fortran-mode
- f90-mode
- ada-mode
- xml-mode
- sgml-mode
auto-complete-clang-async ちょっとその前に
続いてauto-comlete-clang-asyncを入れ……る前に, XCode付属のclangではうまく動いてくれないという不幸が訪れるので先に自前でclangをビルドする.
clang
llvm.orgから一式落としてくる. 執筆段階では3.4がリリースされているので3.4を利用する.
curl -O http://llvm.org/releases/3.4/llvm-3.4.src.tar.gz curl -O http://llvm.org/releases/3.4/clang-3.4.src.tar.gz tar zxvf llvm-3.4.src.tar.gz tar zxvf clang-3.4.src.tar.gz mv clang-3.4 llvm-3.4/tools/clang mkdir build cd build # $HOME/local/llvmにinstallする前提. ../llvm-3.4/configure --prefix $HOME/local/llvm --enable-optimized --disable-assersions make clean && make -j4 && make check-all && make install
auto-complete-clang-async
いよいよC++のコード補完をよしなにするために
git clone git@github.com:Golevka/emacs-clang-complete-async cd emacs-clang-comlete-async export DYLD_LIBRARY_PATH=$HOME/local/llvm/lib:$DYLD_LIBRARY_PATH # 上でinstallしたlibclang.dylibにアクセス可能にするための処置. make cp clang-complete ~/.emacs.d/bin # Emacsからアクセスできる場所に設置. cp auto-complete-clang-async.el ~/.emacs.d/site-lisp
clang-completeが内部でclangのcc1を起動して良い感じの補完候補を抽出してくれるようになるらしい(ちゃんとコード読んでない).
そのclang-comleteと通信してEmacs上でコード補完を行えるようにしてくれるのがauto-comlete-clang-async.
auto-complete-clang-asyncを以下のようにする事で使用可能となる.
(require 'auto-complete-clang-async) (defun ac-cc-mode-setup () (setq ac-clang-complete-executable (expand-file-name "~/.emacs.d/bin/clang-complete")) (setq ac-sources (append '(ac-source-clang-async) ac-sources)) (setq ac-clang-cflags (mapcar (lambda (item) (concat "-I" (expand-file-name item))) (split-string "~/local/llvm/lib/clang/3.4/include ~/local/include"))) (setq ac-clang-cflags (append '("-std=c++1y") ac-clang-cflags)) (ac-clang-launch-completion-process)) (add-hook 'c-mode-common-hook 'ac-cc-mode-setup) (add-hook 'c++-mode-common-hook 'ac-cc-mode-setup) (add-hook 'auto-complete-mode-hook 'ac-common-setup) (global-auto-complete-mode t)
clang-complete, というかclang -cc1はCFLAGSを元に補完候補を抽出するので追加のincludeパスがある場合はac-clang-cflagsに設定を追加する必要がある.
上の例だとC++1yを対象としていてObjctive-Cではちゃんと補完されないため, 設定用の函数を作りobjc-mode-hookに別途設定を施す必要があるがそれはまた今度.