branch: elpa/php-mode
commit 86e788eeeab57e0576fad9ec9ea1fab0c236efb7
Merge: e175393855 c439aac957
Author: USAMI Kenta <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #809 from emacs-php/fix/support-emacs32
Support Emacs HEAD(32)
---
lisp/php-mode.el | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
lisp/php.el | 8 ++---
2 files changed, 100 insertions(+), 13 deletions(-)
diff --git a/lisp/php-mode.el b/lisp/php-mode.el
index afd512946f..490ff7b80f 100644
--- a/lisp/php-mode.el
+++ b/lisp/php-mode.el
@@ -102,7 +102,7 @@
(let ((tag (replace-regexp-in-string
(rx bos "v") ""
(shell-command-to-string "git describe --tags")))
- (pattern (rx (group (+ any)) eol)))
+ (pattern (rx (group (+ nonl)) eol)))
(if (string-match pattern tag)
(match-string 0 tag)
(error "Faild to obtain git tag"))))
@@ -470,6 +470,12 @@ any) is a brace list.
PHP does not have an C-like \"enum\" keyword."
php nil)
+;; cc-mode renamed `c-after-brace-list-decl-kwds' to `c-after-enum-list-kwds';
+;; keep the old name defined so cc-langs' transitional lookup stays quiet where
+;; the rename landed (see `c-after-enum-list-key' in cc-langs.el).
+(c-lang-defconst c-after-brace-list-decl-kwds
+ php nil)
+
(c-lang-defconst c-typeless-decl-kwds
php (append (c-lang-const c-class-decl-kwds php) '("function" "const")))
@@ -675,6 +681,57 @@ a backward search limit."
(cons (point) t))))
(t nil)))
+(defun php-mode--anonymous-function-brace-p (pos)
+ "Return non-nil when the opening brace at POS starts a closure body.
+
+POS must be the position of a `{'. A closure is an anonymous
+`function (...) [use (...)] [: type] {' expression; named function
+declarations and other constructs (e.g. `match', `if') return nil."
+ (save-excursion
+ (goto-char pos)
+ (c-backward-syntactic-ws)
+ ;; Step back over an optional return type declaration `): Type {' so
+ ;; that point lands just after the parameter (or `use') list's `)'.
+ (unless (eq (char-before) ?\))
+ (let ((colon (save-excursion
+ (skip-chars-backward "^):;{}(" (point-min))
+ (and (eq (char-before) ?:) (1- (point))))))
+ (when colon
+ (goto-char colon)
+ (c-backward-syntactic-ws))))
+ ;; Walk backwards over the `)...(' list(s): the parameter list, plus an
+ ;; optional `use (...)' clause, until we reach `function' or give up.
+ (let ((result nil) (continue t))
+ (while (and continue (eq (char-before) ?\)))
+ (condition-case nil
+ (backward-list)
+ (error (setq continue nil)))
+ (when continue
+ (c-backward-syntactic-ws)
+ (if (zerop (c-backward-token-2))
+ (cond
+ ((looking-at-p "\\_<function\\_>") (setq result t continue nil))
+ ((looking-at-p "\\_<use\\_>") (c-backward-syntactic-ws))
+ (t (setq continue nil)))
+ (setq continue nil))))
+ result)))
+
+(defun php-c-looking-at-statement-block (orig-fun &rest args)
+ "Treat a closure body as a statement block around
`c-looking-at-statement-block'.
+
+Emacs' CC Mode >= 31 (the change for bug#19867) fails to recognize an
+anonymous function body whose first line is a comment as a statement
+block, and reports it as a brace list, mis-indenting both the body and
+its closing brace. When point is at the opening brace of such a closure,
+return non-nil; otherwise fall back to ORIG-FUN with ARGS.
+
+A closure body is always a statement block, so this is also correct on
+Emacs versions unaffected by the bug."
+ (or (and (derived-mode-p 'php-mode)
+ (eq (char-after) ?\{)
+ (php-mode--anonymous-function-brace-p (point)))
+ (apply orig-fun args)))
+
(c-add-style
"php"
`((c-basic-offset . 4)
@@ -1179,13 +1236,19 @@ After setting the stylevars run hook
`php-mode-STYLENAME-hook'."
(setq-local comment-end "")
(setq-local page-delimiter php-mode-page-delimiter)
- (setq-local font-lock-string-face 'php-string)
- (setq-local font-lock-keyword-face 'php-keyword)
- (setq-local font-lock-builtin-face 'php-builtin)
- (setq-local c-preprocessor-face-name 'php-php-tag)
- (setq-local font-lock-function-name-face 'php-function-name)
- (setq-local font-lock-variable-name-face 'php-variable-name)
- (setq-local font-lock-constant-face 'php-constant)
+ (with-suppressed-warnings ((obsolete font-lock-string-face
+ font-lock-keyword-face
+ font-lock-builtin-face
+ font-lock-function-name-face
+ font-lock-variable-name-face
+ font-lock-constant-face))
+ (setq-local font-lock-string-face 'php-string)
+ (setq-local font-lock-keyword-face 'php-keyword)
+ (setq-local font-lock-builtin-face 'php-builtin)
+ (setq-local c-preprocessor-face-name 'php-php-tag)
+ (setq-local font-lock-function-name-face 'php-function-name)
+ (setq-local font-lock-variable-name-face 'php-variable-name)
+ (setq-local font-lock-constant-face 'php-constant))
(setq-local syntax-propertize-function #'php-syntax-propertize-function)
(add-hook 'syntax-propertize-extend-region-functions
@@ -1244,6 +1307,9 @@ After setting the stylevars run hook
`php-mode-STYLENAME-hook'."
(advice-add 'c-looking-at-or-maybe-in-bracelist
:around 'php-c-looking-at-or-maybe-in-bracelist)
+ (when (fboundp 'c-looking-at-statement-block)
+ (advice-add 'c-looking-at-statement-block
+ :around 'php-c-looking-at-statement-block))
(advice-add 'fixup-whitespace :after #'php-mode--fixup-whitespace-after)
(advice-add 'acm-backend-tabnine-candidate-expand
@@ -1450,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)))
@@ -1552,6 +1618,27 @@ 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))
+ ;; `php-in-string-or-comment-p' calls `syntax-ppss', which may run
+ ;; `syntax-propertize' and clobber the match data, so guard it to
+ ;; keep the `@' match for both the `@new' check below and font-lock.
+ (unless (or (save-match-data (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)
diff --git a/lisp/php.el b/lisp/php.el
index ef46272c75..3124ced08b 100644
--- a/lisp/php.el
+++ b/lisp/php.el
@@ -327,7 +327,7 @@ which will be the name of the method."
(* (syntax whitespace))
"("
,@(when include-args
- '((* any) line-end))))))
+ '((* nonl) line-end))))))
(defun php-create-regexp-for-classlike (type)
"Accepts a `TYPE' of a `classlike' object as a string, such as
@@ -378,7 +378,7 @@ can be used to match against definitions for that
classlike."
(+ (or (syntax word) (syntax symbol)))
(* (syntax whitespace))
(? "=" (* (syntax whitespace))
- (repeat 0 40 any))))
+ (repeat 0 40 nonl))))
1)
("Functions"
,(rx line-start
@@ -389,7 +389,7 @@ can be used to match against definitions for that
classlike."
(+ (or (syntax word) (syntax symbol)))
(* (syntax whitespace))
"("
- (repeat 0 100 any)))
+ (repeat 0 100 nonl)))
1)
("Import"
,(rx line-start
@@ -397,7 +397,7 @@ can be used to match against definitions for that
classlike."
(group
"use"
(+ (syntax whitespace))
- (repeat 0 100 any)))
+ (repeat 0 100 nonl)))
1)
("Classes"
,(php-create-regexp-for-classlike
"\\(?:class\\|interface\\|trait\\|enum\\)") 0)