Windows上のNTEmacsでC++を書くための設定をしました
"EmacsをVisualStudioみたいにしてやるぜ!"って書くとビッグマウスが過ぎる気がしたので地味なタイトルにしたのですが、目指すところはそこです。
Windows + cygwin + NTEmacsでやっていきます。
お品書き
下準備 NTEmacsとauto-install.elとcygwin
http://sourceforge.jp/projects/gnupack/releases/?package_id=10839
からemacsの最新バージョンをダウンロードして解凍して適当なところにおいてください(2013/03/03現在emacs-24.2-20121208.exe)。
bin/runemacs.exeからemacsを実行できます。
なくても良いのですがあると便利なのでauto-install.elをインストールします。
http://www.emacswiki.org/emacs/download/auto-install.el
からauto-install.elをダウンロードして~/.emacs.d/site-lisp/においてください。
(フォルダがなければ作成してください)
次に~/.emacsに以下を追加してください。
(なければ作成してください)
(add-to-list 'load-path "~/.emacs.d/site-lisp/") (add-to-list 'load-path "~/.emacs.d/auto-install/") (require 'auto-install)
auto-complete-clang-async.elで補完
EmacsにおけるC++の補完は、ちゃんとソースを解析して候補を出してくれるものに限ると多分clangとgccsenseの2つしかないと思います。
一応CEDETもあるけど、なんか巨大なうえになんかよくわからんというか。。。 以前試してみたけど全く動かせなかったのでとりあえず今回は却下としておきます。ひい。
gccsenseはDebianで動かせて良い感じだったのですが、Windowsでは(僕は)動かすことが出来なかったので今回は却下です。
(VMWareにDebianを入れてsshで接続して... 見たいな事も試しましたがいちいちVMを立ち上げるのがめんどくさくてやめました)
clangはauto-complete-clang.elというものがあったので以前試してみたのですが、僕の貧弱な環境だと遅くて使い物にならない感じでした。
auto-complete-clang-async.elは補完候補を非同期で集めてくれるんだと思います。しらんけど。
とにかくこれが僕の環境でも使えるくらいにははやかったのでこれを採用することにします。
参考URL
http://boronology.blogspot.jp/2012/09/emacscemacs-clang-complete-async.html
まず、auto-complete.elをインストールします。
M-x auto-install-batch auto-complete development version
~/.emacs.d/site-lisp/ac-dictフォルダを作成しておいてください。
.emacsに以下を追加します。
;; auto-complete (require 'auto-complete-config) (add-to-list 'ac-dictionary-directories "~/.emacs.d/site-lisp/ac-dict") (ac-config-default)
次に、LLVMとclangをインストールします。
cygwinのインストーラでllvmとclangで検索にひっかかったものをとりあえず全部インストールしてください。
最後にemacs-clang-complete-asyncをインストールします。
$ git clone git://github.com/Golevka/emacs-clang-complete-async.git $ cd emacs-clang-complete-async $ make
を実行して作成されたclang-complete.exeをパスの通ったフォルダにおいてください。そして、auto-complete-clang-async.elを~/.emacs.d/site-lisp/においてください。そして、以下を.emacsに追加するのです。
;; auto-complete-clang-async (require 'auto-complete-clang-async) (defun ac-cc-mode-setup () (setq ac-clang-complete-executable "~/.emacs.d/site-lisp/clang-complete") (setq ac-sources '(ac-source-clang-async)) (ac-clang-launch-completion-process) ) (defun my-ac-config () (global-set-key "\M-/" 'ac-start) ;; C-n/C-p で候補を選択 (define-key ac-complete-mode-map "\C-n" 'ac-next) (define-key ac-complete-mode-map "\C-p" 'ac-previous) (add-hook 'c-mode-common-hook 'ac-cc-mode-setup) (add-hook 'auto-complete-mode-hook 'ac-common-setup) (global-auto-complete-mode t)) (my-ac-config)
これで、
vector<int> v;
v.
関数を補完したときに引数が勝手に入っちゃってたりとか、親クラスの関数を補完しようとするとへんなのがくっついちゃったりとかして挙動が微妙なとこが何点かありますが今後に期待というかんじでしょうか。
c-eldocで関数とかの宣言を見る
たまにしか使わない関数の引数とか覚えてるわけないですよね。
何をしてくれる関数か分かっていて、引数の順番が分からないだけなのにいちいちドキュメントを引くのもめんどうですよね。
ということでeldocです。
参考URL
http://d.hatena.ne.jp/mooz/20100421/p1
インストール方法は以下です。
M-x auto-install-from-emacswiki c-eldoc.el
でc-eldoc.elを入手します。
そして、以下を.emacsに追加します。
;; c-eldoc ; コマンドを/bin/cpp から変更 (setq c-eldoc-cpp-command "C:\\cygwin\\bin\\cpp-3 ") (load "c-eldoc") (setq c-eldoc-includes "-I./ -I../ ") (add-hook 'c-mode-hook 'c-turn-on-eldoc-mode) (add-hook 'c++-mode-hook (lambda () (set (make-local-variable 'eldoc-idle-delay) 0.20) (c-turn-on-eldoc-mode)))
注意が必要なのが、cppのパスを変更すること(とcpp-3の後にちゃんとスペースを入れること!)と、cpp-3の(Windows的な意味での)実行権限を自分に与えておくことです。cpp-3.exeのプロパティから設定しておいてください。
gtagsで関数の定義にジャンプ
"この関数の定義を見たい!"ってときはよくありますよね。grepかけても良いですがいちいち面倒ですよね。
そこでgtags(GNU Global)です。
参考URL
http://cha.la.coocan.jp/doc/gnu_global.html
http://qiita.com/items/d9e686d2f2a092321e34
まず以下からバイナリを落としてきます。
http://adoxa.3eeweb.com/global/index.html
解凍してパスが通ったフォルダにおいといてください。
次に、gtags.elを落としてきます。
M-x auto-install-from-url https://raw.github.com/voins/gtags/master/gtags.el
ほんで.emacsに以下を追加します。
; GTAGS ;--- GNU GLOBAL(gtags) gtags.el --- (require 'gtags) (global-set-key "\C-o" 'gtags-find-tag) ;関数の定義元へ (global-set-key "\M-r" 'gtags-find-rtag) ;関数の参照先へ (global-set-key "\M-s" 'gtags-find-symbol) ;変数の定義元/参照先へ (global-set-key "\C-cp" 'gtags-find-pattern) (global-set-key "\C-cf" 'gtags-find-file) ;ファイルにジャンプ (global-set-key "\M-o" 'gtags-pop-stack) ;前のバッファに戻る ;; update GTAGS (defun update-gtags (&optional prefix) (interactive "P") (let ((rootdir (gtags-get-rootpath)) (args (if prefix "-v" "-iv"))) (when rootdir (let* ((default-directory rootdir) (buffer (get-buffer-create "*update GTAGS*"))) (save-excursion (set-buffer buffer) (erase-buffer) (let ((result (process-file "gtags" nil buffer nil args))) (if (= 0 result) (message "GTAGS successfully updated.") (message "update GTAGS error with exit status %d" result)))))))) (add-hook 'after-save-hook 'update-gtags) (add-hook 'c-mode-common-hook '(lambda() (gtags-mode 1)))
gtagsは"どのファイルの何行目に関数hogehogeの定義がある"みたいな情報をまとめたファイル(タグファイル)をあらかじめ作成しておいて、
"hogehogeどこー?"って言われたときにそのタグファイルから関数の定義位置をかえす、みたいなことをするので、ファイルを書き換えたら
タグファイルを更新してやらなければなりません。手動でやるのは面倒ですが、この設定だとファイル保存時に自動で更新してくれます。
flymakeで文法チェック
セミコロンを付け忘れたとか、閉じ括弧が一個足りなかったとか、そういうしょうもないミスでコンパイルが失敗するのはめんどくさいですよね。
参考URL
http://d.hatena.ne.jp/suztomo/20080905/1220633281
インストール方法は以下です。
.emacsに以下を追加します。
;; flymake (require 'flymake) (defun flymake-cc-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) ; g++ を g++-4に変更 (list "g++-4" (list "-Wall" "-Wextra" "-fsyntax-only" local-file)))) (push '("\\.cpp$" flymake-cc-init) flymake-allowed-file-name-masks) (add-hook 'c++-mode-hook '(lambda () (flymake-mode t)))
これも同様にg++-4の実行権限を追加しておいてください。
flymake自体はemacsに含まれているのでauto-installとかはしなくても大丈夫です。
smart-compileで簡単コンパイル
ある程度の規模のプロジェクトであればちゃんとしたMakefileとかを作ると思うので
M-x compile
でコンパイルできるのですが、ちょっとしたテストコードとかだとこうはいかないので、わざわざ端末から
g++ hoge.cpp -o hoge & ./hoge
見たいな事をしなきゃいけません。
これを一発でやりたいなというのをかなえてくれるのがsmart-compile.elです。
インストールは以下です。
auto-install-from-emacswiki smart-compile.el
そして以下を.emacsに追加します。
;; smart-compile (require 'smart-compile) (setq smart-compile-alist '( (emacs-lisp-mode . (emacs-lisp-byte-compile)) (html-mode . (browse-url-of-buffer)) (nxhtml-mode . (browse-url-of-buffer)) (html-helper-mode . (browse-url-of-buffer)) (octave-mode . (run-octave)) ("\\.c\\'" . "gcc -O2 %f -lm -o %n") ;; ("\\.c\\'" . "gcc -O2 %f -lm -o %n && ./%n") ("\\.[Cc]+[Pp]*\\'" . "g++-4 -O2 %f -lm -o %n && %n.exe") ;; ("\\.[Cc]+[Pp]*\\'" . "g++ -O2 %f -lm -o %n") ("\\.m\\'" . "gcc -O2 %f -lobjc -lpthread -o %n") ("\\.java\\'" . "javac %f") ("\\.php\\'" . "php -l %f") ("\\.f90\\'" . "gfortran %f -o %n") ("\\.[Ff]\\'" . "gfortran %f -o %n") ("\\.cron\\(tab\\)?\\'" . "crontab %f") ("\\.tex\\'" . (tex-file)) ("\\.texi\\'" . "makeinfo %f") ("\\.mp\\'" . "mptopdf %f") ("\\.pl\\'" . "perl -cw %f") ("\\.rb\\'" . "ruby -cw %f"))) (global-set-key (kbd "C-x C-x") 'smart-compile)
こうしておくとC-x C-xと入力することでコンパイルと実行が出来ます。
デバッガにかけたいときとかはC-x C-xのあとにミニバッファに表示されるコマンドをいじくってやればよいでしょう。
GDBでデバッグ
デバッガなしで開発をするっていうのは、結構厳しいものがあると思います。
参考URL
http://d.hatena.ne.jp/higepon/20090505/p1
higepon先生の設定をまるパクリさせてもらえば良いと思います。
;;; GDB 関連 ;;; 有用なバッファを開くモード (setq gdb-many-windows t) ;;; 変数の上にマウスカーソルを置くと値を表示 (add-hook 'gdb-mode-hook '(lambda () (gud-tooltip-mode t))) ;;; I/O バッファを表示 (setq gdb-use-separate-io-buffer t) ;;; t にすると mini buffer に値が表示される (setq gud-tooltip-echo-area nil)
まとめ
ここまでやるとそれなりには、"VisualStudioっぽい"感じというか、IDEでよくある機能をEmacsでも実現できると思います。
何点か微妙な部分もありますが、僕はおおむね満足しています。
意図的に扱わなかった内容として、
- プロジェクト管理とプロジェクト内検索
- リファクタリングツール
があります。
プロジェクト管理はeproject.elとか使えばよさそうだったのですが、プロジェクト内検索をうまくやる方法が良く分からなかったので扱いませんでした。
(anything-project.elがよさそうだったのですが、ackに依存していて、Windowsのコマンドプロンプトからうまくackを呼べなかったので使えませんでした。)
とりあえずは、moccur-grep-findとか使えばいいとおもいます。
リファクタリングツールは、そもそもフリーのものが見つけられなかったので扱いませんでした。