質問

I use php-mode in Emacs, it work fine execept when I use closures as argument like this:

$app->get('/', function() use ($app) {
        echo "foo";
    });

It seams that when function is inside function invocation the indentation is doubled. How to fix this?

EDIT

How to make it look like this (the same as javascript-mode handle anonymous functions).

$app->get('/', function() use ($app) {
    echo "foo";
});
役に立ちましたか?

解決 2

With help from @amalloy I manage to create this fix that solve the problem:

(defun unident-closure ()
  (let ((syntax (mapcar 'car c-syntactic-context)))
    (if (and (member 'arglist-cont-nonempty syntax)
             (or
              (member 'statement-block-intro syntax)
              (member 'block-close syntax)))
        (save-excursion
          (beginning-of-line)
          (delete-char c-basic-offset)))))

(add-hook 'php-mode-hook (lambda ()
                           (add-hook 'c-special-indent-hook 'unident-closure))

not sure If it need to be in php-mode-hook or not

Great help was C-c C-s that show what will be in c-syntactic-context variable when c-special-indent-hook is fired (and it's after indent was done).

CC-Mode Manual also help

UPDATE

I found this code that is invalid

array('tags' => array_map($rows,function($row) {
....    return array(
....        'name' => $row['name'],
....        'size' => $normalize($row['tag_count']);
....    );
....});

(dots are the spaces that need to be removed)

and another one

return array('tags' =>
             array_map($rows, function($row) use ($normalize) {
             ....    return array(
             ....        'name' => $row['name'],
             ....        'size' => $normalize($row['tag_count']);
             ....    );
             ....});

so I need to modify the function, C-c C-s shows that arglist-cont-nonempty appear twice (each additional arglist-cont-nonempty add more indent that need to be removed)

(defun unident-closure ()
  (let ((syntax (mapcar 'car c-syntactic-context)))
    (if (and (member 'arglist-cont-nonempty syntax)
             (or
              (member 'statement-block-intro syntax)
              (member 'brace-list-intro syntax)
              (member 'brace-list-close syntax)
              (member 'block-close syntax)))
        (save-excursion
          (beginning-of-line)
          (delete-char (* (count 'arglist-cont-nonempty syntax)
                          c-basic-offset))))))

他のヒント

If you put point at the end of the first line and press C-c C-o, you can see what syntactic construct cc-mode thinks you're in the middle of, and customize how it indents that construct. I don't have php-mode on my current computer, but I think setting this to zero worked reasonably well back when I was doing PHP.

I tried the code in jcubic's answer and it no longer workers. Based on amalloy's helpful answer, I've modified jcubic's workaround to the following, which works.

(defun unident-closure ()
  (let ((syntax (mapcar 'car c-syntactic-context)))
    (if (and (member 'arglist-cont-nonempty syntax)
             (or
              (member 'statement-block-intro syntax)
              (member 'brace-list-intro syntax)
              (member 'brace-list-close syntax)
              (member 'block-close syntax)
              (member 'defun-block-intro syntax)
              (member 'defun-close syntax)))
        (save-excursion
          (beginning-of-line)
          (delete-char (* (count 'arglist-cont-nonempty syntax)
                          c-basic-offset))))))
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top