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"
    (:eval (let ((lang (treesit-language-at (point))))
	     (cond ((eq lang 'html) "+HTML")
		   ((eq lang 'javascript) "+HTML+JS")
		   ((eq lang 'css) "+HTML+CSS")))))
  "Major mode for editing PHP, powered by tree-sitter."
  :syntax-table php-ts-mode--syntax-table

  ;; TODO: wouldn't better to delegate the check and the
  ;; init of the mhtml parser to mhtml-ts-mode?
  (if (not (and
	    (treesit-ensure-installed 'php)
	    (treesit-ensure-installed 'phpdoc)
	    (treesit-ensure-installed 'html)
	    (treesit-ensure-installed 'javascript)
	    (treesit-ensure-installed 'jsdoc)
	    (treesit-ensure-installed 'css)))
      (error "Tree-sitter for PHP isn't
    available.  You can install the parsers with M-x
    `php-ts-mode-install-parsers'")

    ;; phpdoc is a local parser, don't create a parser for it
    ;; create the parser needed by mhtml-ts-mode
    (treesit-parser-create 'html)
    (treesit-parser-create 'css)
    (treesit-parser-create 'javascript)

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

		  :embed 'html
		  :host 'php
		  '((program (text) @cap)
		    (text_interpolation (text) @cap)))
		 ;; inject the range rules from mhtml-ts-mode
		 mhtml-ts-mode--range-settings))

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

    (setq-local treesit-thing-settings
		(append
		 `((php
		    (defun ,php-ts-mode--treesit-defun-type-regexp)
		    (sexp (not (or (and named
					,(rx bos (or "program"
						     "comment")
					     eos))
				   (and anonymous
					,(rx bos (or "{" "}" "[" "]"
						     "(" ")" ",")
					     eos)))))
		    (list
		     ,(rx bos (or "namespace_use_group"
				  "enum_declaration_list"
				  "declaration_list"
				  "property_hook_list"
				  "use_list"
				  "anonymous_function_use_clause"
				  "formal_parameters"
				  "match_block"
				  "switch_block"
				  "compound_statement"
				  "parenthesized_expression"
				  "_array_destructing"
				  "arguments"
				  "_complex_string_part")
			  eos))
		    (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")))))
		 mhtml-ts-mode--treesit-thing-settings))

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

    (setq-local c-ts-common-indent-offset 'php-ts-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 ,@(alist-get 'html
					     (mhtml-ts-mode--treesit-indent-rules))))
			;; Replace rules for js and css, to
			;; indent appropriately when injected
			;; into html.
			(treesit-simple-indent-modify-rules
			 'javascript
			 `((javascript ((parent-is "program")
					mhtml-ts-mode--js-css-tag-bol
					php-ts-js-css-indent-offset)))
			 `((javascript
			    ,@(alist-get 'javascript
					 (mhtml-ts-mode--treesit-indent-rules)))))

			(treesit-simple-indent-modify-rules
			 'css
			 `((css ((parent-is "stylesheet")
				 mhtml-ts-mode--js-css-tag-bol
				 php-ts-js-css-indent-offset)))
			 `((css
			    ,@(alist-get 'css
					 (mhtml-ts-mode--treesit-indent-rules)))))
			))

    ;; Comment
    (php-ts-mode--comment-setup t) ; Init the comment setup for PHP
    ;; Allow the comment machinery to automatically switch between the
    ;; various comment styles supported by `php-ts-mode'.
    (setq-local comment-setup-function #'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))

    (setq-local electric-layout-rules
                '((?\; . after) (?\{ . after) (?\} . before)))

    ;; Imenu/Which-function
    (setq-local treesit-aggregated-simple-imenu-settings
		(append
		 '((php ("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)))
		 mhtml-ts-mode--treesit-aggregated-simple-imenu-settings))

    ;; Outline
    (setq-local treesit-aggregated-outline-predicate
		(append
		 `((php . ,(rx bos (or "class_declaration"
				       "function_definition"
				       "interface_declaration"
				       "method_declaration"
				       "namespace_definition"
				       "trait_declaration")
			       eos))
		   (phpdoc . ,(rx bos "document" eos)))
		 mhtml-ts-mode--treesit-aggregated-outline-predicate))

    ;; Font-lock.
    (setq-local treesit-font-lock-settings
		(append
		 (php-ts-mode--font-lock-settings)
		 (php-ts-mode--custom-html-font-lock-settings)
		 php-ts-mode--phpdoc-font-lock-settings))

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

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

    ;; Find files
    (setq-local find-sibling-rules php-ts-mode-find-sibling-rules)

    ;; 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)))