branch: elpa/php-mode
commit 68faa1cfe9dd7742efac462eda85f63b94478d43
Author: USAMI Kenta <[email protected]>
Commit: USAMI Kenta <[email protected]>

    Fix error-control operator "@" fontification on Emacs 31+
    
    CC Mode >= 31 fontifies a bare `@' as a keyword because `@new' is
    registered in `c-type-list-kwds', so the error-control operator in e.g.
    `@fopen(...)' or `@$a' was highlighted as `php-keyword' rather than
    `php-errorcontrol-op' (the `lang/errorcontrol.php' faces test fails on
    Emacs 31/32).
    
    The previous matcher `\<\(@\)' never matched: `@' has punctuation
    syntax, so a word boundary can never precede it.  Replace it with a
    matcher function that highlights a single `@' as the error-control
    operator, overriding CC Mode's keyword face, while skipping `@' inside
    strings and comments and the `@new' keyword.
---
 lisp/php-mode.el | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/lisp/php-mode.el b/lisp/php-mode.el
index c844f93db4..07dd4ee411 100644
--- a/lisp/php-mode.el
+++ b/lisp/php-mode.el
@@ -1516,7 +1516,7 @@ for \\[find-tag] (which see)."
    ;;   already fontified by another pattern. Note that using OVERRIDE
    ;;   is usually overkill.
    `(
-     ("\\<\\(@\\)" 1 'php-errorcontrol-op)
+     (php-mode--error-control-op-font-lock-find 0 'php-errorcontrol-op t)
      ;; import function statement
      (,(rx symbol-start (group "use" (+ (syntax whitespace)) "function")
            (+ (syntax whitespace)))
@@ -1618,6 +1618,24 @@ The output will appear in the buffer *PHP*."
 (defconst php-string-interpolated-variable-regexp
   "{\\$[^}\n\\\\]*\\(?:\\\\.[^}\n\\\\]*\\)*}\\|\\${\\sw+}\\|\\$\\sw+")
 
+(defun php-mode--error-control-op-font-lock-find (limit)
+  "Font-lock matcher for the error-control operator `@' up to LIMIT.
+
+Match a single `@' that is used as the error-control operator, skipping
+occurrences inside strings or comments and the `@new' keyword (which CC
+Mode fontifies as a keyword).  CC Mode >= 31 fontifies a bare `@' as a
+keyword because `@new' is registered in `c-type-list-kwds', so this
+matcher is set to override that face."
+  (let (found)
+    (while (and (not found)
+                (re-search-forward "@" limit t))
+      (unless (or (php-in-string-or-comment-p)
+                  (save-excursion
+                    (goto-char (match-beginning 0))
+                    (looking-at-p "@new\\_>")))
+        (setq found t)))
+    found))
+
 (defun php-mode--string-interpolated-variable-font-lock-find (limit)
   "Apply text-property to LIMIT for string interpolation by font-lock."
   (let (quoted-stuff)

Reply via email to