php-mode icon indicating copy to clipboard operation
php-mode copied to clipboard

Indentation issue after a try/catch with no semicolon

Open braoult opened this issue 6 years ago • 6 comments

Maybe my php-mode setup is incorrect, but I have an indentation issue after a try/catch, if there is no semicolon after the catch(){};

Example:

try {
  a();
}
catch (Exception $e) {
  b();
};                                                // semicolon here

$zobi = "a"
      . "b";                                      // indent OK

try {
  a();
}
catch (Exception $e) {
  b();
} // no semicolon here. This comment indentation is NOK

$zobi = "a"
  . "b";                                          // indent NOK

$zobi = "a"
      . "b";                                      // indent OK again

braoult avatar Jun 19 '19 07:06 braoult

If fact, the issue appears also with simple if(){} structure, if no semicolon at end:

$xxx = "a"
     . "b";                                       // correct indent

if (foo()) {
  bar();
};                                                // semicolon

$xxx = "a"
     . "b";                                       // correct indent

if (foo()) {
  bar();
} // no semicolon: comment indent incorrect

$xxx = "a"
  . "b";                                          // incorrect indent

$xxx = "a"
     . "b";                                       // correct indent

braoult avatar Jun 19 '19 09:06 braoult

@braoult Can you provide us output of M-x php-mode-debug?

zonuexe avatar Jun 19 '19 12:06 zonuexe

Here it is:

Feel free to report on GitHub what you noticed! https://github.com/emacs-php/php-mode/issues/new

Pasting the following information on the issue will help us to investigate the cause.

--- PHP-MODE DEBUG BEGIN ---
versions: GNU Emacs 26.1 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.7)
 of 2019-04-11, modified by Debian; PHP Mode 1.21.4 of 2019-05-29
