Emacsでインデントとスペースをいいかんじに(align-regexp, my-set-indent-tabs-mode)
githubをうろうろしていたらmoriyamahiroshiさんの.emacsに出会いました。
とても勉強になる内容だったのですが、そのなかに、(my-set-indent-tabs-mode)
というものがあり、これを使うと、いいかんじにバッファ先頭のインデントを見て、バッファごとにインデントスタイルを設定できるようでした。
これで、インデントスタイルはメジャーモードごとに決まっていることが多い片方で、フレームワークごとにコーディング規約があったりして、悩ましかったのですが、これは空気を読んでくれるので、なかなかいいかんじでした。
関係部分だけ以下に抜きださせていただきます。
(if (not (fboundp 'defun-if-undefined)) (defmacro defun-if-undefined (name &rest rest) `(unless (fboundp (quote ,name)) (defun ,name ,@rest)))) (defun-if-undefined inside-string-or-comment-p () (let ((state (parse-partial-sexp (point-min) (point)))) (or (nth 3 state) (nth 4 state)))) (defun-if-undefined re-search-forward-without-string-and-comments (&rest args) (let ((value (apply #'re-search-forward args))) (if (and value (inside-string-or-comment-p)) (apply #'re-search-forward-without-string-and-comments args) value))) (defun my-buffer-indent-tabs-code-p (&optional buffer) "Check first indent char." (let ((buffer (or buffer (current-buffer)))) (with-current-buffer buffer (save-excursion (save-restriction (widen) (goto-char (point-min)) (and (re-search-forward-without-string-and-comments "^[ \t]" (point-max) t) (string= (match-string 0) "\t"))))))) (defun my-set-indent-tabs-mode () (setq indent-tabs-mode (my-buffer-indent-tabs-code-p))) (add-hook 'emacs-lisp-mode-hook #'my-set-indent-tabs-mode) (add-hook 'java-mode-hook #'my-set-indent-tabs-mode) (add-hook 'html-mode-hook #'my-set-indent-tabs-mode) (add-hook 'perl-mode-hook #'my-set-indent-tabs-mode) (add-hook 'python-mode-hook #'my-set-indent-tabs-mode) (add-hook 'ruby-mode-hook #'my-set-indent-tabs-mode) (add-hook 'sh-mode-hook #'my-set-indent-tabs-mode)
以下は、ついでに僕の設定です。
(add-hook 'php-mode-hook '(lambda() (setq tab-width 2) (setq c-basic-offset 2) (my-set-indent-tabs-mode)))
align-regexp
Emacsのalign-regexp
は、たいへん便利で、
$scfldpath = $scfldbase.'modules/'.$name.DS; $migrationpath = $scfldpath.'migrations/'; $configpath = $scfldpath.'config/'; $viewspath = $scfldpath.'views/'.$name;
こんなのを
M-x align-regexp RET = RET
で、一瞬でこんなのしてくれます。
$scfldpath = $scfldbase.'modules/'.$name.DS; $migrationpath = $scfldpath.'migrations/'; $configpath = $scfldpath.'config/'; $viewspath = $scfldpath.'views/'.$name;
で、ちょっと悩ましいのが、fuelphpのコーディング規約みたいなやつ。
すべてのインデントはスペースではなくタブを使用すべきです。
しかし、インデント後の整形はタブではなくスペースを使用します。
Emacsのalign-regexpとしては、indent-tabs-modeの値を見て、インデント後の整形も行うので、indent-tabs-modeがtなら、インデント後の整形も
$scfldpath = $scfldbase.'modules/'.$name.DS; $migrationpath = $scfldpath.'migrations/'; $configpath = $scfldpath.'config/'; $viewspath = $scfldpath.'views/'.$name;
となっちゃうので、fuelphpのコーディング規約から外れちゃう。これをうまいこと解決するのが、以下のadviceです。
(defadvice align-regexp (around advise-align-regexp activate) "Let align-regexp indent by spaces." (when indent-tabs-mode (setq indent-tabs-mode nil)) ad-do-it (my-set-indent-tabs-mode))
moriyamahiroshiさんの(my-set-indent-tabs-mode)が空気も読んでくれるので、快適です。
ちなみにphpでalign-regexpするには、てつじんにっきさんの「[php][Emacs] Emacsのphp-modeでalignする」の設定も必要です。Emacs24でもいけます。
ジャンル: Emacs