Skip to content

Commit ec4c166

Browse files
committed
Fix indentation bug when using implements/extends
Correct indentation and highlighting of lines below a <?php is tricky because that construct is inherently not c-like syntax. Summary of the solution applied in this php-mode: * recognize opening tags as preprocessor macros using c-opt-cpp-*, this fixes indentation of lines below * use additional regexp in f-l-keywords to also highlight possible closing tag (common in PEAR style code) * use regexp to work around highlighting glitch, instead of using c-type-prefix-kwds because that opens up range of other problems Added more inline documentation about the custom font-lock expressions and the handling of open tags.
1 parent 0cd7b00 commit ec4c166

File tree

1 file changed

+50
-28
lines changed

1 file changed

+50
-28
lines changed

php-mode.el

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,16 @@ This variable can take one of the following symbol values:
414414
(c-lang-defconst c-vsemi-status-unknown-p-fn
415415
php 'php-c-vsemi-status-unknown-p)
416416

417+
;; Make php-mode recognize opening tags as preprocessor macro's.
418+
;;
419+
;; This is a workaround, the tags must be recognized as something
420+
;; in order for the syntactic guesses of code below the tag
421+
;; to be correct and as a result not break indentation.
422+
;;
423+
;; Note that submatches or \\| here are not expected by cc-mode.
424+
(c-lang-defconst c-opt-cpp-prefix
425+
php "\\s-*<\\?")
426+
417427
(c-lang-defconst c-identifier-ops
418428
php '(
419429
(left-assoc "\\" "::" "->")
@@ -447,28 +457,13 @@ This variable can take one of the following symbol values:
447457
contains another declaration level that should be considered a class."
448458
php '("class" "trait" "interface"))
449459

450-
;; Why does this need to be set as well?
451-
;; If we don't set it: the first class definition of a file will
452-
;; not get the appropriate face
453-
(c-lang-defconst c-type-prefix-kwds
454-
"Keywords where the following name - if any - is a type name, and
455-
where the keyword together with the symbol works as a type in
456-
declarations."
457-
php '("class" "trait" "interface" "namespace"
458-
"as" "insteadof" "instanceof"))
459-
460460
(c-lang-defconst c-brace-list-decl-kwds
461461
"Keywords introducing declarations where the following block (if
462462
any) is a brace list.
463463
464464
PHP does not have an \"enum\"-like keyword."
465465
php nil)
466466

467-
(c-lang-defconst c-other-block-decl-kwds
468-
"Keywords where the following block (if any) contains another
469-
declaration level that should not be considered a class."
470-
php '("namespace"))
471-
472467
(c-lang-defconst c-typeless-decl-kwds
473468
php (append (c-lang-const c-class-decl-kwds) '("function")))
474469

@@ -481,15 +476,13 @@ declaration level that should not be considered a class."
481476
php '("private" "protected" "public"))
482477

483478
(c-lang-defconst c-postfix-decl-spec-kwds
484-
php (append (remove "throws" (c-lang-const c-postfix-decl-spec-kwds))
485-
'("extends" "implements")))
479+
php '("implements" "extends"))
486480

487481
(c-lang-defconst c-type-list-kwds
488-
php (append (remove "import" (c-lang-const c-type-list-kwds))
489-
'("use")))
482+
php '("new" "use" "implements" "extends"))
490483

491484
(c-lang-defconst c-ref-list-kwds
492-
php nil)
485+
php '("namespace"))
493486

494487
(c-lang-defconst c-block-stmt-2-kwds
495488
php (append '("elseif" "foreach" "declare")
@@ -1306,14 +1299,43 @@ a completion list."
13061299
"Medium level highlighting for PHP mode.")
13071300

13081301
(defconst php-font-lock-keywords-3 (append
1309-
`(
1310-
("\\(\\$\\|->\\)\\([a-zA-Z0-9_]+\\)" 2 font-lock-variable-name-face)
1311-
("\\<\\([A-Z0-9_]\\{2,\\}\\)\\>" 1 font-lock-constant-face)
1312-
("\\(\\sw+\\)::" 1 font-lock-constant-face)
1313-
("\\sw+::\\(class\\)" 1 font-lock-constant-face)
1314-
(,(regexp-opt '("<?php" "?>" "<?" "<?=" "<%" "%>")) 0 font-lock-preprocessor-face)
1315-
("(\\(array\\))" 1 font-lock-type-face)) ;; array is a keyword, except when used as cast
1316-
(c-lang-const c-matchers-3 php))
1302+
`(
1303+
;; Highlight variables, e.g. 'var' in '$var' and '$obj->var'
1304+
("\\(\\$\\|->\\)\\([a-zA-Z0-9_]+\\)" 2 font-lock-variable-name-face)
1305+
1306+
;; Highlight all upper-cased symbols as constant
1307+
("\\<\\([A-Z0-9_]\\{2,\\}\\)\\>" 1 font-lock-constant-face)
1308+
1309+
;; Highlight all statically accessed class names as constant,
1310+
;; another valid option would be using type-face, but using constant-face
1311+
;; because this is how it works in c++-mode.
1312+
("\\(\\sw+\\)::" 1 font-lock-constant-face)
1313+
1314+
;; Support the ::class constant in PHP5.6
1315+
("\\sw+::\\(class\\)" 1 font-lock-constant-face)
1316+
1317+
;; Array is a keyword, except when used as cast, so that (int) and (array)
1318+
;; look the same
1319+
("(\\(array\\))" 1 font-lock-type-face)
1320+
1321+
;; Class names are highlighted by cc-mode as defined in c-class-decl-kwds,
1322+
;; below regexp is a workaround for a bug where the class names are not
1323+
;; highlighted right after opening a buffer (editing a file corrects it).
1324+
;;
1325+
;; This behaviour is caused by the preceding '<?php', which cc-mode cannot
1326+
;; handle easily. Registering it as a cpp preprocessor works well (i.e. the
1327+
;; next line is not a statement-cont) but the highlighting glitch remains.
1328+
(,(concat (regexp-opt (c-lang-const c-class-decl-kwds php))
1329+
" \\(\\sw+\\)")
1330+
1 font-lock-type-face)
1331+
1332+
;; While c-opt-cpp-* highlights the <?php opening tags, it is not possible
1333+
;; to make it highlight short open tags and closing tags as well. So we force
1334+
;; the correct face on all cases that c-opt-cpp-* lacks for this purpose.
1335+
;; Note that starting a file with <% breaks indentation, a limitation we
1336+
;; can/should live with.
1337+
(,(regexp-opt '("?>" "<?" "<%" "%>")) 0 font-lock-preprocessor-face))
1338+
(c-lang-const c-matchers-3 php))
13171339
"Detailed highlighting for PHP mode.")
13181340

13191341
(defvar php-font-lock-keywords php-font-lock-keywords-3

0 commit comments

Comments
 (0)