summaryrefslogtreecommitdiff
path: root/.emacs.d/lisp/php.el
diff options
context:
space:
mode:
Diffstat (limited to '.emacs.d/lisp/php.el')
-rw-r--r--.emacs.d/lisp/php.el452
1 files changed, 0 insertions, 452 deletions
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