Goに移るかとおもいきや、普段はC++を書くこと多いです。 C++を書いていると、しょっちゅうインクルードガードを書くことになります。 今日はインクルードガードを簡単にするemacs lispを紹介。
「#pragma onceは甘え」「あれは実はダメ」とかあって、結局#ifdefに落ち着くのですが、#defineする変数名はどうしてますか? ソースディレクトリからのフルパスを使うというのをJubatus含めて、以前は使っていたのですが、pepshisoさんに「ソースの位置が変わると全部書き直しなので、uuidの方がよい」という、至極もっともな指摘をされました。 毎回uuidを手で入力すると日が暮れてしまいそうになるので、emacs lispを作りました。 大変便利です。
それはそうと、emacs lispはライブラリが本当に大変使いにくくて、発狂しそうになりますね。 外部コマンドに全部書いて、それを呼べばいい気がしてきました・・・。
(defun replace-regexp-case-ignore (pat replace str)
(let ((def-case case-fold-search))
(setq case-fold-search nil)
(let ((res (replace-regexp-in-string pat replace str)))
(setq case-fold-search def-case)
res)))
(defun make-capital-var (s)
(setq case-fold-search nil)
(concat
(upcase
(replace-regexp-case-ignore
"[_\\.]" "_"
(replace-regexp-case-ignore "\\([a-z]\\)\\([A-Z]\\)" "\\1_\\2" s)))
"_"))
(defun insert-include (f)
(interactive "b")
(let* ((uuid (shell-command-to-string "uuidgen"))
(no_new_line (replace-regexp-in-string "\n" "" uuid))
(id (replace-regexp-in-string "-" "_" no_new_line))
(var (make-capital-var (concat f "_" id))))
(save-excursion
(beginning-of-buffer)
(insert (concat "#ifndef " var "\n"))
(insert (concat "#define " var "\n")))
(save-excursion
(end-of-buffer)
(insert (concat "#endif // " var "\n")))))
私は、これを"C-c C-i"に割り当てて使っています。
(add-hook 'c++-mode-hook (lambda () (local-set-key (kbd "C-c C-i") 'insert-include)))
0 件のコメント:
コメントを投稿