diff options
Diffstat (limited to '.emacs.d/lisp/php.el')
| -rw-r--r-- | .emacs.d/lisp/php.el | 207 |
1 files changed, 148 insertions, 59 deletions
diff --git a/.emacs.d/lisp/php.el b/.emacs.d/lisp/php.el index 2bf117b..663559a 100644 --- a/.emacs.d/lisp/php.el +++ b/.emacs.d/lisp/php.el | |||
| @@ -4,10 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: USAMI Kenta <tadsan@zonu.me> | 5 | ;; Author: USAMI Kenta <tadsan@zonu.me> |
| 6 | ;; Created: 5 Dec 2018 | 6 | ;; Created: 5 Dec 2018 |
| 7 | ;; Version: 1.21.4 | 7 | ;; Version: 1.22.1 |
| 8 | ;; Keywords: languages, php | 8 | ;; Keywords: languages, php |
| 9 | ;; Homepage: https://github.com/emacs-php/php-mode | 9 | ;; Homepage: https://github.com/emacs-php/php-mode |
| 10 | ;; Package-Requires: ((emacs "24.3") (cl-lib "0.5")) | 10 | ;; Package-Requires: ((emacs "24.3")) |
| 11 | ;; License: GPL-3.0-or-later | 11 | ;; License: GPL-3.0-or-later |
| 12 | 12 | ||
| 13 | ;; This program is free software; you can redistribute it and/or modify | 13 | ;; This program is free software; you can redistribute it and/or modify |
| @@ -159,8 +159,13 @@ it is the character that will terminate the string, or t if the string should be | |||
| 159 | (and (boundp 'poly-php-html-mode) | 159 | (and (boundp 'poly-php-html-mode) |
| 160 | (symbol-value 'poly-php-html-mode))) | 160 | (symbol-value 'poly-php-html-mode))) |
| 161 | 161 | ||
| 162 | (defun php-create-regexp-for-method (visibility) | 162 | (defconst php-beginning-of-defun-regexp |
| 163 | "Make a regular expression for methods with the given VISIBILITY. | 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. | ||
| 164 | 169 | ||
| 165 | VISIBILITY must be a string that names the visibility for a PHP | 170 | VISIBILITY must be a string that names the visibility for a PHP |
| 166 | method, e.g. 'public'. The parameter VISIBILITY can itself also | 171 | method, e.g. 'public'. The parameter VISIBILITY can itself also |
| @@ -170,67 +175,81 @@ The regular expression this function returns will check for other | |||
| 170 | keywords that can appear in method signatures, e.g. 'final' and | 175 | keywords that can appear in method signatures, e.g. 'final' and |
| 171 | 'static'. The regular expression will have one capture group | 176 | 'static'. The regular expression will have one capture group |
| 172 | which will be the name of the method." | 177 | which will be the name of the method." |
| 173 | (concat | 178 | (when (stringp visibility) |
| 174 | ;; Initial space with possible 'abstract' or 'final' keywords | 179 | (setq visibility (list visibility))) |
| 175 | "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?" | 180 | (rx-to-string `(: line-start |
| 176 | ;; 'static' keyword may come either before or after visibility | 181 | (* (syntax whitespace)) |
| 177 | "\\(?:" visibility "\\(?:\\s-+static\\)?\\|\\(?:static\\s-+\\)?" visibility "\\)\\s-+" | 182 | ,@(if visibility |
| 178 | ;; Make sure 'function' comes next with some space after | 183 | `((* (or "abstract" "final" "static") |
| 179 | "function\\s-+" | 184 | (+ (syntax whitespace))) |
| 180 | ;; Capture the name as the first group and the regexp and make sure | 185 | (or ,@visibility) |
| 181 | ;; by the end we see the opening parenthesis for the parameters. | 186 | (+ (syntax whitespace)) |
| 182 | "\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(")) | 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 | "("))) | ||
| 183 | 198 | ||
| 184 | (defun php-create-regexp-for-classlike (type) | 199 | (defun php-create-regexp-for-classlike (type) |
| 185 | "Accepts a `TYPE' of a 'classlike' object as a string, such as | 200 | "Accepts a `TYPE' of a 'classlike' object as a string, such as |
| 186 | 'class' or 'interface', and returns a regexp as a string which | 201 | 'class' or 'interface', and returns a regexp as a string which |
| 187 | can be used to match against definitions for that classlike." | 202 | can be used to match against definitions for that classlike." |
| 188 | (concat | 203 | (concat |
| 189 | ;; First see if 'abstract' or 'final' appear, although really these | 204 | ;; First see if 'abstract' or 'final' appear, although really these |
| 190 | ;; are not valid for all values of `type' that the function | 205 | ;; are not valid for all values of `type' that the function |
| 191 | ;; accepts. | 206 | ;; accepts. |
| 192 | "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?" | 207 | "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?" |
| 193 | ;; The classlike type | 208 | ;; The classlike type |
| 194 | type | 209 | type |
| 195 | ;; Its name, which is the first captured group in the regexp. We | 210 | ;; Its name, which is the first captured group in the regexp. We |
| 196 | ;; allow backslashes in the name to handle namespaces, but again | 211 | ;; allow backslashes in the name to handle namespaces, but again |
| 197 | ;; this is not necessarily correct for all values of `type'. | 212 | ;; this is not necessarily correct for all values of `type'. |
| 198 | "\\s-+\\(\\(?:\\sw\\|\\\\\\|\\s_\\)+\\)")) | 213 | "\\s-+\\(\\(?:\\sw\\|\\\\\\|\\s_\\)+\\)"))) |
| 199 | 214 | ||
| 200 | (defvar php-imenu-generic-expression | 215 | (defconst php-imenu-generic-expression |
| 201 | `(("Namespaces" | 216 | (eval-when-compile |
| 202 | ,(php-create-regexp-for-classlike "namespace") 1) | 217 | `(("Namespaces" |
| 203 | ("Classes" | 218 | ,(php-create-regexp-for-classlike "namespace") 1) |
| 204 | ,(php-create-regexp-for-classlike "class") 1) | 219 | ("Classes" |
| 205 | ("Interfaces" | 220 | ,(php-create-regexp-for-classlike "class") 1) |
| 206 | ,(php-create-regexp-for-classlike "interface") 1) | 221 | ("Interfaces" |
| 207 | ("Traits" | 222 | ,(php-create-regexp-for-classlike "interface") 1) |
| 208 | ,(php-create-regexp-for-classlike "trait") 1) | 223 | ("Traits" |
| 209 | ("All Methods" | 224 | ,(php-create-regexp-for-classlike "trait") 1) |
| 210 | ,(php-create-regexp-for-method "\\(?:\\sw\\|\\s_\\)+") 1) | 225 | ("All Methods" |
| 211 | ("Private Methods" | 226 | ,(php-create-regexp-for-method) 1) |
| 212 | ,(php-create-regexp-for-method "private") 1) | 227 | ("Private Methods" |
| 213 | ("Protected Methods" | 228 | ,(php-create-regexp-for-method '("private")) 1) |
| 214 | ,(php-create-regexp-for-method "protected") 1) | 229 | ("Protected Methods" |
| 215 | ("Public Methods" | 230 | ,(php-create-regexp-for-method '("protected")) 1) |
| 216 | ,(php-create-regexp-for-method "public") 1) | 231 | ("Public Methods" |
| 217 | ("Anonymous Functions" | 232 | ,(php-create-regexp-for-method '("public")) 1) |
| 218 | "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*function\\s-*(" 1) | 233 | ("Anonymous Functions" |
| 219 | ("Named Functions" | 234 | "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*f\\(unctio\\)?n\\s-*(" 1) |
| 220 | "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1)) | 235 | ("Named Functions" |
| 236 | "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1))) | ||
| 221 | "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.") | 237 | "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.") |
| 222 | 238 | ||
| 223 | (defvar php--re-namespace-pattern | 239 | (defconst php--re-namespace-pattern |
| 224 | (php-create-regexp-for-classlike "namespace")) | 240 | (eval-when-compile |
| 241 | (php-create-regexp-for-classlike "namespace"))) | ||
| 225 | 242 | ||
| 226 | (defvar php--re-classlike-pattern | 243 | (defconst php--re-classlike-pattern |
| 227 | (php-create-regexp-for-classlike (regexp-opt '("class" "interface" "trait")))) | 244 | (eval-when-compile |
| 245 | (php-create-regexp-for-classlike (regexp-opt '("class" "interface" "trait"))))) | ||
| 228 | 246 | ||
| 229 | (defun php-get-current-element (re-pattern) | 247 | (defun php-get-current-element (re-pattern) |
| 230 | "Return backward matched element by RE-PATTERN." | 248 | "Return backward matched element by RE-PATTERN." |
| 231 | (save-excursion | 249 | (save-excursion |
| 232 | (when (re-search-backward re-pattern nil t) | 250 | (save-match-data |
| 233 | (match-string-no-properties 1)))) | 251 | (when (re-search-backward re-pattern nil t) |
| 252 | (match-string-no-properties 1))))) | ||
| 234 | 253 | ||
| 235 | ;;; Provide support for Flymake so that users can see warnings and | 254 | ;;; Provide support for Flymake so that users can see warnings and |
| 236 | ;;; errors in real-time as they write code. | 255 | ;;; errors in real-time as they write code. |
| @@ -245,7 +264,7 @@ Look at the `php-executable' variable instead of the constant \"php\" command." | |||
| 245 | 'flymake-php-init))))) | 264 | 'flymake-php-init))))) |
| 246 | (list php-executable (cdr init)))) | 265 | (list php-executable (cdr init)))) |
| 247 | 266 | ||
| 248 | (defconst php-re-detect-html-tag | 267 | (defconst php-re-detect-html-tag-aggressive |
| 249 | (eval-when-compile | 268 | (eval-when-compile |
| 250 | (rx (or (: string-start (* (in space)) | 269 | (rx (or (: string-start (* (in space)) |
| 251 | "<!" | 270 | "<!" |
| @@ -257,13 +276,38 @@ Look at the `php-executable' variable instead of the constant \"php\" command." | |||
| 257 | (* (in space)) (+ (in alpha "-")) (* (in space)) ">")) | 276 | (* (in space)) (+ (in alpha "-")) (* (in space)) ">")) |
| 258 | (: "<" (* (in space)) (+ (in alpha "-")) (* (in space)) ">")))))) | 277 | (: "<" (* (in space)) (+ (in alpha "-")) (* (in space)) ">")))))) |
| 259 | 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 | |||
| 260 | (defun php-buffer-has-html-tag () | 303 | (defun php-buffer-has-html-tag () |
| 261 | "Return position of HTML tag or NIL in current buffer." | 304 | "Return position of HTML tag or NIL in current buffer." |
| 262 | (save-excursion | 305 | (save-excursion |
| 263 | (save-restriction | 306 | (save-restriction |
| 264 | (widen) | 307 | (widen) |
| 265 | (goto-char (point-min)) | 308 | (goto-char (point-min)) |
| 266 | (re-search-forward php-re-detect-html-tag nil t)))) | 309 | (save-match-data |
| 310 | (re-search-forward (php-re-detect-html-tag) nil t))))) | ||
| 267 | 311 | ||
| 268 | (defun php-derivation-major-mode () | 312 | (defun php-derivation-major-mode () |
| 269 | "Return major mode for PHP file by file-name and its content." | 313 | "Return major mode for PHP file by file-name and its content." |
| @@ -310,6 +354,17 @@ Look at the `php-executable' variable instead of the constant \"php\" command." | |||
| 310 | (insert (concat matched php-namespace-suffix-when-insert))))) | 354 | (insert (concat matched php-namespace-suffix-when-insert))))) |
| 311 | 355 | ||
| 312 | ;;;###autoload | 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 | ||
| 313 | (defun php-run-builtin-web-server (router-or-dir hostname port &optional document-root) | 368 | (defun php-run-builtin-web-server (router-or-dir hostname port &optional document-root) |
| 314 | "Run PHP Built-in web server. | 369 | "Run PHP Built-in web server. |
| 315 | 370 | ||
| @@ -338,9 +393,8 @@ When `DOCUMENT-ROOT' is NIL, the document root is obtained from `ROUTER-OR-DIR'. | |||
| 338 | (if (file-directory-p router-or-dir) | 393 | (if (file-directory-p router-or-dir) |
| 339 | router-or-dir | 394 | router-or-dir |
| 340 | (directory-file-name router-or-dir)))) | 395 | (directory-file-name router-or-dir)))) |
| 341 | (pattern (rx-form `(: bos ,(getenv "HOME")))) | 396 | (short-dirname (abbreviate-file-name default-directory)) |
| 342 | (short-dirname (replace-regexp-in-string pattern "~" default-directory)) | 397 | (short-filename (abbreviate-file-name router-or-dir)) |
| 343 | (short-filename (replace-regexp-in-string pattern "~" router-or-dir)) | ||
| 344 | (buf-name (format "php -S %s:%s -t %s %s" | 398 | (buf-name (format "php -S %s:%s -t %s %s" |
| 345 | hostname | 399 | hostname |
| 346 | port | 400 | port |
| @@ -359,5 +413,40 @@ When `DOCUMENT-ROOT' is NIL, the document root is obtained from `ROUTER-OR-DIR'. | |||
| 359 | (if (called-interactively-p 'interactive) #'display-buffer #'get-buffer) | 413 | (if (called-interactively-p 'interactive) #'display-buffer #'get-buffer) |
| 360 | (format "*%s*" buf-name)))) | 414 | (format "*%s*" buf-name)))) |
| 361 | 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 | |||
| 362 | (provide 'php) | 451 | (provide 'php) |
| 363 | ;;; php.el ends here | 452 | ;;; php.el ends here |
