Search code examples
phpemacsindentationphp-mode

how to fix php-mode indenting when using closures


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";
});

Solution

  • 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))))))