package-version: 20190530.1910
major-mode: php-mode
minor-modes: (auto-complete-mode show-smartparens-mode smartparens-mode undo-tree-mode helm-mode yas-minor-mode delete-selection-mode icomplete-mode diff-auto-refine-mode magit-auto-revert-mode async-bytecomp-package-mode shell-dirtrack-mode projectile-mode tooltip-mode electric-indent-mode mouse-wheel-mode menu-bar-mode file-name-shadow-mode font-lock-mode blink-cursor-mode auto-composition-mode auto-encryption-mode auto-compression-mode column-number-mode line-number-mode transient-mark-mode auto-fill-mode abbrev-mode hs-minor-mode)
variables: ((indent-tabs-mode nil) (tab-width 8))
custom variables: ((php-executable /usr/bin/php) (php-site-url https://php.net/) (php-manual-url en) (php-search-url nil) (php-class-suffix-when-insert ::) (php-namespace-suffix-when-insert \) (php-default-major-mode php-mode) (php-html-template-major-mode web-mode) (php-blade-template-major-mode web-mode) (php-template-mode-alist ((\.blade . web-mode) (\.phpt\' . php-mode) (\.phtml\' . web-mode))) (php-mode-maybe-hook nil) (php-search-documentation-browser-function nil))
c-indentation-style: php
c-style-variables: ((c-basic-offset 2) (c-comment-only-line-offset 0) (c-indent-comment-alist ((anchored-comment column . 0) (end-block space . 1) (cpp-end-block space . 2))) (c-indent-comments-syntactically-p nil) (c-block-comment-prefix * ) (c-comment-prefix-regexp ((pike-mode . //+!?\|\**) (awk-mode . #+) (other . //+\|\**))) (c-cleanup-list (scope-operator)) (c-hanging-braces-alist ((brace-list-open) (brace-entry-open) (statement-cont) (substatement-open after) (block-close . c-snug-do-while) (extern-lang-open after) (namespace-open after) (module-open after) (composition-open after) (inexpr-class-open after) (inexpr-class-close before) (arglist-cont-nonempty))) (c-hanging-colons-alist nil) (c-hanging-semi&comma-criteria (c-semi&comma-inside-parenlist)) (c-backslash-column 48) (c-backslash-max-column 72) (c-special-indent-hook nil) (c-label-minimum-indentation 1))
c-doc-comment-style: ((java-mode . javadoc) (pike-mode . autodoc) (c-mode . gtkdoc))
c-offsets-alist: ((inexpr-class . +) (inexpr-statement . +) (lambda-intro-cont . +) (inlambda . 0) (template-args-cont c-lineup-template-args +) (incomposition . +) (inmodule . +) (innamespace . +) (inextern-lang . +) (composition-close . 0) (module-close . 0) (namespace-close . 0) (extern-lang-close . 0) (composition-open . 0) (module-open . 0) (namespace-open . 0) (extern-lang-open . 0) (objc-method-call-cont c-lineup-ObjC-method-call-colons c-lineup-ObjC-method-call +) (objc-method-args-cont . c-lineup-ObjC-method-args) (objc-method-intro . [0]) (friend . 0) (cpp-define-intro c-lineup-cpp-define +) (cpp-macro-cont . +) (cpp-macro . [0]) (inclass . +) (stream-op . c-lineup-streamop) (arglist-cont-nonempty first php-lineup-cascaded-calls c-lineup-arglist) (arglist-cont first php-lineup-cascaded-calls 0) (comment-intro . 0) (catch-clause . 0) (else-clause . 0) (do-while-closure . 0) (access-label . -) (substatement . +) (statement-case-intro . +) (statement . 0) (brace-entry-open . 0) (brace-list-entry . c-lineup-under-anchor) (brace-list-close . 0) (block-close . 0) (block-open . 0) (inher-cont . c-lineup-multi-inher) (inher-intro . +) (member-init-cont . c-lineup-multi-inher) (member-init-intro . +) (annotation-var-cont . +) (annotation-top-cont . 0) (topmost-intro . 0) (knr-argdecl . 0) (func-decl-cont . +) (inline-close . 0) (class-close . 0) (class-open . 0) (defun-block-intro . +) (defun-close . 0) (defun-open . 0) (c . c-lineup-C-comments) (string . c-lineup-dont-change) (topmost-intro-cont first php-lineup-cascaded-calls +) (brace-list-intro . +) (brace-list-open . 0) (inline-open . 0) (arglist-close . php-lineup-arglist-close) (arglist-intro . php-lineup-arglist-intro) (statement-cont first php-lineup-cascaded-calls php-lineup-string-cont +) (statement-case-open . 0) (label . +) (substatement-label . 2) (substatement-open . 0) (knr-argdecl-intro . +) (statement-block-intro . +) (case-label . +))
--- PHP-MODE DEBUG END ---

Thank you!

braoult avatar Jun 19 '19 12:06 braoult

@braoult OK, I was able to reproduce your problem.

zonuexe avatar Jun 19 '19 12:06 zonuexe

I understood the cause: the needle is somewhere in this less than 10,000 lines of code 🙃

https://github.com/emacs-mirror/emacs/blob/emacs-26.2/lisp/progmodes/cc-engine.el#L696-L13099

zonuexe avatar Jun 19 '19 14:06 zonuexe

Note

Output debugging information from php-lineup-string-cont.

@@ -888,6 +888,7 @@ e.g.
 $str = 'some'
      . 'string';
 this ^ lineup"
+  (message "%s" langelem)
   (save-excursion
     (goto-char (cdr langelem))
     (let (ret finish)

This problem is reproduced by the following code:

<?php

if (true) {
}

$foo = ""
    . "";

If you indent before ., the following message is output:

(statement-cont . 8)

8 refers to the position where the syntax element starts. It is before if.

As @braoult points out, ; corrects the analysis.

<?php

if (true) {
};

$foo = ""
     . "";
(statement-cont . 24)

The 24 in this code points to before $ foo. That's right.

Given the complex syntax, the CCMode mechanism can not derive the correct position from the wrong report.

zonuexe avatar Jun 19 '19 16:06 zonuexe

Maybe this issue has already been resolved. If you have the same problem, feel free to open it again.

zonuexe avatar Oct 27 '22 16:10 zonuexe

This issue is not resolved, as of today: Emacs 28.1 nativecomp, and php-mode 20221027.1651 (melpa).

I let you decide if we should re-open this issue. Or maybe could we mark it differently - like having a workaround (adding semicolons) ?

braoult avatar Oct 28 '22 10:10 braoult