summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimeon Simeonov2026-08-27 20:53:38 +0200
committerSimeon Simeonov2026-08-27 20:53:38 +0200
commit9daec97a593cd6c419badbf08259bdf3653520ab (patch)
treeb7896065cf7ecab0ace30dafb2a9a1d758d0a6cf
parent85601f50f236686da662b1b00e01df0a0abe761b (diff)
Upgrade markdown-mode rust-mode and yaml-mode. Remove PHP mode.
-rw-r--r--.emacs1
-rw-r--r--.emacs.d/lisp/markdown-mode.el20
-rw-r--r--.emacs.d/lisp/php-face.el207
-rw-r--r--.emacs.d/lisp/php-mode.el1744
-rw-r--r--.emacs.d/lisp/php-project.el283
-rw-r--r--.emacs.d/lisp/php-util-buffer.el135
-rw-r--r--.emacs.d/lisp/php.el452
-rw-r--r--.emacs.d/lisp/rust-playpen.el2
-rw-r--r--.emacs.d/lisp/yaml-mode.el36
-rw-r--r--.emacs.pure1
10 files changed, 40 insertions, 2841 deletions
diff --git a/.emacs b/.emacs
index 49e2d9c..b89bcb7 100644
--- a/.emacs
+++ b/.emacs
@@ -1,3 +1,4 @@
1;; -*- lexical-binding: t; -*-
1;; Set up the keyboard so the delete key on both the regular keyboard 2;; Set up the keyboard so the delete key on both the regular keyboard
2;; and the keypad delete the character under the cursor and to the right 3;; and the keypad delete the character under the cursor and to the right
3;; under X, instead of the default, backspace behavior. 4;; under X, instead of the default, backspace behavior.
diff --git a/.emacs.d/lisp/markdown-mode.el b/.emacs.d/lisp/markdown-mode.el
index 08ed4bb..18e1e96 100644
--- a/.emacs.d/lisp/markdown-mode.el
+++ b/.emacs.d/lisp/markdown-mode.el
@@ -1255,6 +1255,21 @@ Function is called repeatedly until it returns nil. For details, see
1255 (unless (and (eq new-start start) (eq new-end end)) 1255 (unless (and (eq new-start start) (eq new-end end))
1256 (cons new-start (min new-end (point-max)))))))) 1256 (cons new-start (min new-end (point-max))))))))
1257 1257
1258(defvar font-lock-beg)
1259(defvar font-lock-end)
1260
1261(defun markdown-font-lock-extend-region ()
1262 "Extend the font-lock region to cover whole blocks.
1263Used in `font-lock-extend-region-functions'. Inline constructs
1264such as bold and italic may span several lines within a block, so
1265fontifying a region that begins or ends in the middle of one
1266would miss the match entirely."
1267 (let ((res (markdown-syntax-propertize-extend-region font-lock-beg font-lock-end)))
1268 (when res
1269 (setq font-lock-beg (car res)
1270 font-lock-end (cdr res))
1271 t)))
1272
1258(defun markdown-font-lock-extend-region-function (start end _) 1273(defun markdown-font-lock-extend-region-function (start end _)
1259 "Used in `jit-lock-after-change-extend-region-functions'. 1274 "Used in `jit-lock-after-change-extend-region-functions'.
1260Delegates to `markdown-syntax-propertize-extend-region'. START 1275Delegates to `markdown-syntax-propertize-extend-region'. START
@@ -4803,7 +4818,8 @@ at the beginning of the block."
4803 while pos-prop 4818 while pos-prop
4804 for lang = (markdown-code-block-lang pos-prop) 4819 for lang = (markdown-code-block-lang pos-prop)
4805 do (progn (when lang (markdown-gfm-add-used-language lang)) 4820 do (progn (when lang (markdown-gfm-add-used-language lang))
4806 (goto-char (next-single-property-change (point) prop))))))) 4821 (goto-char (or (next-single-property-change (point) prop)
4822 (point-max))))))))
4807 4823
4808(defun markdown-insert-foldable-block () 4824(defun markdown-insert-foldable-block ()
4809 "Insert details disclosure element to make content foldable. 4825 "Insert details disclosure element to make content foldable.
@@ -10439,6 +10455,8 @@ rows and columns and the column alignment."
10439 #'markdown-syntax-propertize-extend-region nil t) 10455 #'markdown-syntax-propertize-extend-region nil t)
10440 (add-hook 'jit-lock-after-change-extend-region-functions 10456 (add-hook 'jit-lock-after-change-extend-region-functions
10441 #'markdown-font-lock-extend-region-function t t) 10457 #'markdown-font-lock-extend-region-function t t)
10458 (add-hook 'font-lock-extend-region-functions
10459 #'markdown-font-lock-extend-region t t)
10442 (setq-local syntax-propertize-function #'markdown-syntax-propertize) 10460 (setq-local syntax-propertize-function #'markdown-syntax-propertize)
10443 (syntax-propertize (point-max)) ;; Propertize before hooks run, etc. 10461 (syntax-propertize (point-max)) ;; Propertize before hooks run, etc.
10444 ;; Font lock. 10462 ;; Font lock.
diff --git a/.emacs.d/lisp/php-face.el b/.emacs.d/lisp/php-face.el
deleted file mode 100644
index 5f40257..0000000
--- a/.emacs.d/lisp/php-face.el
+++ /dev/null
@@ -1,207 +0,0 @@
1;;; php-face.el --- Face definitions for PHP script -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2019 Friends of Emacs-PHP development
4
5;; Author: USAMI Kenta <tadsan@zonu.me>
6;; Created: 5 May 2019
7;; Version: 1.22.1
8;; Keywords: faces, php
9;; Homepage: https://github.com/emacs-php/php-mode
10;; Package-Requires: ((emacs "24.3"))
11;; License: GPL-3.0-or-later
12
13;; This program is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
17
18;; This program is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
24;; along with this program. If not, see <https://www.gnu.org/licenses/>.
25
26;;; Commentary:
27
28;; Face definitions for PHP script.
29
30;;; Code:
31
32;;;###autoload
33(defgroup php-faces nil
34 "Faces used in PHP Mode"
35 :tag "PHP Faces"
36 :group 'php-mode
37 :group 'faces)
38
39(defface php-string '((t (:inherit font-lock-string-face)))
40 "PHP Mode face used to highlight string literals."
41 :group 'php-faces
42 :tag "PHP String")
43
44(defface php-keyword '((t (:inherit font-lock-keyword-face)))
45 "PHP Mode face used to highlight keywords."
46 :group 'php-faces
47 :tag "PHP Keyword")
48
49(defface php-builtin '((t (:inherit font-lock-builtin-face)))
50 "PHP Mode face used to highlight builtins."
51 :group 'php-faces
52 :tag "PHP Built-in")
53
54(defface php-function-name '((t (:inherit font-lock-function-name-face)))
55 "PHP Mode face used to highlight function names."
56 :group 'php-faces
57 :tag "PHP Function Name")
58
59(defface php-function-call '((t ()))
60 "PHP Mode face used to highlight function names in calles."
61 :group 'php-faces
62 :tag "PHP Function Call")
63
64(defface php-method-call '((t (:inherit php-function-call)))
65 "PHP Mode face used to highlight method names in calles."
66 :group 'php-faces
67 :tag "PHP Method Call")
68
69(defface php-static-method-call '((t (:inherit php-method-call)))
70 "PHP Mode face used to highlight static method names in calles."
71 :group 'php-faces
72 :tag "PHP Static Method Call")
73
74(defface php-variable-name '((t (:inherit font-lock-variable-name-face)))
75 "PHP Mode face used to highlight variable names."
76 :group 'php-faces
77 :tag "PHP Variable Name")
78
79(defface php-property-name '((t (:inherit php-variable-name)))
80 "PHP Mode face used to highlight property names."
81 :group 'php-faces
82 :tag "PHP Property Name")
83
84(defface php-variable-sigil '((t ()))
85 "PHP Mode face used to highlight variable sigils ($)."
86 :group 'php-faces
87 :tag "PHP Variable Sigil")
88
89(defface php-operator '((t ()))
90 "PHP Mode face used to operators."
91 :group 'php-faces
92 :tag "PHP Operator")
93
94(defface php-assignment-op '((t (:inherit php-operator)))
95 "PHP Mode face used to assignment operators (=, +=, ...)."
96 :group 'php-faces
97 :tag "PHP Object Op")
98
99(defface php-comparison-op '((t (:inherit php-operator)))
100 "PHP Mode face used to comparison operators (==, !=, ===, ...)."
101 :group 'php-faces
102 :tag "PHP Comparison Op")
103
104(defface php-logical-op '((t (:inherit php-operator)))
105 "PHP Mode face used to logical operators (&&, ||, ?:)."
106 :group 'php-faces
107 :tag "PHP Logical Op")
108
109(defface php-arithmetic-op '((t (:inherit php-operator)))
110 "PHP Mode face used to arithmetic operators (+, -, %, ...)."
111 :group 'php-faces
112 :tag "PHP Arithmetic Op")
113
114(defface php-inc-dec-op '((t (:inherit php-operator)))
115 "PHP Mode face used to increment and decremt operators (--, ++)."
116 :group 'php-faces
117 :tag "PHP Increment/Decrement Op")
118
119(defface php-string-op '((t (:inherit php-operator)))
120 "PHP Mode face used to logical operators (.)."
121 :group 'php-faces
122 :tag "PHP String Op")
123
124(defface php-object-op '((t (:inherit php-operator)))
125 "PHP Mode face used to object operators (->)."
126 :group 'php-faces
127 :tag "PHP Object Op")
128
129(defface php-paamayim-nekudotayim '((t ()))
130 "PHP Mode face used to highlight \"Paamayim Nekudotayim\" scope resolution operators (::)."
131 :group 'php-faces
132 :tag "PHP Paamayim Nekudotayim")
133
134(defface php-type '((t (:inherit font-lock-type-face)))
135 "PHP Mode face used to highlight types."
136 :group 'php-faces
137 :tag "PHP Type")
138
139(defface php-class '((t (:inherit font-lock-type-face)))
140 "PHP Mode face used to highlight class."
141 :group 'php-faces
142 :tag "PHP Class")
143
144(defface php-constant '((t (:inherit font-lock-constant-face)))
145 "PHP Mode face used to highlight constants."
146 :group 'php-faces
147 :tag "PHP Constant")
148
149(defface php-constant-assign '((t (:inherit font-lock-type-face)))
150 "PHP Mode face used to highlight constant assigning (\"const\" statement)."
151 :group 'php-faces
152 :tag "PHP Constant Assign")
153
154(defface php-magical-constant '((t (:inherit font-lock-builtin-face)))
155 "PHP Mode face used to highlight magical constants."
156 :group 'php-faces
157 :tag "PHP Magical Constant")
158
159(defface php-$this '((t (:inherit php-constant)))
160 "PHP Mode face used to highlight $this variables."
161 :group 'php-faces
162 :tag "PHP $this")
163
164(defface php-$this-sigil '((t (:inherit php-constant)))
165 "PHP Mode face used to highlight sigils($) of $this variable."
166 :group 'php-faces
167 :tag "PHP $this Sigil")
168
169(defface php-errorcontrol-op '((t (:inherit font-lock-type-face)))
170 "PHP Mode face used to highlight errorcontrol operators (@).."
171 :group 'php-faces
172 :tag "PHP ErrorControl Op")
173
174(defface php-php-tag '((t (:inherit font-lock-preprocessor-face)))
175 "PHP Mode face used to highlight PHP tags."
176 :group 'php-faces
177 :tag "PHP php Tag")
178
179(defface php-doc-annotation-tag '((t . (:inherit font-lock-constant-face)))
180 "Face used to highlight annotation tags in doc-comment."
181 :group 'php-faces
182 :tag "PHPDoc Annotation Tag")
183
184(defface php-doc-variable-sigil '((t (:inherit font-lock-variable-name-face)))
185 "PHP Mode face used to highlight variable sigils($)."
186 :group 'php-faces
187 :tag "PHPDoc Variable Sigil")
188
189(defface php-doc-$this '((t (:inherit php-type)))
190 "PHP Mode face used to highlight $this variable in doc-comment."
191 :group 'php-faces
192 :tag "PHPDoc $this")
193
194(defface php-doc-$this-sigil '((t (:inherit php-type)))
195 "PHP Mode face used to highlight sigil of $this variable in doc-comment."
196 :group 'php-faces
197 :tag "PHPDoc $this Sigil")
198
199(defface php-doc-class-name '((t (:inherit php-string)))
200 "Face used to class names in doc-comment."
201 :group 'php-faces
202 :tag "PHPDoc Class Name")
203
204(define-obsolete-face-alias 'php-annotations-annotation-face 'php-doc-annotation-tag "1.19.0")
205
206(provide 'php-face)
207;;; php-face.el ends here
diff --git a/.emacs.d/lisp/php-mode.el b/.emacs.d/lisp/php-mode.el
deleted file mode 100644
index faf2ec5..0000000
--- a/.emacs.d/lisp/php-mode.el
+++ /dev/null
@@ -1,1744 +0,0 @@
1;;; php-mode.el --- Major mode for editing PHP code
2
3;; Copyright (C) 2018-2019 Friends of Emacs-PHP development
4;; Copyright (C) 1999, 2000, 2001, 2003, 2004 Turadg Aleahmad
5;; 2008 Aaron S. Hawley
6;; 2011, 2012, 2013, 2014, 2015, 2016, 2017 Eric James Michael Ritz
7
8;; Author: Eric James Michael Ritz
9;; Maintainer: USAMI Kenta <tadsan@zonu.me>
10;; URL: https://github.com/emacs-php/php-mode
11;; Keywords: languages php
12;; Version: 1.22.1
13;; Package-Requires: ((emacs "24.3"))
14;; License: GPL-3.0-or-later
15
16(defconst php-mode-version-number "1.22.1"
17 "PHP Mode version number.")
18
19;; This program is free software; you can redistribute it and/or modify
20;; it under the terms of the GNU General Public License as published by
21;; the Free Software Foundation, either version 3 of the License, or
22;; (at your option) any later version.
23
24;; This program is distributed in the hope that it will be useful,
25;; but WITHOUT ANY WARRANTY; without even the implied warranty of
26;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27;; GNU General Public License for more details.
28
29;; You should have received a copy of the GNU General Public License
30;; along with this program. If not, see <https://www.gnu.org/licenses/>.
31
32;;; Commentary:
33
34;; PHP Mode is a major mode for editing PHP script. It's an extension
35;; of CC mode; thus it inherits all C mode's navigation functionality.
36;; But it colors according to the PHP syntax and indents according to the
37;; PSR-2 coding guidelines. It also includes a couple handy IDE-type
38;; features such as documentation search and a source and class browser.
39
40;; Please read the manual for setting items compatible with CC Mode.
41;; https://www.gnu.org/software/emacs/manual/html_mono/ccmode.html
42
43;; This mode is designed for PHP scripts consisting of a single <?php block.
44;; We recommend the introduction of Web Mode for HTML and Blade templates combined with PHP.
45;; http://web-mode.org/
46
47;; Modern PHP Mode can be set on a project basis by .dir-locals.el.
48;; Please read php-project.el for details of directory local variables.
49
50;; If you are using a package manager, you do not need (require 'php-mode) in
51;; your ~/.emacs.d/init.el. Read the README for installation instructions.
52;; https://github.com/emacs-php/php-mode
53
54;;; Code:
55
56(require 'php)
57(require 'php-face)
58(require 'cc-mode)
59(require 'cc-langs)
60
61(eval-when-compile
62 (require 'cc-fonts))
63
64;; Boilerplate from other `cc-mode' derived modes. See
65;; http://cc-mode.sourceforge.net/derived-mode-ex.el for details on how this all
66;; fits together.
67(eval-and-compile
68 (c-add-language 'php-mode 'java-mode))
69
70(require 'font-lock)
71(require 'add-log)
72(require 'custom)
73(require 'etags)
74(require 'speedbar)
75(require 'imenu)
76(require 'nadvice nil t)
77
78(require 'cl-lib)
79(require 'mode-local)
80(require 'php-project)
81
82(eval-when-compile
83 (require 'regexp-opt)
84 (defvar c-vsemi-status-unknown-p)
85 (defvar syntax-propertize-via-font-lock))
86
87;; Work around emacs bug#18845, cc-mode expects cl to be loaded
88;; while php-mode only uses cl-lib (without compatibility aliases)
89(eval-and-compile
90 (when (and (= emacs-major-version 24) (>= emacs-minor-version 4))
91 (require 'cl)))
92
93;; Work around https://github.com/emacs-php/php-mode/issues/310.
94;;
95;; In emacs 24.4 and 24.5, lines after functions with a return type
96;; are incorrectly analyzed as member-init-cont.
97;;
98;; Before emacs 24.4, c member initializers are not supported this
99;; way. Starting from emacs 25.1, cc-mode only detects member
100;; initializers when the major mode is c++-mode.
101(eval-and-compile
102 (if (and (= emacs-major-version 24) (or (= emacs-minor-version 4)
103 (= emacs-minor-version 5)))
104 (defun c-back-over-member-initializers ()
105 ;; Override of cc-engine.el, cc-mode in emacs 24.4 and 24.5 are too
106 ;; optimistic in recognizing c member initializers. Since we don't
107 ;; need it in php-mode, just return nil.
108 nil)))
109
110(autoload 'php-mode-debug "php-mode-debug"
111 "Display informations useful for debugging PHP Mode." t)
112
113;; Local variables
114
115;;;###autoload
116(defgroup php-mode nil
117 "Major mode for editing PHP code."
118 :tag "PHP Mode"
119 :prefix "php-mode-"
120 :group 'languages
121 :group 'php
122 :link '(url-link :tag "Official Site" "https://github.com/emacs-php/php-mode")
123 :link '(url-link :tag "PHP Mode Wiki" "https://github.com/emacs-php/php-mode/wiki"))
124
125(define-obsolete-variable-alias 'php-default-face 'php-mode-default-face "1.20.0")
126(defcustom php-mode-default-face 'default
127 "Default face in `php-mode' buffers."
128 :group 'php-mode
129 :tag "PHP Mode Default Face"
130 :type 'face)
131
132(define-obsolete-variable-alias 'php-speedbar-config 'php-mode-speedbar-config "1.20.0")
133(defcustom php-mode-speedbar-config t
134 "When set to true automatically configures Speedbar to observe PHP files.
135Ignores php-file patterns option; fixed to expression \"\\.\\(inc\\|php[s345]?\\)\""
136 :group 'php-mode
137 :tag "PHP Mode Speedbar Config"
138 :type 'boolean
139 :set (lambda (sym val)
140 (set-default sym val)
141 (when val
142 (speedbar-add-supported-extension
143 "\\.\\(inc\\|php[s345]?\\|phtml\\)"))))
144
145(defcustom php-mode-speedbar-open nil
146 "Normally `php-mode' starts with the speedbar closed.
147Turning this on will open it whenever `php-mode' is loaded."
148 :group 'php-mode
149 :tag "PHP Mode Speedbar Open"
150 :type 'boolean
151 :set (lambda (sym val)
152 (set-default sym val)
153 (when val
154 (speedbar 1))))
155
156(define-obsolete-variable-alias 'php-template-compatibility 'php-mode-template-compatibility "1.20.0")
157(defcustom php-mode-template-compatibility t
158 "Should detect presence of html tags."
159 :group 'php-mode
160 :tag "PHP Mode Template Compatibility"
161 :type 'boolean)
162
163(defun php-mode-extra-constants-create-regexp (kwds)
164 "Create regexp for the list of extra constant keywords KWDS."
165 (concat "[^_$]?\\<\\("
166 (regexp-opt
167 (append kwds
168 (when (boundp 'web-mode-extra-php-constants) web-mode-extra-php-constants)))
169 "\\)\\>[^_]?"))
170
171(defun php-mode-extra-constants-set (sym value)
172 "Apply the list of extra constant keywords `VALUE'.
173
174This function is called when the custom variable php-extra-constants
175is updated. The web-mode-extra-constants list is appended to the list
176of constants when set."
177 ;; remove old keywords
178 (when (boundp 'php-extra-constants)
179 (font-lock-remove-keywords
180 'php-mode `((,(php-mode-extra-constants-create-regexp php-extra-constants) 1 'php-constant))))
181 ;; add new keywords
182 (when value
183 (font-lock-add-keywords
184 'php-mode `((,(php-mode-extra-constants-create-regexp value) 1 'php-constant))))
185 (set sym value))
186
187(define-obsolete-variable-alias 'php-lineup-cascaded-calls 'php-mode-lineup-cascaded-calls "1.20.0")
188(defcustom php-mode-lineup-cascaded-calls nil
189 "Indent chained method calls to the previous line."
190 :group 'php-mode
191 :tag "PHP Mode Lineup Cascaded Calls"
192 :type 'boolean)
193
194(defcustom php-mode-page-delimiter
195 (eval-when-compile
196 (rx symbol-start
197 (or "namespace" "function" "class" "trait" "interface")
198 symbol-end))
199 "Regexp describing line-beginnings that PHP declaration statements."
200 :group 'php-mode
201 :tag "PHP Mode Page Delimiter"
202 :type 'regexp)
203
204(define-obsolete-variable-alias 'php-extra-constants 'php-mode-extra-constants "1.20.0")
205(defcustom php-mode-extra-constants '()
206 "A list of additional strings to treat as PHP constants."
207 :group 'php-mode
208 :tag "PHP Mode Extra Constants"
209 :type '(repeat string)
210 :set 'php-mode-extra-constants-set)
211
212(define-obsolete-variable-alias 'php-do-not-use-semantic-imenu 'php-mode-do-not-use-semantic-imenu "1.20.0")
213(defcustom php-mode-do-not-use-semantic-imenu t
214 "Customize `imenu-create-index-function' for `php-mode'.
215
216If using function `semantic-mode' `imenu-create-index-function' will be
217set to `semantic-create-imenu-index' due to `c-mode' being its
218parent. Set this variable to t if you want to use
219`imenu-default-create-index-function' even with `semantic-mode'
220enabled."
221 :group 'php-mode
222 :tag "PHP Mode Do Not Use Semantic Imenu"
223 :type 'boolean)
224
225(defcustom php-completion-file ""
226 "Path to the file which contains the function names known to PHP."
227 :type 'string)
228
229(defcustom php-manual-path ""
230 "Path to the directory which contains the PHP manual."
231 :type 'string)
232
233;;;###autoload
234(if (version< emacs-version "24.4")
235 (dolist (i '("php" "php5" "php7"))
236 (add-to-list 'interpreter-mode-alist (cons i 'php-mode)))
237 (add-to-list 'interpreter-mode-alist
238 ;; Match php, php-3, php5, php7, php5.5, php-7.0.1, etc.
239 (cons "php\\(?:-?[3457]\\(?:\\.[0-9]+\\)*\\)?" 'php-mode)))
240
241(defcustom php-mode-hook nil
242 "List of functions to be executed on entry to `php-mode'."
243 :group 'php-mode
244 :tag "PHP Mode Hook"
245 :type 'hook)
246
247(defcustom php-mode-pear-hook nil
248 "Hook called when a PHP PEAR file is opened with `php-mode'."
249 :group 'php-mode
250 :tag "PHP Mode Pear Hook"
251 :type 'hook)
252
253(defcustom php-mode-drupal-hook nil
254 "Hook called when a Drupal file is opened with `php-mode'."
255 :group 'php-mode
256 :tag "PHP Mode Drupal Hook"
257 :type 'hook)
258
259(defcustom php-mode-wordpress-hook nil
260 "Hook called when a WordPress file is opened with `php-mode'."
261 :group 'php-mode
262 :tag "PHP Mode WordPress Hook"
263 :type 'hook)
264
265(defcustom php-mode-symfony2-hook nil
266 "Hook called when a Symfony2 file is opened with `php-mode'."
267 :group 'php-mode
268 :tag "PHP Mode Symfony2 Hook"
269 :type 'hook)
270
271(defcustom php-mode-psr2-hook nil
272 "Hook called when a PSR-2 file is opened with `php-mode'."
273 :group 'php-mode
274 :tag "PHP Mode PSR-2 Hook"
275 :type 'hook)
276
277(defcustom php-mode-force-pear nil
278 "Normally PEAR coding rules are enforced only when the filename contains \"PEAR.\"
279Turning this on will force PEAR rules on all PHP files."
280 :group 'php-mode
281 :tag "PHP Mode Force Pear"
282 :type 'boolean)
283
284(defcustom php-mode-warn-if-mumamo-off t
285 "Warn once per buffer if you try to indent a buffer without
286mumamo-mode turned on. Detects if there are any HTML tags in the
287buffer before warning, but this is is not very smart; e.g. if you
288have any tags inside a PHP string, it will be fooled."
289 :group 'php-mode
290 :tag "PHP Mode Warn If MuMaMo Off"
291 :type '(choice (const :tag "Warn" t) (const "Don't warn" nil)))
292
293(defcustom php-mode-coding-style 'pear
294 "Select default coding style to use with php-mode.
295This variable can take one of the following symbol values:
296
297`Default' - use a reasonable default style for PHP.
298
299`PEAR' - use coding styles preferred for PEAR code and modules.
300
301`Drupal' - use coding styles preferred for working with Drupal projects.
302
303`WordPress' - use coding styles preferred for working with WordPress projects.
304
305`Symfony2' - use coding styles preferred for working with Symfony2 projects.
306
307`PSR-2' - use coding styles preferred for working with projects using PSR-2 standards."
308 :group 'php-mode
309 :tag "PHP Mode Coding Style"
310 :type '(choice (const :tag "Default" php)
311 (const :tag "PEAR" pear)
312 (const :tag "Drupal" drupal)
313 (const :tag "WordPress" wordpress)
314 (const :tag "Symfony2" symfony2)
315 (const :tag "PSR-2" psr2))
316 :initialize 'custom-initialize-default)
317
318;; Since this function has a bad influence on the environment of many users,
319;; temporarily disable it
320(defcustom php-mode-enable-project-coding-style nil
321 "When set to true override php-mode-coding-style by php-project-coding-style.
322
323If you want to suppress styles from being overwritten by directory / file
324local variables, set NIL."
325 :group 'php-mode
326 :tag "PHP Mode Enable Project Coding Style"
327 :type 'boolean)
328
329(defcustom php-mode-enable-backup-style-variables t
330 "When set to `T', back up values set by hook and buffer local variables.
331
332This function may interfere with other hooks and other behaviors.
333In that case set to `NIL'."
334 :group 'php-mode
335 :tag "PHP Mode Enable Backup Style Variables"
336 :type 'boolean)
337
338(define-obsolete-variable-alias 'php-mode-disable-parent-mode-hooks 'php-mode-disable-c-mode-hook "1.21.0")
339(defcustom php-mode-disable-c-mode-hook t
340 "When set to `T', do not run hooks of parent modes (`java-mode', `c-mode')."
341 :group 'php-mode
342 :tag "PHP Mode Disable C Mode Hook"
343 :type 'boolean)
344
345(defcustom php-mode-enable-project-local-variable t
346 "When set to `T', apply project local variable to buffer local variable."
347 :group 'php-mode
348 :tag "PHP Mode Enable Project Local Variable"
349 :type 'boolean)
350
351(defun php-mode-version ()
352 "Display string describing the version of PHP Mode."
353 (interactive)
354 (let ((fmt
355 (eval-when-compile
356 (let ((id "$Id$"))
357 (concat "PHP Mode %s"
358 (if (string= id (concat [?$ ?I ?d ?$]))
359 ""
360 (concat " " id)))))))
361 (funcall
362 (if (called-interactively-p 'interactive) #'message #'format)
363 fmt php-mode-version-number)))
364
365;;;###autoload
366(define-obsolete-variable-alias 'php-available-project-root-files 'php-project-available-root-files "1.19.0")
367
368(defvar php-mode-map
369 (let ((map (make-sparse-keymap "PHP Mode")))
370 ;; Remove menu item for c-mode
371 (define-key map [menu-bar C] nil)
372
373 ;; (define-key map [menu-bar php complete-function]
374 ;; '("Complete function name" . php-complete-function))
375 ;; (define-key map [menu-bar php browse-manual]
376 ;; '("Browse manual" . php-browse-manual))
377 ;; (define-key map [menu-bar php search-documentation]
378 ;; '("Search documentation" . php-search-documentation))
379
380 ;; By default PHP Mode binds C-M-h to c-mark-function, which it
381 ;; inherits from cc-mode. But there are situations where
382 ;; c-mark-function fails to properly mark a function. For
383 ;; example, if we use c-mark-function within a method definition
384 ;; then the region will expand beyond the method and into the
385 ;; class definition itself.
386 ;;
387 ;; Changing the default to mark-defun provides behavior that users
388 ;; are more likely to expect.
389 (define-key map (kbd "C-M-h") 'mark-defun)
390
391 ;; Many packages based on cc-mode provide the 'C-c C-w' binding
392 ;; to toggle Subword Mode. See the page
393 ;;
394 ;; https://www.gnu.org/software/emacs/manual/html_node/ccmode/Subword-Movement.html
395 ;;
396 ;; for more information about Subword mode.
397 (define-key map (kbd "C-c C-w") 'subword-mode)
398
399 ;; We inherit c-beginning-of-defun and c-end-of-defun from CC Mode
400 ;; but we have two replacement functions specifically for PHP. We
401 ;; remap the commands themselves and not their default
402 ;; key-bindings so that our PHP-specific versions will work even
403 ;; if the user has reconfigured their keys, e.g. if they rebind
404 ;; c-end-of-defun to something other than C-M-e.
405 (define-key map [remap c-beginning-of-defun] 'php-beginning-of-defun)
406 (define-key map [remap c-end-of-defun] 'php-end-of-defun)
407 (define-key map [remap c-set-style] 'php-set-style)
408
409 (define-key map [(control c) (control f)] 'php-search-documentation)
410 (define-key map [(meta tab)] 'php-complete-function)
411 (define-key map [(control c) (control m)] 'php-browse-manual)
412 (define-key map [(control .)] 'php-show-arglist)
413 (define-key map [(control c) (control r)] 'php-send-region)
414 ;; Use the Emacs standard indentation binding. This may upset c-mode
415 ;; which does not follow this at the moment, but I see no better
416 ;; choice.
417 (define-key map [tab] 'indent-for-tab-command)
418 map)
419 "Keymap for `php-mode'.")
420
421(c-lang-defconst c-mode-menu
422 php (append '(["Complete function name" php-complete-function t]
423 ["Browse manual" php-browse-manual t]
424 ["Search documentation" php-search-documentation t]
425 ["----" t])
426 (c-lang-const c-mode-menu)))
427
428(c-lang-defconst c-at-vsemi-p-fn
429 php 'php-c-at-vsemi-p)
430
431(c-lang-defconst c-vsemi-status-unknown-p-fn
432 php 'php-c-vsemi-status-unknown-p)
433
434(c-lang-defconst c-get-state-before-change-functions
435 php nil)
436
437(c-lang-defconst c-before-font-lock-functions
438 php (c-get-lang-constant 'c-before-font-lock-functions nil t))
439
440;; Make php-mode recognize opening tags as preprocessor macro's.
441;;
442;; This is a workaround, the tags must be recognized as something
443;; in order for the syntactic guesses of code below the tag
444;; to be correct and as a result not break indentation.
445;;
446;; Note that submatches or \\| here are not expected by cc-mode.
447(c-lang-defconst c-opt-cpp-prefix
448 php "\\s-*<\\?")
449
450(c-lang-defconst c-anchored-cpp-prefix
451 php "\\s-*\\(<\\?(=\\|\\sw+)\\)")
452
453(c-lang-defconst c-identifier-ops
454 php '(
455 (left-assoc "\\" "::" "->")
456 (prefix "\\" "::")))
457
458(c-lang-defconst c-operators
459 php `((prefix "new" "clone")
460 ,@(c-lang-const c-identifier-ops)
461 (postfix "->")
462 (postfix "++" "--" "[" "]" "(" ")")
463 (right-assoc "**")
464 (prefix "++" "--" "+" "-" "~" "(" ")" "@")
465 (prefix "instanceof")
466 (prefix "!")
467 (left-assoc "*" "/" "%")
468 (left-assoc "+" "-" ".")
469 (left-assoc "<<" ">>")
470 (left-assoc "<" ">" "<=" ">=")
471 (left-assoc "==" "!=" "===" "!==" "<>" "<=>")
472 (left-assoc "&")
473 (left-assoc "^")
474 (left-assoc "|")
475 (left-assoc "&&")
476 (left-assoc "||")
477 (right-assoc "??")
478 (left-assoc "?:")
479 (right-assoc-sequence "?" ":")
480 (right-assoc ,@(c-lang-const c-assignment-operators))
481 (left-assoc "and")
482 (left-assoc "xor")
483 (left-assoc "or")
484 (left-assoc ",")))
485
486;; Allow '\' when scanning from open brace back to defining
487;; construct like class
488(c-lang-defconst c-block-prefix-disallowed-chars
489 php (cl-set-difference (c-lang-const c-block-prefix-disallowed-chars)
490 '(?\\)))
491
492;; Allow $ so variables are recognized in cc-mode and remove @. This
493;; makes cc-mode highlight variables and their type hints in arglists.
494(c-lang-defconst c-symbol-start
495 php (concat "[" c-alpha "_$]"))
496
497;; All string literals can possibly span multiple lines
498(c-lang-defconst c-multiline-string-start-char
499 php t)
500
501(c-lang-defconst c-assignment-operators
502 php '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" "&=" "^=" "|=" ".=" "??="))
503
504(c-lang-defconst beginning-of-defun-function
505 php 'php-beginning-of-defun)
506
507(c-lang-defconst end-of-defun-function
508 php 'php-end-of-defun)
509
510(c-lang-defconst c-primitive-type-kwds
511 php '("int" "integer" "bool" "boolean" "float" "double" "real"
512 "string" "object" "void"))
513
514(c-lang-defconst c-class-decl-kwds
515 "Keywords introducing declarations where the following block (if any)
516contains another declaration level that should be considered a class."
517 php '("class" "trait" "interface"))
518
519(c-lang-defconst c-brace-list-decl-kwds
520 "Keywords introducing declarations where the following block (if
521any) is a brace list.
522
523PHP does not have an \"enum\"-like keyword."
524 php nil)
525
526(c-lang-defconst c-typeless-decl-kwds
527 php (append (c-lang-const c-class-decl-kwds) '("function")))
528
529(c-lang-defconst c-modifier-kwds
530 php '("abstract" "const" "final" "static"))
531
532(c-lang-defconst c-protection-kwds
533 "Access protection label keywords in classes."
534 php '("private" "protected" "public"))
535
536(c-lang-defconst c-postfix-decl-spec-kwds
537 php '("implements" "extends"))
538
539(c-lang-defconst c-type-list-kwds
540 php '("@new" ;; @new is *NOT* language construct, it's workaround for coloring.
541 "new" "use" "implements" "extends" "namespace" "instanceof" "insteadof"))
542
543(c-lang-defconst c-ref-list-kwds
544 php nil)
545
546(c-lang-defconst c-block-stmt-2-kwds
547 php '("catch" "declare" "elseif" "for" "foreach" "if" "switch" "while"))
548
549(c-lang-defconst c-simple-stmt-kwds
550 php '("break" "continue" "die" "echo" "exit" "goto" "return" "throw"
551 "include" "include_once" "print" "require" "require_once"))
552
553(c-lang-defconst c-constant-kwds
554 php '("true" "false" "null"))
555
556(c-lang-defconst c-lambda-kwds
557 php '("function" "use"))
558
559(c-lang-defconst c-other-block-decl-kwds
560 php '("namespace"))
561
562(c-lang-defconst c-other-kwds
563 "Keywords not accounted for by any other `*-kwds' language constant."
564 php
565 '(
566 "__halt_compiler"
567 "and"
568 "array"
569 "as"
570 "break"
571 "catch"
572 "clone"
573 "default"
574 "empty"
575 "enddeclare"
576 "endfor"
577 "endforeach"
578 "endif"
579 "endswitch"
580 "endwhile"
581 "eval"
582 "fn" ;; NOT c-lambda-kwds
583 "global"
584 "isset"
585 "list"
586 "or"
587 "parent"
588 "static"
589 "unset"
590 "var"
591 "xor"
592 "yield"
593 "yield from"
594
595 ;; Below keywords are technically not reserved keywords, but
596 ;; threated no differently by php-mode from actual reserved
597 ;; keywords
598 ;;
599 ;;; declare directives:
600 "encoding"
601 "ticks"
602 "strict_types"
603
604 ;;; self for static references:
605 "self"
606 ))
607
608;; PHP does not have <> templates/generics
609(c-lang-defconst c-recognize-<>-arglists
610 php nil)
611
612(c-lang-defconst c-<>-type-kwds
613 php nil)
614
615(c-lang-defconst c-inside-<>-type-kwds
616 php nil)
617
618(c-lang-defconst c-enums-contain-decls
619 php nil)
620
621(c-lang-defconst c-nonlabel-token-key
622 "Regexp matching things that can't occur in generic colon labels.
623
624This overrides cc-mode `c-nonlabel-token-key' to support switching on
625double quoted strings and true/false/null.
626
627Note: this regexp is also applied to goto-labels, a future improvement
628might be to handle switch and goto labels differently."
629 php (concat
630 ;; All keywords except `c-label-kwds' and `c-constant-kwds'.
631 (c-make-keywords-re t
632 (cl-set-difference (c-lang-const c-keywords)
633 (append (c-lang-const c-label-kwds)
634 (c-lang-const c-constant-kwds))
635 :test 'string-equal))))
636
637(c-lang-defconst c-basic-matchers-before
638 php (cl-remove-if (lambda (elm) (and (listp elm) (equal (car elm) "\\s|")))
639 (c-lang-const c-basic-matchers-before php)))
640
641(c-lang-defconst c-basic-matchers-after
642 php (cl-remove-if (lambda (elm) (and (listp elm) (memq 'c-annotation-face elm)))
643 (c-lang-const c-basic-matchers-after php)))
644
645(c-lang-defconst c-opt-<>-sexp-key
646 php nil)
647
648(defconst php-mode--re-return-typed-closure
649 (eval-when-compile
650 (rx symbol-start "function" symbol-end
651 (* (syntax whitespace))
652 "(" (* (not (any "("))) ")"
653 (* (syntax whitespace))
654 (? symbol-start "use" symbol-end
655 (* (syntax whitespace))
656 "(" (* (not (any "("))) ")"
657 (* (syntax whitespace)))
658 ":" (+ (not (any "{}")))
659 (group "{"))))
660
661(defun php-c-lineup-arglist (langelem)
662 "Line up the current argument line under the first argument using `c-lineup-arglist' LANGELEM."
663 (let (in-return-typed-closure)
664 (when (and (consp langelem)
665 (eq 'arglist-cont-nonempty (car langelem)))
666 (save-excursion
667 (save-match-data
668 (when (re-search-backward php-mode--re-return-typed-closure (cdr langelem) t)
669 (goto-char (match-beginning 1))
670 (when (not (php-in-string-or-comment-p))
671 (setq in-return-typed-closure t))))))
672 (unless in-return-typed-closure
673 (c-lineup-arglist langelem))))
674
675(defun php-lineup-cascaded-calls (langelem)
676 "Line up chained methods using `c-lineup-cascaded-calls',
677but only if the setting is enabled"
678 (when php-mode-lineup-cascaded-calls
679 (c-lineup-cascaded-calls langelem)))
680
681(c-add-style
682 "php"
683 `((c-basic-offset . 4)
684 (c-offsets-alist . ((arglist-close . php-lineup-arglist-close)
685 (arglist-cont . (first php-lineup-cascaded-calls 0))
686 (arglist-cont-nonempty . (first php-lineup-cascaded-calls php-c-lineup-arglist))
687 (arglist-intro . php-lineup-arglist-intro)
688 (case-label . +)
689 (class-open . 0)
690 (comment-intro . 0)
691 (inexpr-class . 0)
692 (inlambda . 0)
693 (inline-open . 0)
694 (namespace-open . 0)
695 (lambda-intro-cont . +)
696 (label . +)
697 (statement-cont . (first php-lineup-cascaded-calls php-lineup-string-cont +))
698 (substatement-open . 0)
699 (topmost-intro-cont . (first php-lineup-cascaded-calls +))))
700 (indent-tabs-mode . nil)
701 (tab-width . ,(default-value 'tab-width))
702 (fill-column . ,(default-value 'fill-column))
703 (show-trailing-whitespace . ,(default-value 'show-trailing-whitespace))
704 (php-mode-lineup-cascaded-calls . t)
705 (php-style-delete-trailing-whitespace . nil)))
706
707(defun php-enable-default-coding-style ()
708 "Set PHP Mode to use reasonable default formatting."
709 (interactive)
710 (php-set-style "php"))
711
712(c-add-style
713 "pear"
714 '("php"
715 (c-basic-offset . 4)
716 (c-offsets-alist . ((case-label . 0)))
717 (tab-width . 4)))
718
719(defun php-enable-pear-coding-style ()
720 "Set up php-mode to use the coding styles preferred for PEAR code and modules."
721 (interactive)
722 (php-set-style "pear"))
723
724(c-add-style
725 "drupal"
726 '("php"
727 (c-basic-offset . 2)
728 (tab-width . 2)
729 (fill-column . 78)
730 (show-trailing-whitespace . t)
731 (php-mode-lineup-cascaded-calls . nil)
732 (php-style-delete-trailing-whitespace . t)))
733
734(defun php-enable-drupal-coding-style ()
735 "Make php-mode use coding styles that are preferable for working with Drupal."
736 (interactive)
737 (php-set-style "drupal"))
738
739(c-add-style
740 "wordpress"
741 '("php"
742 (c-basic-offset . 4)
743 (c-indent-comments-syntactically-p t)
744 (indent-tabs-mode . t)
745 (tab-width . 4)
746 (fill-column . 78)))
747
748(defun php-enable-wordpress-coding-style ()
749 "Make php-mode use coding styles that are preferable for working with Wordpress."
750 (interactive)
751 (php-set-style "wordpress"))
752
753(c-add-style
754 "symfony2"
755 '("php"
756 (c-offsets-alist . ((statement-cont . php-lineup-hanging-semicolon)))
757 (c-indent-comments-syntactically-p . t)
758 (php-mode-lineup-cascaded-calls . nil)
759 (fill-column . 78)))
760
761(defun php-enable-symfony2-coding-style ()
762 "Make php-mode use coding styles that are preferable for working with Symfony2."
763 (interactive)
764 (php-set-style "symfony2"))
765
766(c-add-style
767 "psr2" ; PSR-2 / PSR-12
768 '("php"
769 (c-offsets-alist . ((statement-cont . +)))
770 (c-indent-comments-syntactically-p . t)
771 (fill-column . 78)
772 (show-trailing-whitespace . t)
773 (php-mode-lineup-cascaded-calls . nil)
774 (php-style-delete-trailing-whitespace . t)))
775
776(defun php-enable-psr2-coding-style ()
777 "Make php-mode comply to the PSR-2 coding style."
778 (interactive)
779 (php-set-style "psr2"))
780
781(defun php-beginning-of-defun (&optional arg)
782 "Move to the beginning of the ARGth PHP function from point.
783Implements PHP version of `beginning-of-defun-function'."
784 (interactive "p")
785 (let (found-p (arg (or arg 1)))
786 (while (> arg 0)
787 (setq found-p (re-search-backward php-beginning-of-defun-regexp
788 nil 'noerror))
789 (setq arg (1- arg)))
790 (while (< arg 0)
791 (end-of-line 1)
792 (let ((opoint (point)))
793 (beginning-of-defun 1)
794 (forward-list 2)
795 (forward-line 1)
796 (if (eq opoint (point))
797 (setq found-p (re-search-forward php-beginning-of-defun-regexp
798 nil 'noerror)))
799 (setq arg (1+ arg))))
800 (not (null found-p))))
801
802(defun php-end-of-defun (&optional arg)
803 "Move the end of the ARGth PHP function from point.
804Implements PHP version of `end-of-defun-function'
805
806See `php-beginning-of-defun'."
807 (interactive "p")
808 (php-beginning-of-defun (- (or arg 1))))
809
810
811(defvar php-warned-bad-indent nil)
812
813;; Do it but tell it is not good if html tags in buffer.
814(defun php-check-html-for-indentation ()
815 (let ((html-tag-re "^\\s-*</?\\sw+.*?>")
816 (here (point)))
817 (goto-char (line-beginning-position))
818 (if (or (when (boundp 'mumamo-multi-major-mode) mumamo-multi-major-mode)
819 ;; Fix-me: no idea how to check for mmm or multi-mode
820 (save-match-data
821 (not (or (re-search-forward html-tag-re (line-end-position) t)
822 (re-search-backward html-tag-re (line-beginning-position) t)))))
823 (progn
824 (goto-char here)
825 t)
826 (goto-char here)
827 (setq php-warned-bad-indent t)
828 (let* ((known-multi-libs '(("mumamo" mumamo (lambda () (nxhtml-mumamo)))
829 ("mmm-mode" mmm-mode (lambda () (mmm-mode 1)))
830 ("multi-mode" multi-mode (lambda () (multi-mode 1)))
831 ("web-mode" web-mode (lambda () (web-mode)))))
832 (known-names (mapcar (lambda (lib) (car lib)) known-multi-libs))
833 (available-multi-libs (delq nil
834 (mapcar
835 (lambda (lib)
836 (when (locate-library (car lib)) lib))
837 known-multi-libs)))
838 (available-names (mapcar (lambda (lib) (car lib)) available-multi-libs))
839 (base-msg
840 (concat
841 "Indentation fails badly with mixed HTML/PHP in the HTML part in
842plain `php-mode'. To get indentation to work you must use an
843Emacs library that supports 'multiple major modes' in a buffer.
844Parts of the buffer will then be in `php-mode' and parts in for
845example `html-mode'. Known such libraries are:\n\t"
846 (mapconcat 'identity known-names ", ")
847 "\n"
848 (if available-multi-libs
849 (concat
850 "You have these available in your `load-path':\n\t"
851 (mapconcat 'identity available-names ", ")
852 "\n\n"
853 "Do you want to turn any of those on? ")
854 "You do not have any of those in your `load-path'.")))
855 (is-using-multi
856 (catch 'is-using
857 (dolist (lib available-multi-libs)
858 (when (and (boundp (cadr lib))
859 (symbol-value (cadr lib)))
860 (throw 'is-using t))))))
861 (unless is-using-multi
862 (if available-multi-libs
863 (if (not (y-or-n-p base-msg))
864 (message "Did not do indentation, but you can try again now if you want")
865 (let* ((name
866 (if (= 1 (length available-multi-libs))
867 (car available-names)
868 ;; Minibuffer window is more than one line, fix that first:
869 (message "")
870 (completing-read "Choose multiple major mode support library: "
871 available-names nil t
872 (car available-names)
873 '(available-names . 1)
874 )))
875 (mode (when name
876 (cl-caddr (assoc name available-multi-libs)))))
877 (when mode
878 ;; Minibuffer window is more than one line, fix that first:
879 (message "")
880 (load name)
881 (funcall mode))))
882 (lwarn 'php-indent :warning base-msg)))
883 nil))))
884
885(defun php-cautious-indent-region (start end &optional quiet)
886 "Carefully indent region `START' `END' in contexts other than HTML templates.
887
888If the optional argument `QUIET' is non-nil then no syntactic errors are
889reported, even if `c-report-syntactic-errors' is non-nil."
890 (if (or (not php-mode-warn-if-mumamo-off)
891 (not (php-in-poly-php-html-mode))
892 php-warned-bad-indent
893 (php-check-html-for-indentation))
894 (funcall 'c-indent-region start end quiet)))
895
896(defun php-cautious-indent-line ()
897 "Carefully indent lines in contexts other than HTML templates."
898 (if (or (not php-mode-warn-if-mumamo-off)
899 (not (php-in-poly-php-html-mode))
900 php-warned-bad-indent
901 (php-check-html-for-indentation))
902 (let ((here (point))
903 doit)
904 (move-beginning-of-line nil)
905 ;; Don't indent heredoc end mark
906 (save-match-data
907 (unless (and (looking-at "[a-zA-Z0-9_]+;\n")
908 (php-in-string-p))
909 (setq doit t)))
910 (goto-char here)
911 (when doit
912 (funcall 'c-indent-line)))))
913
914(defun php-c-at-vsemi-p (&optional pos)
915 "Return t on html lines (including php region border), otherwise nil.
916POS is a position on the line in question.
917
918This is was done due to the problem reported here:
919
920 URL `https://answers.launchpad.net/nxhtml/+question/43320'"
921 (if (not php-template-compatibility)
922 nil
923 (setq pos (or pos (point)))
924 (let ((here (point))
925 ret)
926 (save-match-data
927 (goto-char pos)
928 (beginning-of-line)
929 (setq ret (looking-at
930 (rx
931 (or (seq
932 bol
933 (0+ space)
934 "<"
935 (in "a-z\\?"))
936 (seq
937 (0+ not-newline)
938 (in "a-z\\?")
939 ">"
940 (0+ space)
941 eol))))))
942 (goto-char here)
943 ret)))
944
945(defun php-c-vsemi-status-unknown-p ()
946 "Always return NIL. See `php-c-at-vsemi-p'."
947 nil)
948
949(defun php-lineup-string-cont (langelem)
950 "Line up string toward equal sign or dot.
951e.g.
952$str = 'some'
953 . 'string';
954this ^ lineup"
955 (save-excursion
956 (goto-char (cdr langelem))
957 (let (ret finish)
958 (while (and (not finish) (re-search-forward "[=.]" (line-end-position) t))
959 (unless (php-in-string-or-comment-p)
960 (setq finish t
961 ret (vector (1- (current-column))))))
962 ret)))
963
964(defun php-lineup-arglist-intro (langelem)
965 (save-excursion
966 (goto-char (cdr langelem))
967 (vector (+ (current-column) c-basic-offset))))
968
969(defun php-lineup-arglist-close (langelem)
970 (save-excursion
971 (goto-char (cdr langelem))
972 (vector (current-column))))
973
974(defun php-lineup-arglist (_langelem)
975 (save-excursion
976 (beginning-of-line)
977 (if (looking-at-p "\\s-*->") '+ 0)))
978
979(defun php-lineup-hanging-semicolon (_langelem)
980 (save-excursion
981 (beginning-of-line)
982 (if (looking-at-p "\\s-*;\\s-*$") 0 '+)))
983
984(eval-and-compile
985 (defconst php-heredoc-start-re
986 "<<<\\(?:\\_<.+?\\_>\\|'\\_<.+?\\_>'\\|\"\\_<.+?\\_>\"\\)$"
987 "Regular expression for the start of a PHP heredoc."))
988
989(defun php-heredoc-end-re (heredoc-start)
990 "Build a regular expression for the end of a heredoc started by the string HEREDOC-START."
991 ;; Extract just the identifier without <<< and quotes.
992 (string-match "\\_<.+?\\_>" heredoc-start)
993 (concat "^\\s-*\\(" (match-string 0 heredoc-start) "\\)\\W"))
994
995(defun php-syntax-propertize-function (start end)
996 "Apply propertize rules from START to END."
997 (goto-char start)
998 (while (and (< (point) end)
999 (re-search-forward php-heredoc-start-re end t))
1000 (php-heredoc-syntax))
1001 (goto-char start)
1002 (while (re-search-forward "['\"]" end t)
1003 (when (php-in-comment-p)
1004 (c-put-char-property (match-beginning 0)
1005 'syntax-table (string-to-syntax "_")))))
1006
1007(defun php-heredoc-syntax ()
1008 "Mark the boundaries of searched heredoc."
1009 (goto-char (match-beginning 0))
1010 (c-put-char-property (point) 'syntax-table (string-to-syntax "|"))
1011 (if (re-search-forward (php-heredoc-end-re (match-string 0)) nil t)
1012 (goto-char (match-end 1))
1013 ;; Did not find the delimiter so go to the end of the buffer.
1014 (goto-char (point-max)))
1015 (c-put-char-property (1- (point)) 'syntax-table (string-to-syntax "|")))
1016
1017(defvar-local php-mode--propertize-extend-region-current nil
1018 "Prevent undesirable recursion in PHP-SYNTAX-PROPERTIZE-EXTEND-REGION")
1019
1020(defun php-syntax-propertize-extend-region (start end)
1021 "Extend the propertize region if START or END falls inside a PHP heredoc."
1022 (let ((pair (cons start end)))
1023 (when (not (member pair php-mode--propertize-extend-region-current))
1024 ;; re-search functions may trigger
1025 ;; syntax-propertize-extend-region-functions to be called again, which in
1026 ;; turn call this to be called again.
1027 (push pair php-mode--propertize-extend-region-current)
1028 (unwind-protect
1029 (let ((new-start)
1030 (new-end))
1031 (goto-char start)
1032 (when (re-search-backward php-heredoc-start-re nil t)
1033 (let ((maybe (point)))
1034 (when (and (re-search-forward (php-heredoc-end-re (match-string 0)) nil t)
1035 (> (point) start))
1036 (setq new-start maybe))))
1037 (goto-char end)
1038 (when (re-search-backward php-heredoc-start-re nil t)
1039 (if (re-search-forward (php-heredoc-end-re (match-string 0)) nil t)
1040 (when (> (point) end)
1041 (setq new-end (point)))
1042 (setq new-end (point-max))))
1043 (when (or new-start new-end)
1044 (cons (or new-start start) (or new-end end))))
1045 ;; Cleanup
1046 (setq php-mode--propertize-extend-region-current
1047 (delete pair php-mode--propertize-extend-region-current))))))
1048
1049(easy-menu-define php-mode-menu php-mode-map "PHP Mode Commands"
1050 (cons "PHP" (c-lang-const c-mode-menu php)))
1051
1052(defun php-mode-get-style-alist ()
1053 "Return an alist consisting of `php' style and styles that inherit it."
1054 (cl-loop for l in c-style-alist
1055 if (or (string= (car l) "php")
1056 (equal (cadr l) "php"))
1057 collect l))
1058
1059(defvar php-mode-set-style-history nil)
1060(defvar-local php-mode--delayed-set-style nil)
1061(defvar-local php-style-delete-trailing-whitespace nil)
1062
1063(defun php-set-style (stylename &optional dont-override)
1064 "Set the current `php-mode' buffer to use the style STYLENAME.
1065STYLENAME is one of the names selectable in `php-mode-coding-style'.
1066
1067Borrow the `interactive-form' from `c-set-style' and use the original
1068`c-set-style' function to set all declared stylevars.
1069For compatibility with `c-set-style' pass DONT-OVERRIDE to it.
1070
1071After setting the stylevars run hooks according to STYLENAME
1072
1073 \"pear\" `php-mode-pear-hook'
1074 \"drupal\" `php-mode-drupal-hook'
1075 \"wordpress\" `php-mode-wordpress-hook'
1076 \"symfony2\" `php-mode-symfony2-hook'
1077 \"psr2\" `php-mode-psr2-hook'"
1078 (interactive
1079 (list (let ((completion-ignore-case t)
1080 (prompt (format "Which %s indentation style? "
1081 mode-name)))
1082 (completing-read prompt
1083 (php-mode-get-style-alist)
1084 nil t nil
1085 'php-mode-set-style-history
1086 c-indentation-style))))
1087 (php-mode--disable-delay-set-style)
1088
1089 ;; Back up manually set variables
1090 (let* (value
1091 (backup-vars
1092 (and php-mode-enable-backup-style-variables
1093 (cl-loop for name in c-style-variables
1094 do (setq value (symbol-value name))
1095 if (and value (not (eq 'set-from-style value)))
1096 collect (cons name value)))))
1097 (c-set-style stylename dont-override)
1098 ;; Restore variables
1099 (cl-loop for (name . value) in backup-vars
1100 do (set (make-local-variable name) value)))
1101
1102 (if (eq (symbol-value 'php-style-delete-trailing-whitespace) t)
1103 (add-hook 'before-save-hook 'delete-trailing-whitespace nil t)
1104 (remove-hook 'before-save-hook 'delete-trailing-whitespace t))
1105 (cond ((equal stylename "pear") (run-hooks 'php-mode-pear-hook))
1106 ((equal stylename "drupal") (run-hooks 'php-mode-drupal-hook))
1107 ((equal stylename "wordpress") (run-hooks 'php-mode-wordpress-hook))
1108 ((equal stylename "symfony2") (run-hooks 'php-mode-symfony2-hook))
1109 ((equal stylename "psr2") (run-hooks 'php-mode-psr2-hook))))
1110
1111(defun php-mode--disable-delay-set-style (&rest args)
1112 "Disable php-mode-set-style-delay on after hook. `ARGS' be ignore."
1113 (setq php-mode--delayed-set-style nil)
1114 (when (fboundp 'advice-remove)
1115 (advice-remove #'php-mode--disable-delay-set-style #'c-set-style)))
1116
1117(defun php-mode-set-style-delay ()
1118 "Set the current `php-mode' buffer to use the style by custom or local variables."
1119 (when php-mode--delayed-set-style
1120 (let ((coding-style (or (and (boundp 'php-project-coding-style) php-project-coding-style)
1121 php-mode-coding-style)))
1122 (prog1 (when coding-style
1123 (php-set-style (symbol-name coding-style)))
1124 (remove-hook 'hack-local-variables-hook #'php-mode-set-style-delay)))))
1125
1126(defun php-mode-set-local-variable-delay ()
1127 "Set local variable from php-project."
1128 (php-project-apply-local-variables)
1129 (remove-hook 'hack-local-variables-hook #'php-mode-set-local-variable-delay))
1130
1131(defvar php-mode-syntax-table
1132 (let ((table (make-syntax-table)))
1133 (c-populate-syntax-table table)
1134 (modify-syntax-entry ?_ "_" table)
1135 (modify-syntax-entry ?` "\"" table)
1136 (modify-syntax-entry ?\" "\"" table)
1137 (modify-syntax-entry ?# "< b" table)
1138 (modify-syntax-entry ?\n "> b" table)
1139 (modify-syntax-entry ?$ "_" table)
1140 table))
1141
1142;;;###autoload
1143(define-derived-mode php-mode c-mode "PHP"
1144 "Major mode for editing PHP code.
1145
1146\\{php-mode-map}"
1147 :syntax-table php-mode-syntax-table
1148 ;; :after-hook (c-update-modeline)
1149 ;; (setq abbrev-mode t)
1150 (when php-mode-disable-c-mode-hook
1151 (setq-local c-mode-hook nil)
1152 (setq-local java-mode-hook nil))
1153 (c-initialize-cc-mode t)
1154 (c-init-language-vars php-mode)
1155 (c-common-init 'php-mode)
1156
1157 (setq-local comment-start "// ")
1158 (setq-local comment-start-skip
1159 (eval-when-compile
1160 (rx (group (or (: "#")
1161 (: "/" (+ "/"))
1162 (: "/*")))
1163 (* (syntax whitespace)))))
1164 (setq-local comment-end "")
1165 (setq-local page-delimiter php-mode-page-delimiter)
1166
1167 (setq-local font-lock-string-face 'php-string)
1168 (setq-local font-lock-keyword-face 'php-keyword)
1169 (setq-local font-lock-builtin-face 'php-builtin)
1170 (setq-local c-preprocessor-face-name 'php-php-tag)
1171 (setq-local font-lock-function-name-face 'php-function-name)
1172 (setq-local font-lock-variable-name-face 'php-variable-name)
1173 (setq-local font-lock-constant-face 'php-constant)
1174
1175 (setq-local syntax-propertize-function #'php-syntax-propertize-function)
1176 (add-hook 'syntax-propertize-extend-region-functions
1177 #'php-syntax-propertize-extend-region t t)
1178
1179 (setq imenu-generic-expression php-imenu-generic-expression)
1180
1181 ;; PHP vars are case-sensitive
1182 (setq case-fold-search t)
1183
1184 (when php-mode-enable-project-local-variable
1185 (add-hook 'hack-local-variables-hook #'php-mode-set-local-variable-delay t t))
1186
1187 ;; When php-mode-enable-project-coding-style is set, it is delayed by hook.
1188 ;; Since it depends on the timing at which the file local variable is set.
1189 ;; File local variables are set after initialization of major mode except `run-hook' is complete.
1190 (if php-mode-enable-project-coding-style
1191 (progn
1192 (add-hook 'hack-local-variables-hook #'php-mode-set-style-delay t t)
1193 (setq php-mode--delayed-set-style t)
1194 (when (fboundp 'advice-add)
1195 (advice-add #'c-set-style :after #'php-mode--disable-delay-set-style '(local))))
1196 (let ((php-mode-enable-backup-style-variables nil))
1197 (php-set-style (symbol-name php-mode-coding-style))))
1198
1199 (when (or php-mode-force-pear
1200 (and (stringp buffer-file-name)
1201 (string-match "PEAR\\|pear" buffer-file-name)
1202 (string-match "\\.php\\'" buffer-file-name)))
1203 (php-set-style "pear"))
1204
1205 (setq indent-line-function 'php-cautious-indent-line)
1206 (setq indent-region-function 'php-cautious-indent-region)
1207 (setq c-at-vsemi-p-fn #'php-c-at-vsemi-p)
1208 (setq c-vsemi-status-unknown-p-fn #'php-c-vsemi-status-unknown-p)
1209
1210 ;; We map the php-{beginning,end}-of-defun functions so that they
1211 ;; replace the similar commands that we inherit from CC Mode.
1212 ;; Because of our remapping we may not actually need to keep the
1213 ;; following two local variables, but we keep them for now until we
1214 ;; are completely sure their removal will not break any current
1215 ;; behavior or backwards compatibility.
1216 (setq-local beginning-of-defun-function 'php-beginning-of-defun)
1217 (setq-local end-of-defun-function 'php-end-of-defun)
1218
1219 (setq-local open-paren-in-column-0-is-defun-start nil)
1220 (setq-local defun-prompt-regexp
1221 "^\\s-*function\\s-+&?\\s-*\\(\\(\\sw\\|\\s_\\)+\\)\\s-*")
1222 (setq-local add-log-current-defun-header-regexp
1223 php-beginning-of-defun-regexp)
1224
1225 (when (>= emacs-major-version 25)
1226 (with-silent-modifications
1227 (save-excursion
1228 (let* ((start (point-min))
1229 (end (min (point-max)
1230 (+ start syntax-propertize-chunk-size))))
1231 (php-syntax-propertize-function start end))))))
1232
1233(declare-function semantic-create-imenu-index "semantic/imenu" (&optional stream))
1234
1235(defvar-mode-local php-mode imenu-create-index-function
1236 (if php-do-not-use-semantic-imenu
1237 #'imenu-default-create-index-function
1238 (require 'semantic/imenu)
1239 #'semantic-create-imenu-index)
1240 "Imenu index function for PHP.")
1241
1242
1243;; Define function name completion function
1244(defvar php-completion-table nil
1245 "Obarray of tag names defined in current tags table and functions known to PHP.")
1246
1247(defun php-complete-function ()
1248 "Perform function completion on the text around point.
1249Completes to the set of names listed in the current tags table
1250and the standard php functions.
1251The string to complete is chosen in the same way as the default
1252for \\[find-tag] (which see)."
1253 (interactive)
1254 (let ((pattern (php-get-pattern))
1255 beg
1256 completion
1257 (php-functions (php-completion-table)))
1258 (if (not pattern) (message "Nothing to complete")
1259 (if (not (search-backward pattern nil t))
1260 (message "Can't complete here")
1261 (setq beg (point))
1262 (forward-char (length pattern))
1263 (setq completion (try-completion pattern php-functions nil))
1264 (cond ((eq completion t))
1265 ((null completion)
1266 (message "Can't find completion for \"%s\"" pattern)
1267 (ding))
1268 ((not (string= pattern completion))
1269 (delete-region beg (point))
1270 (insert completion))
1271 (t
1272 (let ((selected (completing-read
1273 "Select completion: "
1274 (all-completions pattern php-functions)
1275 nil t pattern)))
1276 (delete-region beg (point))
1277 (insert selected))))))))
1278
1279(defun php-completion-table ()
1280 "Build variable `php-completion-table' on demand.
1281The table includes the PHP functions and the tags from the
1282current `tags-file-name'."
1283 (or (and tags-file-name
1284 (save-excursion (tags-verify-table tags-file-name))
1285 php-completion-table)
1286 (let ((tags-table
1287 (when tags-file-name
1288 (with-current-buffer (get-file-buffer tags-file-name)
1289 (etags-tags-completion-table))))
1290 (php-table
1291 (cond ((and (not (string= "" php-completion-file))
1292 (file-readable-p php-completion-file))
1293 (php-build-table-from-file php-completion-file))
1294 ((and (not (string= "" php-manual-path))
1295 (file-directory-p php-manual-path))
1296 (php-build-table-from-path php-manual-path))
1297 (t nil))))
1298 (unless (or php-table tags-table)
1299 (error
1300 (concat "No TAGS file active nor are "
1301 "`php-completion-file' or `php-manual-path' set")))
1302 (when tags-table
1303 ;; Combine the tables.
1304 (if (obarrayp tags-table)
1305 (mapatoms (lambda (sym) (intern (symbol-name sym) php-table))
1306 tags-table)
1307 (setq php-table (append tags-table php-table))))
1308 (setq php-completion-table php-table))))
1309
1310(defun php-build-table-from-file (filename)
1311 (let ((table (make-vector 1022 0))
1312 (buf (find-file-noselect filename)))
1313 (with-current-buffer buf
1314 (goto-char (point-min))
1315 (while (re-search-forward
1316 "^\\([-a-zA-Z0-9_.]+\\)\n"
1317 nil t)
1318 (intern (buffer-substring (match-beginning 1) (match-end 1))
1319 table)))
1320 (kill-buffer buf)
1321 table))
1322
1323(defun php-build-table-from-path (path)
1324 "Return list of PHP function name from `PATH' directory."
1325 (cl-loop for file in (directory-files path nil "^function\\..+\\.html$")
1326 if (string-match "\\.\\([-a-zA-Z_0-9]+\\)\\.html$" file)
1327 collect (replace-regexp-in-string
1328 "-" "_" (substring file (match-beginning 1) (match-end 1)) t)))
1329
1330;; Find the pattern we want to complete
1331;; find-tag-default from GNU Emacs etags.el
1332(defun php-get-pattern ()
1333 (save-excursion
1334 (while (looking-at "\\sw\\|\\s_")
1335 (forward-char 1))
1336 (if (or (re-search-backward "\\sw\\|\\s_"
1337 (save-excursion (beginning-of-line) (point))
1338 t)
1339 (re-search-forward "\\(\\sw\\|\\s_\\)+"
1340 (save-excursion (end-of-line) (point))
1341 t))
1342 (progn (goto-char (match-end 0))
1343 (buffer-substring-no-properties
1344 (point)
1345 (progn (forward-sexp -1)
1346 (while (looking-at "\\s'")
1347 (forward-char 1))
1348 (point))))
1349 nil)))
1350
1351(defun php-show-arglist ()
1352 "Show function arguments at cursor position."
1353 (interactive)
1354 (let* ((tagname (php-get-pattern))
1355 (buf (find-tag-noselect tagname nil nil))
1356 arglist)
1357 (with-current-buffer buf
1358 (save-excursion
1359 (goto-char (point-min))
1360 (when (re-search-forward
1361 (format "function\\s-+%s\\s-*(\\([^{]*\\))" tagname)
1362 nil t)
1363 (setq arglist (buffer-substring-no-properties
1364 (match-beginning 1) (match-end 1))))))
1365 (if arglist
1366 (message "Arglist for %s: %s" tagname arglist)
1367 (message "Unknown function: %s" tagname))))
1368
1369(defcustom php-search-documentation-browser-function nil
1370 "Function to display PHP documentation in a WWW browser.
1371
1372If non-nil, this shadows the value of `browse-url-browser-function' when
1373calling `php-search-documentation' or `php-search-local-documentation'."
1374 :group 'php
1375 :tag "PHP Search Documentation Browser Function"
1376 :type '(choice (const :tag "default" nil) function)
1377 :link '(variable-link browse-url-browser-function))
1378
1379(defun php-browse-documentation-url (url)
1380 "Browse a documentation URL using the configured browser function.
1381
1382See `php-search-documentation-browser-function'."
1383 (let ((browse-url-browser-function
1384 (or php-search-documentation-browser-function
1385 browse-url-browser-function)))
1386 (browse-url url)))
1387
1388(defvar php-search-local-documentation-types
1389 (list "function" "control-structures" "class" "book")
1390 ;; "intro" and "ref" also look interesting, but for all practical purposes
1391 ;; their terms are sub-sets of the "book" terms (with the few exceptions
1392 ;; being very unlikely search terms).
1393 "The set (and priority sequence) of documentation file prefixes
1394under which to search for files in the local documentation directory.")
1395
1396(defvar php-search-local-documentation-words-cache nil)
1397
1398(defun php--search-documentation-read-arg ()
1399 "Obtain interactive argument for searching documentation."
1400 ;; Cache the list of documentation words available for completion,
1401 ;; based on the defined types-of-interest.
1402 (let ((types-list php-search-local-documentation-types)
1403 (words-cache php-search-local-documentation-words-cache)
1404 (local-manual (and (stringp php-manual-path)
1405 (not (string= php-manual-path "")))))
1406 (when (and local-manual
1407 (not (assq types-list words-cache)))
1408 ;; Generate the cache on the first run, or if the types changed.
1409 ;; We read the filenames matching our types list in the local
1410 ;; documentation directory, and extract the 'middle' component
1411 ;; of each. e.g. "function.array-map.html" => "array_map".
1412 (let* ((types-opt (regexp-opt types-list))
1413 (pattern (concat "\\`" types-opt "\\.\\(.+\\)\\.html\\'"))
1414 (collection
1415 (mapcar (lambda (filename) (subst-char-in-string
1416 ?- ?_ (replace-regexp-in-string
1417 pattern "\\1" filename)))
1418 (directory-files php-manual-path nil pattern))))
1419 ;; Replace the entire cache. If the types changed, we don't need
1420 ;; to retain the collection for the previous value.
1421 (setq words-cache (list (cons types-list collection)))
1422 (setq php-search-local-documentation-words-cache words-cache)))
1423 ;; By default we search for (current-word) immediately, without prompting.
1424 ;; With a prefix argument, or if there is no (current-word), we perform a
1425 ;; completing read for a word from the cached collection.
1426 (let* ((default (current-word))
1427 (prompt (if default
1428 (format "Search PHP docs (%s): " default)
1429 "Search PHP docs: "))
1430 (collection (and local-manual
1431 (cdr (assq types-list words-cache))))
1432 (word (if (or current-prefix-arg (not default))
1433 (completing-read prompt collection nil nil nil nil default)
1434 default)))
1435 ;; Return interactive argument list.
1436 (list word))))
1437
1438(defun php-search-local-documentation (word)
1439 "Search the local PHP documentation (i.e. in `php-manual-path') for
1440the word at point. The function returns t if the requested documentation
1441exists, and nil otherwise.
1442
1443With a prefix argument, prompt (with completion) for a word to search for."
1444 (interactive (php--search-documentation-read-arg))
1445 (let ((file (catch 'found
1446 (cl-loop for type in php-search-local-documentation-types do
1447 (let* ((doc-html (format "%s.%s.html"
1448 type
1449 (replace-regexp-in-string
1450 "_" "-" (downcase word))))
1451 (file (expand-file-name doc-html php-manual-path)))
1452 (when (file-exists-p file)
1453 (throw 'found file)))))))
1454 (when file
1455 (let ((file-url (if (string-prefix-p "file://" file)
1456 file
1457 (concat "file://" file))))
1458 (php-browse-documentation-url file-url))
1459 t)))
1460
1461(defsubst php-search-web-documentation (word)
1462 "Return URL to search PHP manual search by `WORD'."
1463 (php-browse-documentation-url (concat (or php-search-url php-site-url) word)))
1464
1465;; Define function documentation function
1466(defun php-search-documentation (word)
1467 "Search PHP documentation for the `WORD' at point.
1468
1469If `php-manual-path' has a non-empty string value then the command
1470will first try searching the local documentation. If the requested
1471documentation does not exist it will fallback to searching the PHP
1472website.
1473
1474With a prefix argument, prompt for a documentation word to search
1475for. If the local documentation is available, it is used to build
1476a completion list."
1477 (interactive (php--search-documentation-read-arg))
1478 (if (and (stringp php-manual-path)
1479 (not (string= php-manual-path "")))
1480 (or (php-search-local-documentation word)
1481 (php-search-web-documentation word))
1482 (php-search-web-documentation word)))
1483
1484;; Define function for browsing manual
1485(defun php-browse-manual ()
1486 "Bring up manual for PHP."
1487 (interactive)
1488 (browse-url (if (stringp php-manual-url)
1489 php-manual-url
1490 (format "%smanual/%s/" php-site-url php-manual-url))))
1491
1492
1493;; Font Lock
1494(defconst php-phpdoc-type-keywords
1495 (list "string" "integer" "int" "boolean" "bool" "float"
1496 "double" "object" "mixed" "array" "resource"
1497 "void" "null" "false" "true" "self" "static"
1498 "callable" "iterable" "number"))
1499
1500(defconst php-phpdoc-type-tags
1501 (list "package" "param" "property" "property-read" "property-write"
1502 "return" "throws" "var"))
1503
1504(defconst php-phpdoc-font-lock-doc-comments
1505 `(("{@[-[:alpha:]]+\\s-*\\([^}]*\\)}" ; "{@foo ...}" markup.
1506 (0 'php-doc-annotation-tag prepend nil)
1507 (1 'php-string prepend nil))
1508 (,(rx (group "$") (group (in "A-Za-z_") (* (in "0-9A-Za-z_"))))
1509 (1 'php-doc-variable-sigil prepend nil)
1510 (2 'php-variable-name prepend nil))
1511 ("\\(\\$\\)\\(this\\)\\>" (1 'php-doc-$this-sigil prepend nil) (2 'php-doc-$this prepend nil))
1512 (,(concat "\\s-@" (regexp-opt php-phpdoc-type-tags) "\\s-+"
1513 "\\(" (rx (+ (? "?") (? "\\") (+ (in "0-9A-Z_a-z")) (? "[]") (? "|"))) "\\)+")
1514 1 'php-string prepend nil)
1515 (,(concat "\\(?:|\\|\\?\\|\\s-\\)\\("
1516 (regexp-opt php-phpdoc-type-keywords 'words)
1517 "\\)")
1518 1 font-lock-type-face prepend nil)
1519 ("https?://[^\n\t ]+"
1520 0 'link prepend nil)
1521 ("^\\(?:/\\*\\)?\\(?:\\s \\|\\*\\)*\\(@[[:alpha:]][-[:alpha:]\\]*\\)" ; "@foo ..." markup.
1522 1 'php-doc-annotation-tag prepend nil)))
1523
1524(defvar php-phpdoc-font-lock-keywords
1525 `((,(lambda (limit)
1526 (c-font-lock-doc-comments "/\\*\\*" limit
1527 php-phpdoc-font-lock-doc-comments)))))
1528
1529(defconst php-font-lock-keywords-1 (c-lang-const c-matchers-1 php)
1530 "Basic highlighting for PHP Mode.")
1531
1532(defconst php-font-lock-keywords-2 (c-lang-const c-matchers-2 php)
1533 "Medium level highlighting for PHP Mode.")
1534
1535(defconst php-font-lock-keywords-3
1536 (append
1537 php-phpdoc-font-lock-keywords
1538 ;; php-mode patterns *before* cc-mode:
1539 ;; only add patterns here if you want to prevent cc-mode from applying
1540 ;; a different face.
1541 `(
1542 ;; Highlight variables, e.g. 'var' in '$var' and '$obj->var', but
1543 ;; not in $obj->var()
1544 ("\\(->\\)\\(\\sw+\\)\\s-*(" (1 'php-object-op) (2 'php-method-call))
1545 ("\\<\\(const\\)\\s-+\\(\\_<.+?\\_>\\)" (1 'php-keyword) (2 'php-constant-assign))
1546
1547 ;; Logical operator (!)
1548 ("\\(![^=]\\)" 1 'php-logical-op)
1549
1550 ;; Highlight special variables
1551 ("\\(\\$\\)\\(this\\)\\>" (1 'php-$this-sigil) (2 'php-$this))
1552 ("\\(\\$+\\)\\(\\sw+\\)" (1 'php-variable-sigil) (2 'php-variable-name))
1553 ("\\(->\\)\\([a-zA-Z0-9_]+\\)" (1 'php-object-op) (2 'php-property-name))
1554
1555 ;; Highlight function/method names
1556 ("\\<function\\s-+&?\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1 'php-function-name)
1557
1558 ;; 'array' and 'callable' are keywords, except in the following situations:
1559 ;; - when used as a type hint
1560 ;; - when used as a return type
1561 ("\\b\\(array\\|callable\\)\\s-+&?\\$" 1 font-lock-type-face)
1562 (")\\s-*:\\s-*\\??\\(array\\|callable\\)\\b" 1 font-lock-type-face)
1563 ;; For 'array', there is an additional situation:
1564 ;; - when used as cast, so that (int) and (array) look the same
1565 ("(\\(array\\))" 1 font-lock-type-face)
1566
1567 (,(regexp-opt php-magical-constants 'symbols) (1 'php-magical-constant))
1568 ;; namespaces
1569 ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)[^:a-zA-Z0-9_\\\\]" 1 'font-lock-type-face)
1570 ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)::" 1 'php-constant)
1571 (,(eval-when-compile
1572 (rx bol (* (syntax whitespace))
1573 (or "private" "protected" "public")
1574 (+ (syntax whitespace))
1575 (group (? "?") (+ (or "\\" (syntax word) (syntax symbol))))
1576 (+ (syntax whitespace))
1577 (: "$" (+ (or (syntax word) (syntax symbol))))))
1578 1 'php-class)
1579 ;; Support the ::class constant in PHP5.6
1580 ("\\sw+\\(::\\)\\(class\\)\\b" (1 'php-paamayim-nekudotayim) (2 'php-magical-constant))
1581
1582 ;; Highlight static method calls as such. This is necessary for method
1583 ;; names which are identical to keywords to be highlighted correctly.
1584 ("\\sw+::\\(\\sw+\\)(" 1 'php-static-method-call)
1585 ;; Multiple catch (FooException | BarException $e)
1586 (,(rx symbol-start "catch" symbol-end
1587 (* (syntax whitespace)) "(" (* (syntax whitespace))
1588 (group (+ (or (syntax word) (syntax symbol)))))
1589 (1 font-lock-type-face)
1590 (,(rx (* (syntax whitespace)) "|" (* (syntax whitespace))
1591 (group (+ (or (syntax word) (syntax symbol))) symbol-end))
1592 nil nil (1 font-lock-type-face)))
1593 ;; While c-opt-cpp-* highlights the <?php opening tags, it is not
1594 ;; possible to make it highlight short open tags and closing tags
1595 ;; as well. So we force the correct face on all cases that
1596 ;; c-opt-cpp-* lacks for this purpose.
1597 ;;
1598 ;; Note that starting a file with <% breaks indentation, a
1599 ;; limitation we can/should live with.
1600 (,(regexp-opt '("<?php" "<?=" "?>"
1601 "<?" ;; obsolete short open tag
1602 "<%" "%>" ;; obsolete ASP tag
1603 ;; Obsoleted tags were deleted in PHP 7.
1604 ;; @see http://php.net/manual/language.basic-syntax.phptags.php
1605 ))
1606 0 'php-php-tag))
1607
1608 ;; cc-mode patterns
1609 (c-lang-const c-matchers-3 php)
1610
1611 ;; php-mode patterns *after* cc-mode:
1612 ;; most patterns should go here, faces will only be applied if not
1613 ;; already fontified by another pattern. Note that using OVERRIDE
1614 ;; is usually overkill.
1615 `(
1616 ("\\<\\(@\\)" 1 'php-errorcontrol-op)
1617 ;; Highlight function calls
1618 ("\\(\\_<\\(?:\\sw\\|\\s_\\)+?\\_>\\)\\s-*(" 1 'php-function-call)
1619 ;; Highlight all upper-cased symbols as constant
1620 ("\\<\\([A-Z_][A-Z0-9_]+\\)\\>" 1 'php-constant)
1621
1622 ;; Highlight all statically accessed class names as constant,
1623 ;; another valid option would be using type-face, but using
1624 ;; constant-face because this is how it works in c++-mode.
1625 ("\\(\\sw+\\)\\(::\\)" (1 'php-constant) (2 'php-paamayim-nekudotayim))
1626
1627 ;; Highlight class name after "use .. as"
1628 ("\\<as\\s-+\\(\\sw+\\)" 1 font-lock-type-face)
1629
1630 ;; Class names are highlighted by cc-mode as defined in
1631 ;; c-class-decl-kwds, below regexp is a workaround for a bug
1632 ;; where the class names are not highlighted right after opening
1633 ;; a buffer (editing a file corrects it).
1634 ;;
1635 ;; This behaviour is caused by the preceding '<?php', which
1636 ;; cc-mode cannot handle easily. Registering it as a cpp
1637 ;; preprocessor works well (i.e. the next line is not a
1638 ;; statement-cont) but the highlighting glitch remains.
1639 (,(concat (regexp-opt (c-lang-const c-class-decl-kwds php))
1640 " \\(\\sw+\\)")
1641 1 font-lock-type-face)
1642
1643 ;; Highlight the ? character for nullable return types.
1644 ("function.+:\\s-*\\(\\?\\)\\(?:\\sw\\|\\s_\\|\\\\\\)+" 1 font-lock-type-face)
1645 (")\\s-*:\\s-*\\(\\?\\)\\(?:\\sw\\|\\s_\\|\\\\\\)+\\s-*\\(?:\{\\|;\\)" 1 font-lock-type-face)
1646
1647 ;; Highlight the ? character for nullable type hints.
1648 ("\\(\\?\\)\\(:?\\sw\\|\\s_\\|\\\\\\)+\\s-+\\$" 1 font-lock-type-face)
1649
1650 ;; Class names without a namespace are not highlighted at all when they
1651 ;; are used as nullable type hints or return types (both nullable and
1652 ;; non-nullable). We have to use separate regular expressions, because
1653 ;; we want to capture the class name as well, not just the ? character
1654 ;; like the regexps above.
1655 ("\\?\\(\\(:?\\sw\\|\\s_\\)+\\)\\s-+\\$" 1 font-lock-type-face)
1656 ("function.+:\\s-*\\??\\(\\(?:\\sw\\|\\s_\\)+\\)" 1 font-lock-type-face)
1657 (")\\s-*:\\s-*\\??\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*\\(?:\{\\|;\\)" 1 font-lock-type-face)
1658
1659 ;; Assignment operators (=, +=, ...)
1660 ("\\([^=<!>]+?\\([\-+./%]?=\\)[^=<!>]+?\\)" 2 'php-assignment-op)
1661
1662 ;; Comparison operators (==, ===, >=, ...)
1663 ("\\([!=]=\\{1,2\\}[>]?\\|[<>]=?\\)" 1 'php-comparison-op)
1664
1665 ;; Arithmetic operators (+, -, *, **, /, %)
1666 ("\\(?:[A-Za-z0-9[:blank:]]\\)\\([\-+*/%]\\*?\\)\\(?:[A-Za-z0-9[:blank:]]\\)" 1 'php-arithmetic-op)
1667
1668 ;; Increment and Decrement operators (++, --)
1669 ("\\(\-\-\\|\+\+\\)\$\\w+" 1 'php-inc-dec-op) ;; pre inc/dec
1670 ("\$\\w+\\(\-\-\\|\+\+\\)" 1 'php-inc-dec-op) ;; post inc/dec
1671
1672 ;; Logical operators (and, or, &&, ...)
1673 ;; Not operator (!) is defined in "before cc-mode" section above.
1674 ("\\(&&\\|||\\)" 1 'php-logical-op)))
1675 "Detailed highlighting for PHP Mode.")
1676
1677(defvar php-font-lock-keywords php-font-lock-keywords-3
1678 "Default expressions to highlight in PHP Mode.")
1679
1680(add-to-list
1681 (eval-when-compile
1682 (if (boundp 'flymake-proc-allowed-file-name-masks)
1683 'flymake-proc-allowed-file-name-masks
1684 'flymake-allowed-file-name-masks))
1685 '("\\.php[345s]?\\'" php-flymake-php-init))
1686
1687
1688(defun php-send-region (start end)
1689 "Send the region between `START' and `END' to PHP for execution.
1690The output will appear in the buffer *PHP*."
1691 (interactive "r")
1692 (let ((php-buffer (get-buffer-create "*PHP*"))
1693 (code (buffer-substring start end)))
1694 ;; Calling 'php -r' will fail if we send it code that starts with
1695 ;; '<?php', which is likely. So we run the code through this
1696 ;; function to check for that prefix and remove it.
1697 (let ((cleaned-php-code (if (string-prefix-p "<?php" code t)
1698 (substring code 5)
1699 code)))
1700 (call-process php-executable nil php-buffer nil "-r" cleaned-php-code))))
1701
1702
1703(defconst php-string-interpolated-variable-regexp
1704 "{\\$[^}\n\\\\]*\\(?:\\\\.[^}\n\\\\]*\\)*}\\|\\${\\sw+}\\|\\$\\sw+")
1705
1706(defun php-string-intepolated-variable-font-lock-find (limit)
1707 (while (re-search-forward php-string-interpolated-variable-regexp limit t)
1708 (let ((quoted-stuff (nth 3 (syntax-ppss))))
1709 (when (and quoted-stuff (member quoted-stuff '(?\" ?`)))
1710 (put-text-property (match-beginning 0) (match-end 0)
1711 'face 'php-variable-name))))
1712 nil)
1713
1714(eval-after-load 'php-mode
1715 '(progn
1716 (font-lock-add-keywords
1717 'php-mode
1718 `((php-string-intepolated-variable-font-lock-find))
1719 'append)))
1720
1721
1722
1723;;; Correct the behavior of `delete-indentation' by modifying the
1724;;; logic of `fixup-whitespace'.
1725(defadvice fixup-whitespace (after php-mode-fixup-whitespace)
1726 "Remove whitespace before certain characters in PHP Mode."
1727 (let* ((no-behind-space ";\\|,\\|->\\|::")
1728 (no-front-space "->\\|::"))
1729 (when (and (eq major-mode 'php-mode)
1730 (or (looking-at-p (concat " \\(" no-behind-space "\\)"))
1731 (save-excursion
1732 (forward-char -2)
1733 (looking-at-p no-front-space))))
1734 (delete-char 1))))
1735
1736(ad-activate 'fixup-whitespace)
1737
1738;;;###autoload
1739(progn
1740 (add-to-list 'auto-mode-alist '("/\\.php_cs\\(?:\\.dist\\)?\\'" . php-mode))
1741 (add-to-list 'auto-mode-alist '("\\.\\(?:php[s345]?\\|phtml\\)\\'" . php-mode-maybe)))
1742
1743(provide 'php-mode)
1744;;; php-mode.el ends here
diff --git a/.emacs.d/lisp/php-project.el b/.emacs.d/lisp/php-project.el
deleted file mode 100644
index 18115cc..0000000
--- a/.emacs.d/lisp/php-project.el
+++ /dev/null
@@ -1,283 +0,0 @@
1;;; php-project.el --- Project support for PHP application -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2018-2019 Friends of Emacs-PHP development
4
5;; Author: USAMI Kenta <tadsan@zonu.me>
6;; Keywords: tools, files
7;; URL: https://github.com/emacs-php/php-mode
8;; Version: 1.22.1
9;; Package-Requires: ((emacs "24.3"))
10;; License: GPL-3.0-or-later
11
12;; This program is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
16
17;; This program is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with this program. If not, see <https://www.gnu.org/licenses/>.
24
25;;; Commentary:
26
27;; Define project specific functions and variables for PHP application.
28;;
29;; ## API
30;;
31;; ### `php-project-get-root-dir()'
32;;
33;; Return root directory of current buffer file. The root directory is
34;; determined by several marker file or directory.
35;;
36;; ### `php-project-get-bootstrap-scripts()'
37;;
38;; Return list of path to bootstrap script file.
39;;
40;; ### `php-project-get-php-executable()'
41;;
42;; Return path to PHP executable file with the project settings overriding.
43;;
44;; ### `php-project-get-phan-executable()'
45;;
46;; Return path to Phan executable file with the project settings overriding.
47;; Phan is a static analyzer and LSP server implementation for PHP.
48;; See https://github.com/phan/phan
49;;
50;; ## `.dir-locals.el' support
51;;
52;; - `php-project-coding-style'
53;; - Symbol value of the coding style. (ex. `pear', `psr2')
54;; - `php-project-root'
55;; - Symbol of marker file of project root. (ex. `git', `composer')
56;; - Full path to project root directory. (ex. "/path/to/your-project")
57;; - `php-project-bootstrap-scripts'
58;; - List of path to bootstrap file of project.
59;; (ex. (((root . "vendor/autoload.php") (root . "inc/bootstrap.php")))
60;; - `php-project-php-executable'
61;; - Path to project specific PHP executable file.
62;; - If you want to use a file different from the system wide `php' command.
63;; - `php-project-phan-executable'
64;; - Path to project specific Phan executable file.
65;; - When not specified explicitly, it is automatically searched from
66;; Composer's dependency of the project and `exec-path'.
67;;
68
69;;; Code:
70(require 'cl-lib)
71
72;; Constants
73(defconst php-project-composer-autoloader "vendor/autoload.php")
74
75;; Custom variables
76(defgroup php-project nil
77 "Major mode for editing PHP code."
78 :tag "PHP Project"
79 :prefix "php-project-"
80 :group 'php)
81
82(defcustom php-project-auto-detect-etags-file nil
83 "If `T', automatically detect etags file when file is opened."
84 :tag "PHP Project Auto Detect Etags File"
85 :group 'php-project
86 :type 'boolean)
87
88;; Variables
89(defvar php-project-available-root-files
90 '((projectile ".projectile")
91 (composer "composer.json" "composer.lock")
92 (git ".git")
93 (mercurial ".hg")
94 (subversion ".svn")
95 ;; NOTICE: This method does not detect the top level of .editorconfig
96 ;; However, we can integrate it by adding the editorconfig.el's API.
97 ;;(editorconfig . ".editorconfig")
98 ))
99
100;; Buffer local variables
101
102;;;###autoload
103(progn
104 (defvar-local php-project-root 'auto
105 "Method of searching for the top level directory.
106
107`auto' (default)
108 Try to search file in order of `php-project-available-root-files'.
109
110SYMBOL
111 Key of `php-project-available-root-files'.
112
113STRING
114 A file/directory name of top level marker.
115 If the string is an actual directory path, it is set as the absolute path
116 of the root directory, not the marker.")
117 (put 'php-project-root 'safe-local-variable
118 #'(lambda (v) (or (stringp v) (assq v php-project-available-root-files))))
119
120 (defvar-local php-project-etags-file nil)
121 (put 'php-project-etags-file 'safe-local-variable
122 #'(lambda (v) (or (functionp v)
123 (eq v t)
124 (php-project--eval-bootstrap-scripts v))))
125
126 (defvar-local php-project-bootstrap-scripts nil
127 "List of path to bootstrap php script file.
128
129The ideal bootstrap file is silent, it only includes dependent files,
130defines constants, and sets the class loaders.")
131 (put 'php-project-bootstrap-scripts 'safe-local-variable #'php-project--eval-bootstrap-scripts)
132
133 (defvar-local php-project-php-executable nil
134 "Path to php executable file.")
135 (put 'php-project-php-executable 'safe-local-variable
136 #'(lambda (v) (and (stringp v) (file-executable-p v))))
137
138 (defvar-local php-project-phan-executable nil
139 "Path to phan executable file.")
140 (put 'php-project-phan-executable 'safe-local-variable #'php-project--eval-bootstrap-scripts)
141
142 (defvar-local php-project-coding-style nil
143 "Symbol value of the coding style of the project that PHP major mode refers to.
144
145Typically it is `pear', `drupal', `wordpress', `symfony2' and `psr2'.")
146 (put 'php-project-coding-style 'safe-local-variable #'symbolp)
147
148 (defvar-local php-project-php-file-as-template 'auto
149 "
150`auto' (default)
151 Automatically switch to mode for template when HTML tag detected in file.
152
153`t'
154 Switch all PHP files in that directory to mode for HTML template.
155
156`nil'
157 Any .php in that directory is just a PHP script.
158
159\(\(PATTERN . SYMBOL))
160 Alist of file name pattern regular expressions and the above symbol pairs.
161 PATTERN is regexp pattern.
162")
163 (put 'php-project-php-file-as-template 'safe-local-variable #'php-project--validate-php-file-as-template)
164
165 (defvar-local php-project-repl nil
166 "Function name or path to REPL (interactive shell) script.")
167 (put 'php-project-repl 'safe-local-variable
168 #'(lambda (v) (or (functionp v)
169 (php-project--eval-bootstrap-scripts v))))
170
171 (defvar-local php-project-unit-test nil
172 "Function name or path to unit test script.")
173 (put 'php-project-unit-test 'safe-local-variable
174 #'(lambda (v) (or (functionp v)
175 (php-project--eval-bootstrap-scripts v))))
176
177 (defvar-local php-project-deploy nil
178 "Function name or path to deploy script.")
179 (put 'php-project-deploy 'safe-local-variable
180 #'(lambda (v) (or (functionp v)
181 (php-project--eval-bootstrap-scripts v))))
182
183 (defvar-local php-project-build nil
184 "Function name or path to build script.")
185 (put 'php-project-build 'safe-local-variable
186 #'(lambda (v) (or (functionp v)
187 (php-project--eval-bootstrap-scripts v))))
188
189 (defvar-local php-project-server-start nil
190 "Function name or path to server-start script.")
191 (put 'php-project-server-start 'safe-local-variable
192 #'(lambda (v) (or (functionp v)
193 (php-project--eval-bootstrap-scripts v)))))
194
195;; Functions
196(defun php-project--validate-php-file-as-template (val)
197 "Return T when `VAL' is valid list of safe ."
198 (cond
199 ((null val) t)
200 ((memq val '(t auto)) t)
201 ((listp val)
202 (cl-loop for v in val
203 always (and (consp v)
204 (stringp (car v))
205 (php-project--validate-php-file-as-template (cdr v)))))
206 (t nil)))
207
208(defun php-project--eval-bootstrap-scripts (val)
209 "Return T when `VAL' is valid list of safe bootstrap php script."
210 (cond
211 ((stringp val) (and (file-exists-p val) val))
212 ((eq 'composer val)
213 (let ((path (expand-file-name php-project-composer-autoloader (php-project-get-root-dir))))
214 (and (file-exists-p path) path)))
215 ((and (consp val) (eq 'root (car val)) (stringp (cdr val)))
216 (let ((path (expand-file-name (cdr val) (php-project-get-root-dir))))
217 (and (file-exists-p path) path)))
218 ((null val) nil)
219 ((listp val)
220 (cl-loop for v in val collect (php-project--eval-bootstrap-scripts v)))
221 (t nil)))
222
223(defun php-project-get-php-executable ()
224 "Return path to PHP executable file."
225 (cond
226 ((and (stringp php-project-php-executable)
227 (file-executable-p php-project-php-executable))
228 php-project-php-executable)
229 ((boundp 'php-executable) php-executable)
230 (t (executable-find "php"))))
231
232(defun php-project-get-phan-executable ()
233 "Return path to phan executable file."
234 (or (car-safe (php-project--eval-bootstrap-scripts
235 (list php-project-phan-executable
236 (cons 'root "vendor/bin/phan"))))
237 (executable-find "phan")))
238
239(defun php-project-get-file-html-template-type (filename)
240 "Return symbol T, NIL or `auto' by `FILENAME'."
241 (cond
242 ((not php-project-php-file-as-template) nil)
243 ((eq t php-project-php-file-as-template) t)
244 ((eq 'auto php-project-php-file-as-template) 'auto)
245 ((listp php-project-php-file-as-template)
246 (assoc-default filename php-project-php-file-as-template #'string-match-p))
247 (t (prog1 nil
248 (warn "php-project-php-file-as-template is unexpected format")))))
249
250(defun php-project-apply-local-variables ()
251 "Apply php-project variables to local variables."
252 (when (null tags-file-name)
253 (when (or (and php-project-auto-detect-etags-file
254 (null php-project-etags-file))
255 (eq php-project-etags-file t))
256 (let ((tags-file (expand-file-name "TAGS" (php-project-get-root-dir))))
257 (when (file-exists-p tags-file)
258 (setq-local php-project-etags-file tags-file))))
259 (when php-project-etags-file
260 (setq-local tags-file-name (php-project--eval-bootstrap-scripts php-project-etags-file)))))
261;;;###autoload
262(defun php-project-get-bootstrap-scripts ()
263 "Return list of bootstrap script."
264 (let ((scripts (php-project--eval-bootstrap-scripts php-project-bootstrap-scripts)))
265 (if (stringp scripts) (list scripts) scripts)))
266
267;;;###autoload
268(defun php-project-get-root-dir ()
269 "Return path to current PHP project."
270 (if (and (stringp php-project-root) (file-directory-p php-project-root))
271 php-project-root
272 (let ((detect-method
273 (cond
274 ((stringp php-project-root) (list php-project-root))
275 ((eq php-project-root 'auto)
276 (cl-loop for m in php-project-available-root-files
277 append (cdr m)))
278 (t (cdr-safe (assq php-project-root php-project-available-root-files))))))
279 (cl-loop for m in detect-method
280 thereis (locate-dominating-file default-directory m)))))
281
282(provide 'php-project)
283;;; php-project.el ends here
diff --git a/.emacs.d/lisp/php-util-buffer.el b/.emacs.d/lisp/php-util-buffer.el
deleted file mode 100644
index 70836a0..0000000
--- a/.emacs.d/lisp/php-util-buffer.el
+++ /dev/null
@@ -1,135 +0,0 @@
1;;; php-util-buffer.el --- Utility function for buffer manipulation -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2018-2019 Friends of Emacs-PHP development
4;; Copyright 2013 The go-mode Authors. All rights reserved.
5
6;; Author: Dominik Honnef
7;; Maintainer: USAMI Kenta <tadsan@zonu.me>
8;; URL: https://github.com/emacs-php/php-mode
9;; Keywords: lisp
10
11;; This program is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
15
16;; This program is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with this program. If not, see <https://www.gnu.org/licenses/>.
23
24;;; Commentary:
25
26;; Functions for patching buffer.
27
28;;; Original License:
29
30;; Copyright (c) 2014 The go-mode Authors. All rights reserved.
31
32;; Redistribution and use in source and binary forms, with or without
33;; modification, are permitted provided that the following conditions are
34;; met:
35
36;; * Redistributions of source code must retain the above copyright
37;; notice, this list of conditions and the following disclaimer.
38;; * Redistributions in binary form must reproduce the above
39;; copyright notice, this list of conditions and the following disclaimer
40;; in the documentation and/or other materials provided with the
41;; distribution.
42;; * Neither the name of the copyright holder nor the names of its
43;; contributors may be used to endorse or promote products derived from
44;; this software without specific prior written permission.
45
46;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
49;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
50;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
52;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57
58;;; Code:
59
60;; gofmt apply-rcs-patch Function
61;; These functions are copied by go-mode(gofmt).
62(defun php-util-buffer--delete-whole-line (&optional arg)
63 "Delete the current line without putting it in the `kill-ring'.
64Derived from function `kill-whole-line'. ARG is defined as for that
65function."
66 (setq arg (or arg 1))
67 (if (and (> arg 0)
68 (eobp)
69 (save-excursion (forward-visible-line 0) (eobp)))
70 (signal 'end-of-buffer nil))
71 (if (and (< arg 0)
72 (bobp)
73 (save-excursion (end-of-visible-line) (bobp)))
74 (signal 'beginning-of-buffer nil))
75 (cond ((zerop arg)
76 (delete-region (progn (forward-visible-line 0) (point))
77 (progn (end-of-visible-line) (point))))
78 ((< arg 0)
79 (delete-region (progn (end-of-visible-line) (point))
80 (progn (forward-visible-line (1+ arg))
81 (unless (bobp)
82 (backward-char))
83 (point))))
84 (t
85 (delete-region (progn (forward-visible-line 0) (point))
86 (progn (forward-visible-line arg) (point))))))
87
88(defun php-util-buffer-apply-rcs-patch (target-buffer patch-buffer)
89 "Apply an RCS-formatted diff from `PATCH-BUFFER' to the `TARGET-BUFFER'."
90 (let (
91 ;; Relative offset between buffer line numbers and line numbers
92 ;; in patch.
93 ;;
94 ;; Line numbers in the patch are based on the source file, so
95 ;; we have to keep an offset when making changes to the
96 ;; buffer.
97 ;;
98 ;; Appending lines decrements the offset (possibly making it
99 ;; negative), deleting lines increments it. This order
100 ;; simplifies the forward-line invocations.
101 (line-offset 0)
102 (column (current-column)))
103 (save-excursion
104 (with-current-buffer patch-buffer
105 (goto-char (point-min))
106 (while (not (eobp))
107 (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
108 (error "Invalid rcs patch or internal error in php-util-buffer-apply-rcs-patch"))
109 (forward-line)
110 (let ((action (match-string 1))
111 (from (string-to-number (match-string 2)))
112 (len (string-to-number (match-string 3))))
113 (cond
114 ((equal action "a")
115 (let ((start (point)))
116 (forward-line len)
117 (let ((text (buffer-substring start (point))))
118 (with-current-buffer target-buffer
119 (cl-decf line-offset len)
120 (goto-char (point-min))
121 (forward-line (- from len line-offset))
122 (insert text)))))
123 ((equal action "d")
124 (with-current-buffer target-buffer
125 (goto-char (point-min))
126 (forward-line (1- (- from line-offset)))
127 (cl-incf line-offset len)
128 (php-util-buffer--delete-whole-line len)))
129 (t
130 (error "Invalid rcs patch or internal error in php-util-buffer--apply-rcs-patch")))))))
131 (move-to-column column)))
132;; Copy of go-mode.el ends here
133
134(provide 'php-util-buffer)
135;;; php-util-buffer.el ends here
diff --git a/.emacs.d/lisp/php.el b/.emacs.d/lisp/php.el
deleted file mode 100644
index 663559a..0000000
--- a/.emacs.d/lisp/php.el
+++ /dev/null
@@ -1,452 +0,0 @@
1;;; php.el --- PHP support for friends -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2019 Friends of Emacs-PHP development
4
5;; Author: USAMI Kenta <tadsan@zonu.me>
6;; Created: 5 Dec 2018
7;; Version: 1.22.1
8;; Keywords: languages, php
9;; Homepage: https://github.com/emacs-php/php-mode
10;; Package-Requires: ((emacs "24.3"))
11;; License: GPL-3.0-or-later
12
13;; This program is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
17
18;; This program is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
24;; along with this program. If not, see <https://www.gnu.org/licenses/>.
25
26;;; Commentary:
27
28;; This file provides common variable and functions for PHP packages.
29
30;;; Code:
31(require 'cl-lib)
32(require 'flymake)
33(require 'php-project)
34(require 'rx)
35
36;;;###autoload
37(defgroup php nil
38 "Language support for PHP."
39 :tag "PHP"
40 :group 'languages
41 :link '(url-link :tag "Official Site" "https://github.com/emacs-php/php-mode")
42 :link '(url-link :tag "PHP Mode Wiki" "https://github.com/emacs-php/php-mode/wiki"))
43
44(defcustom php-executable (or (executable-find "php") "/usr/bin/php")
45 "The location of the PHP executable."
46 :group 'php
47 :tag "PHP Executable"
48 :type 'string)
49
50(defcustom php-site-url "https://php.net/"
51 "Default PHP.net site URL.
52
53The URL to use open PHP manual and search word."
54 :group 'php
55 :tag "PHP Site URL"
56 :type 'string)
57
58(defcustom php-manual-url 'en
59 "URL at which to find PHP manual.
60You can replace \"en\" with your ISO language code."
61 :group 'php
62 :tag "PHP Manual URL"
63 :type '(choice (const :tag "English" 'en)
64 (const :tag "Brazilian Portuguese" 'pt_BR)
65 (const :tag "Chinese (Simplified)" 'zh)
66 (const :tag "French" 'fr)
67 (const :tag "German" 'de)
68 (const :tag "Japanese" 'ja)
69 (const :tag "Romanian" 'ro)
70 (const :tag "Russian" 'ru)
71 (const :tag "Spanish" 'es)
72 (const :tag "Turkish" 'tr)
73 (string :tag "PHP manual URL")))
74
75(defcustom php-search-url nil
76 "URL at which to search for documentation on a word."
77 :group 'php
78 :tag "PHP Search URL"
79 :type '(choice (string :tag "URL to search PHP documentation")
80 (const :tag "Use `php-site-url' variable" nil)))
81
82(defcustom php-class-suffix-when-insert "::"
83 "Suffix for inserted class."
84 :group 'php
85 :type 'string)
86
87(defcustom php-namespace-suffix-when-insert "\\"
88 "Suffix for inserted namespace."
89 :group 'php
90 :type 'string)
91
92(defcustom php-default-major-mode 'php-mode
93 "Major mode for editing PHP script."
94 :group 'php
95 :tag "PHP Default Major Mode"
96 :type 'function)
97
98(defcustom php-html-template-major-mode 'web-mode
99 "Major mode for editing PHP-HTML template."
100 :group 'php
101 :tag "PHP-HTML Template Major Mode"
102 :type 'function)
103
104(defcustom php-blade-template-major-mode 'web-mode
105 "Major mode for editing Blade template."
106 :group 'php
107 :tag "PHP Blade Template Major Mode"
108 :type 'function)
109
110(defcustom php-template-mode-alist
111 `(("\\.blade" . ,php-blade-template-major-mode)
112 ("\\.phpt\\'" . ,(if (fboundp 'phpt-mode) 'phpt-mode php-default-major-mode))
113 ("\\.phtml\\'" . ,php-html-template-major-mode))
114 "Automatically use another MAJOR-MODE when open template file."
115 :group 'php
116 :tag "PHP Template Mode Alist"
117 :type '(alist :key-type regexp :value-type function)
118 :link '(url-link :tag "web-mode" "http://web-mode.org/")
119 :link '(url-link :tag "phpt-mode" "https://github.com/emacs-php/phpt-mode"))
120
121(defcustom php-mode-maybe-hook nil
122 "List of functions to be executed on entry to `php-mode-maybe'."
123 :group 'php
124 :tag "PHP Mode Maybe Hook"
125 :type 'hook)
126
127(defcustom php-default-builtin-web-server-port 3939
128 "Port number of PHP Built-in HTTP server (php -S)."
129 :group 'php
130 :tag "PHP Default Built-in Web Server Port"
131 :type 'integer
132 :link '(url-link :tag "Built-in web server"
133 "https://www.php.net/manual/features.commandline.webserver.php"))
134
135;;; PHP Keywords
136(defconst php-magical-constants
137 (list "__LINE__" "__FILE__" "__FUNCTION__" "__CLASS__" "__TRAIT__" "__METHOD__" "__NAMESPACE__")
138 "Magical keyword that is expanded at compile time.
139
140These are different from \"constants\" in strict terms.
141see https://www.php.net/manual/language.constants.predefined.php")
142
143;;; Utillity for locate language construction
144(defsubst php-in-string-p ()
145 "Return non-nil if inside a string.
146it is the character that will terminate the string, or t if the string should be terminated by a generic string delimiter."
147 (nth 3 (syntax-ppss)))
148
149(defsubst php-in-comment-p ()
150 "Return nil if outside a comment, t if inside a non-nestable comment, else an integer (the current comment nesting)."
151 (nth 4 (syntax-ppss)))
152
153(defsubst php-in-string-or-comment-p ()
154 "Return character address of start of comment or string; nil if not in one."
155 (nth 8 (syntax-ppss)))
156
157(defsubst php-in-poly-php-html-mode ()
158 "Return T if current buffer is in `poly-html-mode'."
159 (and (boundp 'poly-php-html-mode)
160 (symbol-value 'poly-php-html-mode)))
161
162(defconst php-beginning-of-defun-regexp
163 "^\\s-*\\(?:\\(?:abstract\\|final\\|private\\|protected\\|public\\|static\\)\\s-+\\)*function\\s-+&?\\(\\(\\sw\\|\\s_\\)+\\)\\s-*("
164 "Regular expression for a PHP function.")
165
166(eval-when-compile
167 (defun php-create-regexp-for-method (&optional visibility)
168 "Make a regular expression for methods with the given VISIBILITY.
169
170VISIBILITY must be a string that names the visibility for a PHP
171method, e.g. 'public'. The parameter VISIBILITY can itself also
172be a regular expression.
173
174The regular expression this function returns will check for other
175keywords that can appear in method signatures, e.g. 'final' and
176'static'. The regular expression will have one capture group
177which will be the name of the method."
178 (when (stringp visibility)
179 (setq visibility (list visibility)))
180 (rx-to-string `(: line-start
181 (* (syntax whitespace))
182 ,@(if visibility
183 `((* (or "abstract" "final" "static")
184 (+ (syntax whitespace)))
185 (or ,@visibility)
186 (+ (syntax whitespace))
187 (* (or "abstract" "final" "static")
188 (+ (syntax whitespace))))
189 '((* (* (or "abstract" "final" "static"
190 "private" "protected" "public")
191 (+ (syntax whitespace))))))
192 "function"
193 (+ (syntax whitespace))
194 (? "&" (* (syntax whitespace)))
195 (group (+ (or (syntax word) (syntax symbol))))
196 (* (syntax whitespace))
197 "(")))
198
199 (defun php-create-regexp-for-classlike (type)
200 "Accepts a `TYPE' of a 'classlike' object as a string, such as
201'class' or 'interface', and returns a regexp as a string which
202can be used to match against definitions for that classlike."
203 (concat
204 ;; First see if 'abstract' or 'final' appear, although really these
205 ;; are not valid for all values of `type' that the function
206 ;; accepts.
207 "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?"
208 ;; The classlike type
209 type
210 ;; Its name, which is the first captured group in the regexp. We
211 ;; allow backslashes in the name to handle namespaces, but again
212 ;; this is not necessarily correct for all values of `type'.
213 "\\s-+\\(\\(?:\\sw\\|\\\\\\|\\s_\\)+\\)")))
214
215(defconst php-imenu-generic-expression
216 (eval-when-compile
217 `(("Namespaces"
218 ,(php-create-regexp-for-classlike "namespace") 1)
219 ("Classes"
220 ,(php-create-regexp-for-classlike "class") 1)
221 ("Interfaces"
222 ,(php-create-regexp-for-classlike "interface") 1)
223 ("Traits"
224 ,(php-create-regexp-for-classlike "trait") 1)
225 ("All Methods"
226 ,(php-create-regexp-for-method) 1)
227 ("Private Methods"
228 ,(php-create-regexp-for-method '("private")) 1)
229 ("Protected Methods"
230 ,(php-create-regexp-for-method '("protected")) 1)
231 ("Public Methods"
232 ,(php-create-regexp-for-method '("public")) 1)
233 ("Anonymous Functions"
234 "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*f\\(unctio\\)?n\\s-*(" 1)
235 ("Named Functions"
236 "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1)))
237 "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.")
238
239(defconst php--re-namespace-pattern
240 (eval-when-compile
241 (php-create-regexp-for-classlike "namespace")))
242
243(defconst php--re-classlike-pattern
244 (eval-when-compile
245 (php-create-regexp-for-classlike (regexp-opt '("class" "interface" "trait")))))
246
247(defun php-get-current-element (re-pattern)
248 "Return backward matched element by RE-PATTERN."
249 (save-excursion
250 (save-match-data
251 (when (re-search-backward re-pattern nil t)
252 (match-string-no-properties 1)))))
253
254;;; Provide support for Flymake so that users can see warnings and
255;;; errors in real-time as they write code.
256(defun php-flymake-php-init ()
257 "PHP specific init-cleanup routines.
258
259This is an alternative function of `flymake-php-init'.
260Look at the `php-executable' variable instead of the constant \"php\" command."
261 (let* ((init (funcall (eval-when-compile
262 (if (fboundp 'flymake-proc-php-init)
263 'flymake-proc-php-init
264 'flymake-php-init)))))
265 (list php-executable (cdr init))))
266
267(defconst php-re-detect-html-tag-aggressive
268 (eval-when-compile
269 (rx (or (: string-start (* (in space))
270 "<!"
271 (or "DOCTYPE" "doctype")
272 (+ (in space))
273 (or "HTML" "html"))
274 (: (or line-start
275 (: "<" (? "/")
276 (* (in space)) (+ (in alpha "-")) (* (in space)) ">"))
277 (: "<" (* (in space)) (+ (in alpha "-")) (* (in space)) ">"))))))
278
279(defconst php-re-detect-html-tag-default
280 (eval-when-compile
281 (rx (or (: string-start (* (in space))
282 "<!"
283 (or "DOCTYPE" "doctype")
284 (+ (in space))
285 (or "HTML" "html"))
286 (: line-start
287 (: "<" (* (in space)) (+ (in alpha "-")) (* (in space)) ">"))))))
288
289(defcustom php-re-detect-html-tag 'php-re-detect-html-tag-default
290 "Regexp pattern variable-name of HTML detection."
291 :group 'php
292 :tag "PHP Re Detect HTML Tag"
293 :type '(choice (const :tag "Default pattern" 'php-re-detect-html-tag-default)
294 (const :tag "Aggressive pattern" 'php-re-detect-html-tag-aggressive)
295 (variable :tag "Variable name of RegExp pattern")))
296
297(defsubst php-re-detect-html-tag ()
298 "Return RegExp pattern for HTML detection."
299 (if (symbolp php-re-detect-html-tag)
300 (symbol-value php-re-detect-html-tag)
301 php-re-detect-html-tag))
302
303(defun php-buffer-has-html-tag ()
304 "Return position of HTML tag or NIL in current buffer."
305 (save-excursion
306 (save-restriction
307 (widen)
308 (goto-char (point-min))
309 (save-match-data
310 (re-search-forward (php-re-detect-html-tag) nil t)))))
311
312(defun php-derivation-major-mode ()
313 "Return major mode for PHP file by file-name and its content."
314 (let ((mode (assoc-default buffer-file-name
315 php-template-mode-alist
316 #'string-match-p))
317 type)
318 (when (and (null mode) buffer-file-name
319 php-project-php-file-as-template)
320 (setq type (php-project-get-file-html-template-type buffer-file-name))
321 (cond
322 ((eq t type) (setq mode php-html-template-major-mode))
323 ((eq 'auto type)
324 (when (php-buffer-has-html-tag)
325 (setq mode php-html-template-major-mode)))))
326 (when (and mode (not (fboundp mode)))
327 (if (string-match-p "\\.blade\\." buffer-file-name)
328 (warn "php-mode is NOT support blade template. %s"
329 "Please install `web-mode' package")
330 (setq mode nil)))
331 (or mode php-default-major-mode)))
332
333;;;###autoload
334(defun php-mode-maybe ()
335 "Select PHP mode or other major mode."
336 (interactive)
337 (run-hooks php-mode-maybe-hook)
338 (funcall (php-derivation-major-mode)))
339
340;;;###autoload
341(defun php-current-class ()
342 "Insert current class name if cursor in class context."
343 (interactive)
344 (let ((matched (php-get-current-element php--re-classlike-pattern)))
345 (when matched
346 (insert (concat matched php-class-suffix-when-insert)))))
347
348;;;###autoload
349(defun php-current-namespace ()
350 "Insert current namespace if cursor in namespace context."
351 (interactive)
352 (let ((matched (php-get-current-element php--re-namespace-pattern)))
353 (when matched
354 (insert (concat matched php-namespace-suffix-when-insert)))))
355
356;;;###autoload
357(defun php-copyit-fqsen ()
358 "Copy/kill class/method FQSEN."
359 (interactive)
360 (let ((namespace (or (php-get-current-element php--re-namespace-pattern) ""))
361 (class (or (php-get-current-element php--re-classlike-pattern) ""))
362 (namedfunc (php-get-current-element php-beginning-of-defun-regexp)))
363 (kill-new (concat (if (string= namespace "") "" namespace)
364 (if (string= class "") "" (concat "\\" class "::"))
365 (if (string= namedfunc "") "" (concat namedfunc "()"))))))
366
367;;;###autoload
368(defun php-run-builtin-web-server (router-or-dir hostname port &optional document-root)
369 "Run PHP Built-in web server.
370
371`ROUTER-OR-DIR': Path to router PHP script or Document root.
372`HOSTNAME': Hostname or IP address of Built-in web server.
373`PORT': Port number of Built-in web server.
374`DOCUMENT-ROOT': Path to Document root.
375
376When `DOCUMENT-ROOT' is NIL, the document root is obtained from `ROUTER-OR-DIR'."
377 (interactive
378 (let ((insert-default-directory t)
379 (d-o-r (read-file-name "Document root or Script: " default-directory)))
380 (list
381 (expand-file-name d-o-r)
382 (read-string "Hostname: " "0.0.0.0")
383 (read-number "Port: " php-default-builtin-web-server-port)
384 (if (file-directory-p d-o-r)
385 nil
386 (let ((root-input (read-file-name "Document root: " (directory-file-name d-o-r))))
387 (file-name-directory
388 (if (file-directory-p root-input)
389 root-input
390 (directory-file-name root-input))))))))
391 (let* ((default-directory
392 (or document-root
393 (if (file-directory-p router-or-dir)
394 router-or-dir
395 (directory-file-name router-or-dir))))
396 (short-dirname (abbreviate-file-name default-directory))
397 (short-filename (abbreviate-file-name router-or-dir))
398 (buf-name (format "php -S %s:%s -t %s %s"
399 hostname
400 port
401 short-dirname
402 (if document-root short-filename "")))
403 (args (cl-remove-if
404 #'null
405 (list "-S"
406 (format "%s:%d" hostname port)
407 "-t"
408 default-directory
409 (when document-root router-or-dir)))))
410 (message "Run PHP built-in server: %s" buf-name)
411 (apply #'make-comint buf-name php-executable nil args)
412 (funcall
413 (if (called-interactively-p 'interactive) #'display-buffer #'get-buffer)
414 (format "*%s*" buf-name))))
415
416(defun php-ini ()
417 "Get `php --ini' output buffer."
418 (interactive)
419 (let ((buffer (get-buffer-create " *php --ini*")))
420 (with-current-buffer buffer
421 (view-mode -1)
422 (read-only-mode -1)
423 (erase-buffer)
424 (shell-command (concat php-executable " --ini") buffer)
425 (view-mode +1))
426 (if (called-interactively-p 'interactive)
427 (pop-to-buffer buffer)
428 buffer)))
429
430(defun php-find-system-php-ini-file (&optional file)
431 "Find php.ini FILE by `php --ini'."
432 (interactive
433 (list
434 (let* ((default-directory (expand-file-name "~"))
435 (buffer (php-ini))
436 (path (with-current-buffer buffer
437 (goto-char (point-min))
438 (save-match-data
439 (when (re-search-forward ": \\(.+?\\)$" nil nil)
440 (match-string 1))))))
441 (when (or (null path) (not (file-directory-p path)))
442 (when (called-interactively-p 'interactive)
443 (pop-to-buffer buffer))
444 (user-error "Failed get path to PHP ini files directory"))
445 (read-file-name "Find php.ini file: "
446 (concat (expand-file-name path) "/")
447 nil nil nil
448 #'file-exists-p))))
449 (find-file file))
450
451(provide 'php)
452;;; php.el ends here
diff --git a/.emacs.d/lisp/rust-playpen.el b/.emacs.d/lisp/rust-playpen.el
index a80a184..07b7296 100644
--- a/.emacs.d/lisp/rust-playpen.el
+++ b/.emacs.d/lisp/rust-playpen.el
@@ -17,7 +17,7 @@
17 :group 'rust-mode) 17 :group 'rust-mode)
18 18
19(defcustom rust-playpen-enable-shortener t 19(defcustom rust-playpen-enable-shortener t
20 "Enable shortended URL for playpen links." 20 "Enable shortened URL for playpen links."
21 :type 'boolean 21 :type 'boolean
22 :safe #'booleanp 22 :safe #'booleanp
23 :group 'rust-mode) 23 :group 'rust-mode)
diff --git a/.emacs.d/lisp/yaml-mode.el b/.emacs.d/lisp/yaml-mode.el
index 1bfa43b..dad0380 100644
--- a/.emacs.d/lisp/yaml-mode.el
+++ b/.emacs.d/lisp/yaml-mode.el
@@ -78,7 +78,7 @@
78(defcustom yaml-indent-offset 2 78(defcustom yaml-indent-offset 2
79 "*Amount of offset per level of indentation." 79 "*Amount of offset per level of indentation."
80 :type 'integer 80 :type 'integer
81 :safe 'natnump 81 :safe #'natnump
82 :group 'yaml) 82 :group 'yaml)
83 83
84(defcustom yaml-backspace-function 'backward-delete-char-untabify 84(defcustom yaml-backspace-function 'backward-delete-char-untabify
@@ -186,11 +186,11 @@ that key is pressed to begin a block literal."
186 186
187(defvar yaml-mode-map 187(defvar yaml-mode-map
188 (let ((map (make-sparse-keymap))) 188 (let ((map (make-sparse-keymap)))
189 (define-key map "|" 'yaml-electric-bar-and-angle) 189 (define-key map "|" #'yaml-electric-bar-and-angle)
190 (define-key map ">" 'yaml-electric-bar-and-angle) 190 (define-key map ">" #'yaml-electric-bar-and-angle)
191 (define-key map "-" 'yaml-electric-dash-and-dot) 191 (define-key map "-" #'yaml-electric-dash-and-dot)
192 (define-key map "." 'yaml-electric-dash-and-dot) 192 (define-key map "." #'yaml-electric-dash-and-dot)
193 (define-key map (kbd "DEL") 'yaml-electric-backspace) 193 (define-key map (kbd "DEL") #'yaml-electric-backspace)
194 map) 194 map)
195 "Keymap used in `yaml-mode' buffers.") 195 "Keymap used in `yaml-mode' buffers.")
196 196
@@ -216,20 +216,18 @@ that key is pressed to begin a block literal."
216 216
217;;;###autoload 217;;;###autoload
218(define-derived-mode yaml-mode text-mode "YAML" 218(define-derived-mode yaml-mode text-mode "YAML"
219 "Simple mode to edit YAML. 219 "Simple mode to edit YAML."
220 220 (setq-local electric-indent-inhibit t) ;We can't *re*indent reliably.
221\\{yaml-mode-map}"
222 :syntax-table yaml-mode-syntax-table
223 (set (make-local-variable 'comment-start) "# ") 221 (set (make-local-variable 'comment-start) "# ")
224 (set (make-local-variable 'comment-start-skip) "#+ *") 222 (set (make-local-variable 'comment-start-skip) "#+ *")
225 (set (make-local-variable 'comment-end) "") 223 (set (make-local-variable 'comment-end) "")
226 (set (make-local-variable 'indent-line-function) 'yaml-indent-line) 224 (set (make-local-variable 'indent-line-function) #'yaml-indent-line)
227 (set (make-local-variable 'indent-tabs-mode) nil) 225 (set (make-local-variable 'indent-tabs-mode) nil)
228 (set (make-local-variable 'fill-paragraph-function) 'yaml-fill-paragraph) 226 (set (make-local-variable 'fill-paragraph-function) #'yaml-fill-paragraph)
229 (set (make-local-variable 'page-delimiter) "^---\\([ \t].*\\)*\n") 227 (set (make-local-variable 'page-delimiter) "^---\\([ \t].*\\)*\n")
230 228
231 (set (make-local-variable 'syntax-propertize-function) 229 (set (make-local-variable 'syntax-propertize-function)
232 'yaml-mode-syntax-propertize-function) 230 #'yaml-mode-syntax-propertize-function)
233 (setq font-lock-defaults '(yaml-font-lock-keywords))) 231 (setq font-lock-defaults '(yaml-font-lock-keywords)))
234 232
235 233
@@ -459,6 +457,7 @@ Outside of comments, this behaves as `fill-paragraph' except that
459filling does not cross boundaries of block literals. Inside comments, 457filling does not cross boundaries of block literals. Inside comments,
460this will do usual adaptive fill behaviors." 458this will do usual adaptive fill behaviors."
461 (interactive "*P") 459 (interactive "*P")
460 ;; FIXME: Can we get away with setting only `fill-forward-paragraph-function'?
462 (save-restriction 461 (save-restriction
463 (yaml-narrow-to-block-literal) 462 (yaml-narrow-to-block-literal)
464 (let ((fill-paragraph-function nil)) 463 (let ((fill-paragraph-function nil))
@@ -466,12 +465,13 @@ this will do usual adaptive fill behaviors."
466 (fill-paragraph justify region))))) 465 (fill-paragraph justify region)))))
467 466
468(defun yaml-set-imenu-generic-expression () 467(defun yaml-set-imenu-generic-expression ()
469 (make-local-variable 'imenu-generic-expression) 468 ;; FIXME: Why set this var to its default value?
470 (make-local-variable 'imenu-create-index-function) 469 (setq-local imenu-create-index-function #'imenu-default-create-index-function)
471 (setq imenu-create-index-function 'imenu-default-create-index-function) 470 (setq-local imenu-generic-expression yaml-imenu-generic-expression))
472 (setq imenu-generic-expression yaml-imenu-generic-expression))
473 471
474(add-hook 'yaml-mode-hook 'yaml-set-imenu-generic-expression) 472;; FIXME: Why not inline `yaml-set-imenu-generic-expression' into the
473;; major mode function?
474(add-hook 'yaml-mode-hook #'yaml-set-imenu-generic-expression)
475 475
476 476
477(defun yaml-mode-version () 477(defun yaml-mode-version ()
diff --git a/.emacs.pure b/.emacs.pure
index 46acbfe..9dc4f05 100644
--- a/.emacs.pure
+++ b/.emacs.pure
@@ -1,3 +1,4 @@
1;; -*- lexical-binding: t; -*-
1;; Set up the keyboard so the delete key on both the regular keyboard 2;; Set up the keyboard so the delete key on both the regular keyboard
2;; and the keypad delete the character under the cursor and to the right 3;; and the keypad delete the character under the cursor and to the right
3;; under X, instead of the default, backspace behavior. 4;; under X, instead of the default, backspace behavior.