3

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";
});
jcubic
  • 61,973
  • 54
  • 229
  • 402
  • Doesn't that make sense? It seems to indent 4 spaces for every open parenthesis, be it a round one or a curly one. – Thomas Jul 15 '12 at 02:24
  • It simply should be a way to add somekind of hook that will add 0 indentet to function if it's inside argument and 4 when outside – jcubic Jul 16 '12 at 08:12
  • Could you please edit the question to show what you would like the indentation to be? – Thomas Jul 16 '12 at 08:18
  • Thanks for the EDIT! One more question though, if you don't mind: how should the whole block be indented if you hit ENTER after `'/'`? Or after `function()`? – Thomas Jul 17 '12 at 01:44
  • @Thomas with new line after '/' is fine the same as for javascript mode aligned to '/' (in the same column). – jcubic Jul 18 '12 at 06:39
  • @jcubic what is the version number of `php-mode` you use? – slitvinov Jul 22 '12 at 21:30
  • @slitvinov I try 1.5.0 and 1.6.5 from github. – jcubic Jul 23 '12 at 12:48

3 Answers3

3

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.

amalloy
  • 89,153
  • 8
  • 140
  • 205
  • It's `topmost-intro` and it's already set to 0, but next line is `statement-block-intro` and it's set to `+` can it be 0 if inside `topmost-intro` was before? – jcubic Jul 26 '12 at 10:51
3

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))))))
Community
  • 1
  • 1
jcubic
  • 61,973
  • 54
  • 229
  • 402
0

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))))))
jcubic
  • 61,973
  • 54
  • 229
  • 402
James Dunne
  • 680
  • 6
  • 9
  • 1
    Did you donwload latest version of php-mode, I beleive they fixed the issue. – jcubic Sep 17 '15 at 10:15
  • Yes - still faced the issue. Issue is still open on Github too. I've provided the amended work around (they referenced your answer), hopefully a fix in the mode will be released soon. – James Dunne Sep 17 '15 at 11:02