diff --git a/lisp/php-face.el b/lisp/php-face.el index 15395fb2..85aa38dd 100644 --- a/lisp/php-face.el +++ b/lisp/php-face.el @@ -126,6 +126,11 @@ "PHP Mode face used to object operators (->)." :tag "PHP Object Op") +(defface php-pipe-op '((t (:inherit php-operator))) + "PHP Mode face used to the pipe operator (|>). +The operator was added in PHP 8.5." + :tag "PHP Pipe Op") + (defface php-paamayim-nekudotayim '((t ())) "PHP Mode face used to highlight scope resolution operators (::). The operator is also knows as \"Paamayim Nekudotayim\"." diff --git a/lisp/php-mode.el b/lisp/php-mode.el index 4b050d24..4fd23b29 100644 --- a/lisp/php-mode.el +++ b/lisp/php-mode.el @@ -1518,6 +1518,11 @@ for \\[find-tag] (which see)." ;; Assignment operators (=, +=, ...) ("\\([^=]+?\\([\-+./%]?=\\)[^=) --- PHP 8.5. Must precede the comparison + ;; operators, whose `[<>]=?' alternative would otherwise claim the + ;; `>' and leave the `|' unfontified. + ("\\(|>\\)" 1 'php-pipe-op) + ;; Comparison operators (==, ===, >=, ...) ("\\([!=]=\\{1,2\\}[>]?\\|[<>]=?\\)" 1 'php-comparison-op) diff --git a/tests/php-mode-test.el b/tests/php-mode-test.el index 09a33754..1d5ef11f 100644 --- a/tests/php-mode-test.el +++ b/tests/php-mode-test.el @@ -803,6 +803,36 @@ path; sending those to an HTML mode would take most PHP files away from "Test highlighting language constructs added in PHP 8.4." (with-php-mode-test ("8.4/property-hooks.php" :faces t))) +(defun php-mode-test--faces-of (code token) + "Return the list of faces on TOKEN's characters after fontifying CODE." + (with-temp-buffer + (insert code) + (php-mode) + (font-lock-ensure) + (goto-char (point-min)) + (should (search-forward token nil t)) + (let ((start (- (point) (length token)))) + (mapcar (lambda (i) (get-text-property (+ start i) 'face)) + (number-sequence 0 (1- (length token))))))) + +(ert-deftest php-mode-test-php85-pipe-op () + "The PHP 8.5 pipe operator is fontified as `php-pipe-op'. + +Both characters must get the face. The comparison-operator matcher +claims a bare `>', so without a rule of its own `|>' came out +half-fontified: the `|' plain and the `>' as `php-comparison-op'." + (should (equal '(php-pipe-op php-pipe-op) + (php-mode-test--faces-of " trim(...);\n" "|>"))) + ;; Operators that the new rule must not steal from. + (dolist (probe '(("= $c;\n" ">=" (php-comparison-op php-comparison-op)) + (" $c;\n" ">" (php-comparison-op)) + (" $c;\n" "<=>" (php-comparison-op php-comparison-op php-comparison-op)) + ("