Indentation issue after a try/catch with no semicolon
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
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 Can you provide us output of M-x php-mode-debug?
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 OK, I was able to reproduce your problem.
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
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.
Maybe this issue has already been resolved. If you have the same problem, feel free to open it again.
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) ?