php-modeのインデント設定

Eclipseをやめてemacsphpのコードを書くようにしたけれども、php-modeの標準(php-mode-force-pear tの時)のインデントがちょっと気に食わない。こういった時にささっとカスタマイズできるのがemacsの利点なんだけど、どこを直せばいいのかよくわからない、というもがemacsの欠点、そして最悪elipsを読めばなんとかなるのが利点で、elispがとっつきにくいのが欠点。

      • -

どういうインデントになって欲しいのか

まず、標準のインデントはこんな感じになる。

<?php

function longLongFunctionName($arg1, $arg2,
                              $arg3, $arg4)
{
}

$tmp = array('key1' => 'val1',
             'key2' => 'val2');

$tmp = array(
             'key1' => 'val1',
             'key2' => 'val2');

switch ($a) {
case 1:
    break;
case 2:
    break;
}

まず、引数リストとか配列定義中に改行があると、括弧の位置に合わせてくれる。これは見た目綺麗だけれども、関数名とかが長くなる傾向が高いコードを書かされている書いているので、結構な確率で一行80文字制限を超えてしまう。

それと、switch-caseは他の言語ではこれでいいんだけど、phpのときはcaseもインデントしてほしい。規約的に。

ということで、望むインデントはこう。

<?php

function longLongFunctionName($arg1, $arg2,
    $arg3, $arg4)
{
}

$tmp = array('key1' => 'val1',
    'key2' => 'val2');

$tmp = array(
    'key1' => 'val1',
    'key2' => 'val2');

switch ($a) {
    case 1:
        break;
    case 2:
        break;
}

どうやってカスタマイズするか

php-modeのソースを見ると、php-mode-pear-hookでc-set-offsetを使ってなんかやっていそうな感じ。c-set-offsetはc-offsets-alistの値を設定する関数らしい。この辺りはF1 fとかF1 vとかで調べられた。

引数リストとかの改行はいろいろ設定を変えて試したところ、arglist-introとarglist-cont-nonemptyとarglist-closeで対応できそう。caseについては、case-labelに4を設定すればOK。4じゃなくてc-basic-offsetを指定したほうがいいのかもしれないけれども、面倒なので4。他の所も4。

結局こんな感じのelisp.emacs.elとかそれに相当する部分に書いてカスタマイズ完了。すっきり。

(add-hook 'php-mode-hook
          (lambda ()
            (c-set-offset 'case-label' 4)
            (c-set-offset 'arglist-intro' 4)
            (c-set-offset 'arglist-cont-nonempty' 4)
            (c-set-offset 'arglist-close' 0)))