;;; php-ts-mode.el --- Major mode for editing PHP files using tree-sitter -*- lexical-binding: t; -*- ;; Copyright (C) 2024 Free Software Foundation, Inc. ;; Author: Vincenzo Pupillo ;; Maintainer: Vincenzo Pupillo ;; Created: Jun 2024 ;; Keywords: PHP language tree-sitter ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;; ;; This package provides `php-ts-mode' which is a major mode ;; for editing PHP files with embedded HTML, JavaScript, CSS and phpdoc. ;; Tree Sitter is used to parse each of these languages. ;; ;; Please note that this package requires `html-ts-mode', which ;; registers itself as the major mode for editing HTML. ;; ;; This package is compatible and has been tested with the following ;; tree-sitter grammars: ;; * https://github.com/tree-sitter/tree-sitter-php ;; * https://github.com/tree-sitter/tree-sitter-html ;; * https://github.com/tree-sitter/tree-sitter-javascript ;; * https://github.com/tree-sitter/tree-sitter-jsdoc ;; * https://github.com/tree-sitter/tree-sitter-css ;; * https://github.com/claytonrcarter/tree-sitter-phpdoc ;; ;; Features ;; ;; * Indent ;; * IMenu ;; * Navigation ;; * Which-function ;; * Flymake ;; * Tree-sitter parser installation helper ;; * PHP built-in server support ;; * Shell interaction: execute PHP code in a inferior PHP process ;;; Code: (require 'treesit) (require 'c-ts-common) ;; For comment indent and filling. (require 'css-mode) ;; for embed css into html (require 'js) ;; for embed javascript into html (require 'comint) (eval-when-compile (require 'cl-lib) (require 'rx) (require 'subr-x)) (declare-function treesit-node-child "treesit.c") (declare-function treesit-node-child-by-field-name "treesit.c") (declare-function treesit-node-end "treesit.c") (declare-function treesit-node-parent "treesit.c") (declare-function treesit-node-start "treesit.c") (declare-function treesit-node-string "treesit.c") (declare-function treesit-node-type "treesit.c") (declare-function treesit-parser-add-notifier "treesit.c") (declare-function treesit-parser-buffer "treesit.c") (declare-function treesit-parser-create "treesit.c") (declare-function treesit-parser-included-ranges "treesit.c") (declare-function treesit-parser-list "treesit.c") (declare-function treesit-parser-language "treesit.c") (declare-function treesit-query-compile "treesit.c") (declare-function treesit-search-forward "treesit.c") (declare-function treesit-node-prev-sibling "treesit.c") (declare-function treesit-node-first-child-for-pos "treesit.c") ;;; Install treesitter language parsers (defvar php-ts-mode--language-source-alist '((php . ("https://github.com/tree-sitter/tree-sitter-php" "v0.23.5" "php/src")) (phpdoc . ("https://github.com/claytonrcarter/tree-sitter-phpdoc")) (html . ("https://github.com/tree-sitter/tree-sitter-html" "v0.23.0")) (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript" "v0.23.0")) (jsdoc . ("https://github.com/tree-sitter/tree-sitter-jsdoc" "v0.23.0")) (css . ("https://github.com/tree-sitter/tree-sitter-css" "v0.23.0"))) "Treesitter language parsers required by `php-ts-mode'. You can customize this variable if you want to stick to a specific commit and/or use different parsers.") (defun php-ts-mode-install-parsers () "Install all the required treesitter parsers. `php-ts-mode--language-source-alist' defines which parsers to install." (interactive) (let ((treesit-language-source-alist php-ts-mode--language-source-alist)) (dolist (item php-ts-mode--language-source-alist) (treesit-install-language-grammar (car item))))) ;;; Custom variables (defgroup php-ts-mode nil "Major mode for editing PHP files." :prefix "php-ts-mode-" :group 'languages) (defcustom php-ts-mode-indent-offset 4 "Number of spaces for each indentation step in `php-ts-mode'." :tag "PHP indent offset" :version "30.1" :type 'integer :safe 'integerp) (defcustom php-ts-mode-js-css-indent-offset 2 "JavaScript and CSS indent spaces related to the