Function: php-ts-mode

php-ts-mode is an autoloaded, interactive and byte-compiled function defined in php-ts-mode.el.gz.

Signature

(php-ts-mode)

Documentation

Major mode for editing PHP, powered by tree-sitter.

In addition to any hooks its parent mode prog-mode might have run, this mode runs the hook php-ts-mode-hook, as the final or penultimate step during initialization.

C-M-q prog-indent-sexp
C-c . php-ts-mode-set-style
C-c C-c php-ts-mode-send-buffer
C-c C-k php-ts-mode-set-comment-style
C-c C-l php-ts-mode-send-file
C-c C-n run-php
C-c C-q php-ts-mode--indent-defun
C-c C-r php-ts-mode-send-region
M-q prog-fill-reindent-defun

Probably introduced at or before Emacs version 30.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/php-ts-mode.el.gz
;;;###autoload
(define-derived-mode php-ts-mode prog-mode "PHP"
  "Major mode for editing PHP, powered by tree-sitter."
  :syntax-table php-ts-mode--syntax-table

  (if (not (and
            (treesit-ready-p 'php)
            (treesit-ready-p 'phpdoc)
            (treesit-ready-p 'html)
            (treesit-ready-p 'javascript)
            (treesit-ready-p 'jsdoc)
            (treesit-ready-p 'css)))
      (error "Tree-sitter for PHP isn't
    available.  You can install the parsers with M-x
    `php-ts-mode-install-parsers'")

    ;; Require html-ts-mode only when we load php-ts-mode
    ;; so that we don't get a tree-sitter compilation warning for
    ;; php-ts-mode.
    (defvar html-ts-mode--indent-rules)
    (require 'html-ts-mode)
    ;; For embed html

    ;; phpdoc is a local parser, don't create a parser for it
    (treesit-parser-create 'html)
    (treesit-parser-create 'css)
    (treesit-parser-create 'javascript)

    ;; define the injected parser ranges
    (setq-local treesit-range-settings
                (treesit-range-rules
                 :embed 'phpdoc
                 :host 'php
                 :local t
                 '(((comment) @cap
                    (:match "/\\*\\*" @cap)))

                 :embed 'html
                 :host 'php
                 '((program (text) @cap)
                   (text_interpolation (text) @cap))

                 :embed 'javascript
                 :host 'html
                 :offset '(1 . -1)
                 '((script_element
                    (start_tag (tag_name))
                    (raw_text) @cap))

                 :embed 'jsdoc
                 :host 'javascript
                 :local t
                 `(((comment) @cap
                    (:match ,js--treesit-jsdoc-beginning-regexp @cap)))

                 :embed 'css
                 :host 'html
                 :offset '(1 . -1)
                 '((style_element
                    (start_tag (tag_name))
                    (raw_text) @cap))))

    (setq-local treesit-language-at-point-function #'php-ts-mode--language-at-point)

    ;; Navigation.
    (setq-local treesit-defun-type-regexp
                (regexp-opt '("class_declaration"
                              "enum_declaration"
                              "function_definition"
                              "interface_declaration"
                              "method_declaration"
                              "namespace_definition"
                              "trait_declaration")))

    (setq-local treesit-defun-name-function #'php-ts-mode--defun-name)

    (setq-local treesit-thing-settings
                `((php
                   (defun ,treesit-defun-type-regexp)
                   (sexp (not ,(rx (or "{" "}" "[" "]" "(" ")" ","))))
                   (sentence  ,(regexp-opt
                                '("break_statement"
                                  "case_statement"
                                  "continue_statement"
                                  "declaration"
                                  "default_statement"
                                  "do_statement"
                                  "expression_statement"
                                  "for_statement"
                                  "if_statement"
                                  "return_statement"
                                  "switch_statement"
                                  "while_statement"
                                  "statement")))
                   (text ,(regexp-opt '("comment" "text"))))))

    ;; Indent.
    (when (eq php-ts-mode-indent-style 'wordpress)
      (setq-local indent-tabs-mode t))

    (setq-local c-ts-common-indent-offset 'php-ts-mode-indent-offset)
    (setq-local treesit-simple-indent-rules (php-ts-mode--get-indent-style))
    (setq-local treesit-simple-indent-rules
                (append treesit-simple-indent-rules
                        php-ts-mode--phpdoc-indent-rules
                        html-ts-mode--indent-rules
                        ;; Extended rules for js and css, to
                        ;; indent appropriately when injected
                        ;; into html
                        `((javascript ((parent-is "program")
                                       php-ts-mode--js-css-tag-bol
                                       php-ts-mode-js-css-indent-offset)
                                      ,@(cdr (car js--treesit-indent-rules))))
                        `((css ((parent-is "stylesheet")
                                php-ts-mode--js-css-tag-bol
                                php-ts-mode-js-css-indent-offset)
                               ,@(cdr (car css--treesit-indent-rules))))))

    ;; Comment
    (php-ts-mode-comment-setup)

    ;; PHP vars are case-sensitive
    (setq-local case-fold-search t)

    ;; Electric
    (setq-local electric-indent-chars
                (append "{}():;," electric-indent-chars))

    ;; Imenu/Which-function/Outline
    (setq-local treesit-simple-imenu-settings
                '(("Class" "\\`class_declaration\\'" nil nil)
                  ("Enum" "\\`enum_declaration\\'" nil nil)
                  ("Function" "\\`function_definition\\'" nil nil)
                  ("Interface" "\\`interface_declaration\\'" nil nil)
                  ("Method" "\\`method_declaration\\'" nil nil)
                  ("Namespace" "\\`namespace_definition\\'" nil nil)
                  ("Trait" "\\`trait_declaration\\'" nil nil)
                  ("Variable" "\\`variable_name\\'" nil nil)
                  ("Constant" "\\`const_element\\'" nil nil)))

    ;; Font-lock.
    (setq-local treesit-font-lock-settings
                (append (php-ts-mode--font-lock-settings)
                        php-ts-mode--custom-html-font-lock-settings
                        js--treesit-font-lock-settings
                        (append
                         ;; Rule for coloring CSS property values.
                         ;; Placed before `css--treesit-settings'
                         ;; to win against the same rule contained therein.
                         (treesit-font-lock-rules
                          :language 'css
                          :override t
                          :feature 'variable
                          '((plain_value) @php-ts-mode--colorize-css-value))
                         css--treesit-settings)
                        php-ts-mode--phpdoc-font-lock-settings))

    (setq-local treesit-font-lock-feature-list php-ts-mode--feature-list)

    ;; Align.
    (setq-local align-indent-before-aligning t)

    ;; should be the last one
    (setq-local treesit-primary-parser (treesit-parser-create 'php))
    (treesit-major-mode-setup)
    (add-hook 'flymake-diagnostic-functions #'php-ts-mode-flymake-php nil 'local)))