読者です 読者をやめる 読者になる 読者になる

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で含まれている物は以下.

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に別途設定を施す必要があるがそれはまた今度.