diff options
Diffstat (limited to '.emacs.d/lisp')
| -rw-r--r-- | .emacs.d/lisp/php-face.el | 142 | ||||
| -rw-r--r-- | .emacs.d/lisp/php-mode.el | 462 | ||||
| -rw-r--r-- | .emacs.d/lisp/php-project.el | 2 | ||||
| -rw-r--r-- | .emacs.d/lisp/php.el | 207 | ||||
| -rw-r--r-- | .emacs.d/lisp/yasnippet.el | 532 |
5 files changed, 739 insertions, 606 deletions
diff --git a/.emacs.d/lisp/php-face.el b/.emacs.d/lisp/php-face.el new file mode 100644 index 0000000..e01d517 --- /dev/null +++ b/.emacs.d/lisp/php-face.el | |||
| @@ -0,0 +1,142 @@ | |||
| 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.21.2 | ||
| 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 | |||
| 43 | (defface php-keyword '((t (:inherit font-lock-keyword-face))) | ||
| 44 | "PHP Mode face used to highlight keywords." | ||
| 45 | :group 'php-faces) | ||
| 46 | |||
| 47 | (defface php-builtin '((t (:inherit font-lock-builtin-face))) | ||
| 48 | "PHP Mode face used to highlight builtins." | ||
| 49 | :group 'php-faces) | ||
| 50 | |||
| 51 | (defface php-function-name '((t (:inherit font-lock-function-name-face))) | ||
| 52 | "PHP Mode face used to highlight function names." | ||
| 53 | :group 'php-faces) | ||
| 54 | |||
| 55 | (defface php-function-call '((t (:inherit default))) | ||
| 56 | "PHP Mode face used to highlight function names in calles." | ||
| 57 | :group 'php-faces) | ||
| 58 | |||
| 59 | (defface php-method-call '((t (:inherit php-function-call))) | ||
| 60 | "PHP Mode face used to highlight method names in calles." | ||
| 61 | :group 'php-faces) | ||
| 62 | |||
| 63 | (defface php-static-method-call '((t (:inherit php-method-call))) | ||
| 64 | "PHP Mode face used to highlight static method names in calles." | ||
| 65 | :group 'php-faces) | ||
| 66 | |||
| 67 | (defface php-variable-name '((t (:inherit font-lock-variable-name-face))) | ||
| 68 | "PHP Mode face used to highlight variable names." | ||
| 69 | :group 'php-faces) | ||
| 70 | |||
| 71 | (defface php-property-name '((t (:inherit php-variable-name))) | ||
| 72 | "PHP Mode face used to highlight property names." | ||
| 73 | :group 'php-faces) | ||
| 74 | |||
| 75 | (defface php-variable-sigil '((t (:inherit default))) | ||
| 76 | "PHP Mode face used to highlight variable sigils ($)." | ||
| 77 | :group 'php-faces) | ||
| 78 | |||
| 79 | (defface php-object-op '((t (:inherit default))) | ||
| 80 | "PHP Mode face used to object operators (->)." | ||
| 81 | :group 'php-faces) | ||
| 82 | |||
| 83 | (defface php-paamayim-nekudotayim '((t (:inherit default))) | ||
| 84 | "PHP Mode face used to highlight \"Paamayim Nekudotayim\" scope resolution operators (::)." | ||
| 85 | :group 'php-faces) | ||
| 86 | |||
| 87 | (defface php-type '((t (:inherit font-lock-type-face))) | ||
| 88 | "PHP Mode face used to highlight types." | ||
| 89 | :group 'php-faces) | ||
| 90 | |||
| 91 | (defface php-constant '((t (:inherit font-lock-constant-face))) | ||
| 92 | "PHP Mode face used to highlight constants." | ||
| 93 | :group 'php-faces) | ||
| 94 | |||
| 95 | (defface php-constant-assign '((t (:inherit font-lock-type-face))) | ||
| 96 | "PHP Mode face used to highlight constant assigning (\"const\" statement)." | ||
| 97 | :group 'php-faces) | ||
| 98 | |||
| 99 | (defface php-magical-constant '((t (:inherit font-lock-builtin-face))) | ||
| 100 | "PHP Mode face used to highlight magical constants." | ||
| 101 | :group 'php-faces) | ||
| 102 | |||
| 103 | (defface php-$this '((t (:inherit php-constant))) | ||
| 104 | "PHP Mode face used to highlight $this variables." | ||
| 105 | :group 'php-faces) | ||
| 106 | |||
| 107 | (defface php-$this-sigil '((t (:inherit php-constant))) | ||
| 108 | "PHP Mode face used to highlight sigils($) of $this variable." | ||
| 109 | :group 'php-faces) | ||
| 110 | |||
| 111 | (defface php-errorcontrol-op '((t (:inherit font-lock-type-face))) | ||
| 112 | "PHP Mode face used to highlight errorcontrol operators (@).." | ||
| 113 | :group 'php-face) | ||
| 114 | |||
| 115 | (defface php-php-tag '((t (:inherit font-lock-preprocessor-face))) | ||
| 116 | "PHP Mode face used to highlight PHP tags." | ||
| 117 | :group 'php-faces) | ||
| 118 | |||
| 119 | (defface php-doc-annotation-tag '((t . (:inherit font-lock-constant-face))) | ||
| 120 | "Face used to highlight annotation tags in doc-comment." | ||
| 121 | :group 'php-faces) | ||
| 122 | |||
| 123 | (defface php-doc-variable-sigil '((t (:inherit font-lock-variable-name-face))) | ||
| 124 | "PHP Mode face used to highlight variable sigils($)." | ||
| 125 | :group 'php-faces) | ||
| 126 | |||
| 127 | (defface php-doc-$this '((t (:inherit php-type))) | ||
| 128 | "PHP Mode face used to highlight $this variable in doc-comment." | ||
| 129 | :group 'php-faces) | ||
| 130 | |||
| 131 | (defface php-doc-$this-sigil '((t (:inherit php-type))) | ||
| 132 | "PHP Mode face used to highlight sigil of $this variable in doc-comment." | ||
| 133 | :group 'php-faces) | ||
| 134 | |||
| 135 | (defface php-doc-class-name '((t (:inherit php-string))) | ||
| 136 | "Face used to class names in doc-comment." | ||
| 137 | :group 'php-faces) | ||
| 138 | |||
| 139 | (define-obsolete-face-alias 'php-annotations-annotation-face 'php-doc-annotation-tag "1.19.0") | ||
| 140 | |||
| 141 | (provide 'php-face) | ||
| 142 | ;;; php-face.el ends here | ||
diff --git a/.emacs.d/lisp/php-mode.el b/.emacs.d/lisp/php-mode.el index 8e72fe3..2fa1ab5 100644 --- a/.emacs.d/lisp/php-mode.el +++ b/.emacs.d/lisp/php-mode.el | |||
| @@ -9,30 +9,28 @@ | |||
| 9 | ;; Maintainer: USAMI Kenta <tadsan@zonu.me> | 9 | ;; Maintainer: USAMI Kenta <tadsan@zonu.me> |
| 10 | ;; URL: https://github.com/emacs-php/php-mode | 10 | ;; URL: https://github.com/emacs-php/php-mode |
| 11 | ;; Keywords: languages php | 11 | ;; Keywords: languages php |
| 12 | ;; Version: 1.21.0 | 12 | ;; Version: 1.21.2 |
| 13 | ;; Package-Requires: ((emacs "24.3") (cl-lib "0.5")) | 13 | ;; Package-Requires: ((emacs "24.3") (cl-lib "0.5")) |
| 14 | ;; License: GPL-3.0-or-later | 14 | ;; License: GPL-3.0-or-later |
| 15 | 15 | ||
| 16 | (defconst php-mode-version-number "1.21.0" | 16 | (defconst php-mode-version-number "1.21.2" |
| 17 | "PHP Mode version number.") | 17 | "PHP Mode version number.") |
| 18 | 18 | ||
| 19 | (defconst php-mode-modified "2019-02-28" | 19 | (defconst php-mode-modified "2019-05-11" |
| 20 | "PHP Mode build date.") | 20 | "PHP Mode build date.") |
| 21 | 21 | ||
| 22 | ;; This file is free software; you can redistribute it and/or | 22 | ;; This program is free software; you can redistribute it and/or modify |
| 23 | ;; modify it under the terms of the GNU General Public License | 23 | ;; it under the terms of the GNU General Public License as published by |
| 24 | ;; as published by the Free Software Foundation; either version 3 | 24 | ;; the Free Software Foundation, either version 3 of the License, or |
| 25 | ;; of the License, or (at your option) any later version. | 25 | ;; (at your option) any later version. |
| 26 | 26 | ||
| 27 | ;; This file is distributed in the hope that it will be useful, | 27 | ;; This program is distributed in the hope that it will be useful, |
| 28 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 28 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 29 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 29 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 30 | ;; GNU General Public License for more details. | 30 | ;; GNU General Public License for more details. |
| 31 | 31 | ||
| 32 | ;; You should have received a copy of the GNU General Public License | 32 | ;; You should have received a copy of the GNU General Public License |
| 33 | ;; along with this file; if not, write to the Free Software | 33 | ;; along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 34 | ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 35 | ;; 02110-1301, USA. | ||
| 36 | 34 | ||
| 37 | ;;; Commentary: | 35 | ;;; Commentary: |
| 38 | 36 | ||
| @@ -65,6 +63,8 @@ | |||
| 65 | 63 | ||
| 66 | ;;; Code: | 64 | ;;; Code: |
| 67 | 65 | ||
| 66 | (require 'php) | ||
| 67 | (require 'php-face) | ||
| 68 | (require 'cc-mode) | 68 | (require 'cc-mode) |
| 69 | (require 'cc-langs) | 69 | (require 'cc-langs) |
| 70 | 70 | ||
| @@ -80,12 +80,10 @@ | |||
| 80 | (require 'font-lock) | 80 | (require 'font-lock) |
| 81 | (require 'add-log) | 81 | (require 'add-log) |
| 82 | (require 'custom) | 82 | (require 'custom) |
| 83 | (require 'flymake) | ||
| 84 | (require 'etags) | 83 | (require 'etags) |
| 85 | (require 'speedbar) | 84 | (require 'speedbar) |
| 86 | (require 'imenu) | 85 | (require 'imenu) |
| 87 | (require 'nadvice nil t) | 86 | (require 'nadvice nil t) |
| 88 | (require 'package) | ||
| 89 | 87 | ||
| 90 | (require 'cl-lib) | 88 | (require 'cl-lib) |
| 91 | (require 'mode-local) | 89 | (require 'mode-local) |
| @@ -93,14 +91,13 @@ | |||
| 93 | 91 | ||
| 94 | (eval-when-compile | 92 | (eval-when-compile |
| 95 | (require 'regexp-opt) | 93 | (require 'regexp-opt) |
| 96 | (autoload 'pkg-info-version-info "pkg-info") | ||
| 97 | (defvar c-vsemi-status-unknown-p) | 94 | (defvar c-vsemi-status-unknown-p) |
| 98 | (defvar syntax-propertize-via-font-lock)) | 95 | (defvar syntax-propertize-via-font-lock)) |
| 99 | 96 | ||
| 100 | ;; Work around emacs bug#18845, cc-mode expects cl to be loaded | 97 | ;; Work around emacs bug#18845, cc-mode expects cl to be loaded |
| 101 | ;; while php-mode only uses cl-lib (without compatibility aliases) | 98 | ;; while php-mode only uses cl-lib (without compatibility aliases) |
| 102 | (eval-and-compile | 99 | (eval-and-compile |
| 103 | (if (and (= emacs-major-version 24) (>= emacs-minor-version 4)) | 100 | (when (and (= emacs-major-version 24) (>= emacs-minor-version 4)) |
| 104 | (require 'cl))) | 101 | (require 'cl))) |
| 105 | 102 | ||
| 106 | ;; Work around https://github.com/emacs-php/php-mode/issues/310. | 103 | ;; Work around https://github.com/emacs-php/php-mode/issues/310. |
| @@ -120,16 +117,10 @@ | |||
| 120 | ;; need it in php-mode, just return nil. | 117 | ;; need it in php-mode, just return nil. |
| 121 | nil))) | 118 | nil))) |
| 122 | 119 | ||
| 120 | (autoload 'php-mode-debug "php-mode-debug" | ||
| 121 | "Display informations useful for debugging PHP Mode." t) | ||
| 123 | 122 | ||
| 124 | ;; Local variables | 123 | ;; Local variables |
| 125 | ;;;###autoload | ||
| 126 | (defgroup php nil | ||
| 127 | "Language support for PHP." | ||
| 128 | :tag "PHP" | ||
| 129 | :group 'languages | ||
| 130 | :group 'php | ||
| 131 | :link '(url-link :tag "Official Site" "https://github.com/emacs-php/php-mode") | ||
| 132 | :link '(url-link :tag "PHP Mode Wiki" "https://github.com/emacs-php/php-mode/wiki")) | ||
| 133 | 124 | ||
| 134 | ;;;###autoload | 125 | ;;;###autoload |
| 135 | (defgroup php-mode nil | 126 | (defgroup php-mode nil |
| @@ -141,11 +132,6 @@ | |||
| 141 | :link '(url-link :tag "Official Site" "https://github.com/emacs-php/php-mode") | 132 | :link '(url-link :tag "Official Site" "https://github.com/emacs-php/php-mode") |
| 142 | :link '(url-link :tag "PHP Mode Wiki" "https://github.com/emacs-php/php-mode/wiki")) | 133 | :link '(url-link :tag "PHP Mode Wiki" "https://github.com/emacs-php/php-mode/wiki")) |
| 143 | 134 | ||
| 144 | (defcustom php-executable (or (executable-find "php") | ||
| 145 | "/usr/bin/php") | ||
| 146 | "The location of the PHP executable." | ||
| 147 | :type 'string) | ||
| 148 | |||
| 149 | (define-obsolete-variable-alias 'php-default-face 'php-mode-default-face "1.20.0") | 135 | (define-obsolete-variable-alias 'php-default-face 'php-mode-default-face "1.20.0") |
| 150 | (defcustom php-mode-default-face 'default | 136 | (defcustom php-mode-default-face 'default |
| 151 | "Default face in `php-mode' buffers." | 137 | "Default face in `php-mode' buffers." |
| @@ -180,20 +166,11 @@ Turning this on will open it whenever `php-mode' is loaded." | |||
| 180 | :group 'php-mode | 166 | :group 'php-mode |
| 181 | :type 'boolean) | 167 | :type 'boolean) |
| 182 | 168 | ||
| 183 | (defsubst php-in-string-p () | ||
| 184 | (nth 3 (syntax-ppss))) | ||
| 185 | |||
| 186 | (defsubst php-in-comment-p () | ||
| 187 | (nth 4 (syntax-ppss))) | ||
| 188 | |||
| 189 | (defsubst php-in-string-or-comment-p () | ||
| 190 | (nth 8 (syntax-ppss))) | ||
| 191 | |||
| 192 | (defun php-mode-extra-constants-create-regexp (kwds) | 169 | (defun php-mode-extra-constants-create-regexp (kwds) |
| 193 | "Create regexp for the list of extra constant keywords KWDS." | 170 | "Create regexp for the list of extra constant keywords KWDS." |
| 194 | (concat "[^_$]?\\<\\(" | 171 | (concat "[^_$]?\\<\\(" |
| 195 | (regexp-opt | 172 | (regexp-opt |
| 196 | (append kwds | 173 | (append kwds |
| 197 | (when (boundp 'web-mode-extra-php-constants) web-mode-extra-php-constants))) | 174 | (when (boundp 'web-mode-extra-php-constants) web-mode-extra-php-constants))) |
| 198 | "\\)\\>[^_]?")) | 175 | "\\)\\>[^_]?")) |
| 199 | 176 | ||
| @@ -227,67 +204,6 @@ of constants when set." | |||
| 227 | :type '(repeat string) | 204 | :type '(repeat string) |
| 228 | :set 'php-mode-extra-constants-set) | 205 | :set 'php-mode-extra-constants-set) |
| 229 | 206 | ||
| 230 | (defun php-create-regexp-for-method (visibility) | ||
| 231 | "Make a regular expression for methods with the given VISIBILITY. | ||
| 232 | |||
| 233 | VISIBILITY must be a string that names the visibility for a PHP | ||
| 234 | method, e.g. 'public'. The parameter VISIBILITY can itself also | ||
| 235 | be a regular expression. | ||
| 236 | |||
| 237 | The regular expression this function returns will check for other | ||
| 238 | keywords that can appear in method signatures, e.g. 'final' and | ||
| 239 | 'static'. The regular expression will have one capture group | ||
| 240 | which will be the name of the method." | ||
| 241 | (concat | ||
| 242 | ;; Initial space with possible 'abstract' or 'final' keywords | ||
| 243 | "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?" | ||
| 244 | ;; 'static' keyword may come either before or after visibility | ||
| 245 | "\\(?:" visibility "\\(?:\\s-+static\\)?\\|\\(?:static\\s-+\\)?" visibility "\\)\\s-+" | ||
| 246 | ;; Make sure 'function' comes next with some space after | ||
| 247 | "function\\s-+" | ||
| 248 | ;; Capture the name as the first group and the regexp and make sure | ||
| 249 | ;; by the end we see the opening parenthesis for the parameters. | ||
| 250 | "\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(")) | ||
| 251 | |||
| 252 | (defun php-create-regexp-for-classlike (type) | ||
| 253 | "Accepts a `TYPE' of a 'classlike' object as a string, such as | ||
| 254 | 'class' or 'interface', and returns a regexp as a string which | ||
| 255 | can be used to match against definitions for that classlike." | ||
| 256 | (concat | ||
| 257 | ;; First see if 'abstract' or 'final' appear, although really these | ||
| 258 | ;; are not valid for all values of `type' that the function | ||
| 259 | ;; accepts. | ||
| 260 | "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?" | ||
| 261 | ;; The classlike type | ||
| 262 | type | ||
| 263 | ;; Its name, which is the first captured group in the regexp. We | ||
| 264 | ;; allow backslashes in the name to handle namespaces, but again | ||
| 265 | ;; this is not necessarily correct for all values of `type'. | ||
| 266 | "\\s-+\\(\\(?:\\sw\\|\\\\\\|\\s_\\)+\\)")) | ||
| 267 | |||
| 268 | (defvar php-imenu-generic-expression | ||
| 269 | `(("Namespaces" | ||
| 270 | ,(php-create-regexp-for-classlike "namespace") 1) | ||
| 271 | ("Classes" | ||
| 272 | ,(php-create-regexp-for-classlike "class") 1) | ||
| 273 | ("Interfaces" | ||
| 274 | ,(php-create-regexp-for-classlike "interface") 1) | ||
| 275 | ("Traits" | ||
| 276 | ,(php-create-regexp-for-classlike "trait") 1) | ||
| 277 | ("All Methods" | ||
| 278 | ,(php-create-regexp-for-method "\\(?:\\sw\\|\\s_\\)+") 1) | ||
| 279 | ("Private Methods" | ||
| 280 | ,(php-create-regexp-for-method "private") 1) | ||
| 281 | ("Protected Methods" | ||
| 282 | ,(php-create-regexp-for-method "protected") 1) | ||
| 283 | ("Public Methods" | ||
| 284 | ,(php-create-regexp-for-method "public") 1) | ||
| 285 | ("Anonymous Functions" | ||
| 286 | "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*function\\s-*(" 1) | ||
| 287 | ("Named Functions" | ||
| 288 | "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1)) | ||
| 289 | "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.") | ||
| 290 | |||
| 291 | (define-obsolete-variable-alias 'php-do-not-use-semantic-imenu 'php-mode-do-not-use-semantic-imenu "1.20.0") | 207 | (define-obsolete-variable-alias 'php-do-not-use-semantic-imenu 'php-mode-do-not-use-semantic-imenu "1.20.0") |
| 292 | (defcustom php-mode-do-not-use-semantic-imenu t | 208 | (defcustom php-mode-do-not-use-semantic-imenu t |
| 293 | "Customize `imenu-create-index-function' for `php-mode'. | 209 | "Customize `imenu-create-index-function' for `php-mode'. |
| @@ -299,34 +215,6 @@ parent. Set this variable to t if you want to use | |||
| 299 | enabled." | 215 | enabled." |
| 300 | :type 'boolean) | 216 | :type 'boolean) |
| 301 | 217 | ||
| 302 | (defcustom php-site-url "https://secure.php.net/" | ||
| 303 | "Default PHP.net site URL. | ||
| 304 | |||
| 305 | The URL to use open PHP manual and search word. | ||
| 306 | You can find a mirror site closer to you." | ||
| 307 | :type 'string | ||
| 308 | :link '(url-link :tag "List of Mirror Sites" "https://secure.php.net/mirrors.php")) | ||
| 309 | |||
| 310 | (defcustom php-manual-url 'en | ||
| 311 | "URL at which to find PHP manual. | ||
| 312 | You can replace \"en\" with your ISO language code." | ||
| 313 | :type '(choice (const :tag "English" 'en) | ||
| 314 | (const :tag "Brazilian Portuguese" 'pt_BR) | ||
| 315 | (const :tag "Chinese (Simplified)" 'zh) | ||
| 316 | (const :tag "French" 'fr) | ||
| 317 | (const :tag "German" 'de) | ||
| 318 | (const :tag "Japanese" 'ja) | ||
| 319 | (const :tag "Romanian" 'ro) | ||
| 320 | (const :tag "Russian" 'ru) | ||
| 321 | (const :tag "Spanish" 'es) | ||
| 322 | (const :tag "Turkish" 'tr) | ||
| 323 | (string :tag "PHP manual URL"))) | ||
| 324 | |||
| 325 | (defcustom php-search-url nil | ||
| 326 | "URL at which to search for documentation on a word." | ||
| 327 | :type '(choice (string :tag "URL to search PHP documentation") | ||
| 328 | (const :tag "Use `php-site-url' variable" nil))) | ||
| 329 | |||
| 330 | (defcustom php-completion-file "" | 218 | (defcustom php-completion-file "" |
| 331 | "Path to the file which contains the function names known to PHP." | 219 | "Path to the file which contains the function names known to PHP." |
| 332 | :type 'string) | 220 | :type 'string) |
| @@ -524,6 +412,10 @@ In that case set to `NIL'." | |||
| 524 | (left-assoc "\\" "::" "->") | 412 | (left-assoc "\\" "::" "->") |
| 525 | (prefix "\\" "::"))) | 413 | (prefix "\\" "::"))) |
| 526 | 414 | ||
| 415 | (c-lang-defconst c-operators | ||
| 416 | php (delete '(postfix-if-paren "<" ">") | ||
| 417 | (c-lang-const c-operators))) | ||
| 418 | |||
| 527 | ;; Allow '\' when scanning from open brace back to defining | 419 | ;; Allow '\' when scanning from open brace back to defining |
| 528 | ;; construct like class | 420 | ;; construct like class |
| 529 | (c-lang-defconst c-block-prefix-disallowed-chars | 421 | (c-lang-defconst c-block-prefix-disallowed-chars |
| @@ -580,40 +472,35 @@ PHP does not have an \"enum\"-like keyword." | |||
| 580 | php '("implements" "extends")) | 472 | php '("implements" "extends")) |
| 581 | 473 | ||
| 582 | (c-lang-defconst c-type-list-kwds | 474 | (c-lang-defconst c-type-list-kwds |
| 583 | php '("new" "use" "implements" "extends" "namespace" "instanceof" "insteadof")) | 475 | php '("@new" ;; @new is *NOT* language construct, it's workaround for coloring. |
| 476 | "new" "use" "implements" "extends" "namespace" "instanceof" "insteadof")) | ||
| 584 | 477 | ||
| 585 | (c-lang-defconst c-ref-list-kwds | 478 | (c-lang-defconst c-ref-list-kwds |
| 586 | php nil) | 479 | php nil) |
| 587 | 480 | ||
| 588 | (c-lang-defconst c-block-stmt-2-kwds | 481 | (c-lang-defconst c-block-stmt-2-kwds |
| 589 | php (append '("elseif" "foreach" "declare") | 482 | php '("catch" "declare" "elseif" "for" "foreach" "if" "switch" "while")) |
| 590 | (remove "synchronized" (c-lang-const c-block-stmt-2-kwds)))) | ||
| 591 | 483 | ||
| 592 | (c-lang-defconst c-simple-stmt-kwds | 484 | (c-lang-defconst c-simple-stmt-kwds |
| 593 | php (append '("include" "include_once" "require" "require_once" | 485 | php '("break" "continue" "die" "echo" "exit" "goto" "return" "throw" |
| 594 | "echo" "print" "die" "exit") | 486 | "include" "include_once" "print" "require" "require_once")) |
| 595 | (c-lang-const c-simple-stmt-kwds))) | ||
| 596 | 487 | ||
| 597 | (c-lang-defconst c-constant-kwds | 488 | (c-lang-defconst c-constant-kwds |
| 598 | php '("true" | 489 | php '("true" "false" "null")) |
| 599 | "false" | ||
| 600 | "null")) | ||
| 601 | 490 | ||
| 602 | (c-lang-defconst c-lambda-kwds | 491 | (c-lang-defconst c-lambda-kwds |
| 603 | php '("function" | 492 | php '("function" "use")) |
| 604 | "use")) | ||
| 605 | 493 | ||
| 606 | (c-lang-defconst c-other-block-decl-kwds | 494 | (c-lang-defconst c-other-block-decl-kwds |
| 607 | php '("namespace")) | 495 | php '("namespace")) |
| 608 | 496 | ||
| 609 | (c-lang-defconst c-other-kwds | 497 | (c-lang-defconst c-other-kwds |
| 610 | "Keywords not accounted for by any other `*-kwds' language constant." | 498 | "Keywords not accounted for by any other `*-kwds' language constant." |
| 611 | php '( | 499 | php |
| 500 | '( | ||
| 612 | "__halt_compiler" | 501 | "__halt_compiler" |
| 613 | "and" | 502 | "and" |
| 614 | "array" | 503 | "array" |
| 615 | "callable" | ||
| 616 | "iterable" | ||
| 617 | "as" | 504 | "as" |
| 618 | "break" | 505 | "break" |
| 619 | "catch" | 506 | "catch" |
| @@ -627,6 +514,7 @@ PHP does not have an \"enum\"-like keyword." | |||
| 627 | "endswitch" | 514 | "endswitch" |
| 628 | "endwhile" | 515 | "endwhile" |
| 629 | "eval" | 516 | "eval" |
| 517 | "fn" ;; NOT c-lambda-kwds | ||
| 630 | "global" | 518 | "global" |
| 631 | "isset" | 519 | "isset" |
| 632 | "list" | 520 | "list" |
| @@ -656,6 +544,12 @@ PHP does not have an \"enum\"-like keyword." | |||
| 656 | (c-lang-defconst c-recognize-<>-arglists | 544 | (c-lang-defconst c-recognize-<>-arglists |
| 657 | php nil) | 545 | php nil) |
| 658 | 546 | ||
| 547 | (c-lang-defconst c-<>-type-kwds | ||
| 548 | php nil) | ||
| 549 | |||
| 550 | (c-lang-defconst c-inside-<>-type-kwds | ||
| 551 | php nil) | ||
| 552 | |||
| 659 | (c-lang-defconst c-enums-contain-decls | 553 | (c-lang-defconst c-enums-contain-decls |
| 660 | php nil) | 554 | php nil) |
| 661 | 555 | ||
| @@ -679,6 +573,13 @@ might be to handle switch and goto labels differently." | |||
| 679 | php (cl-remove-if (lambda (elm) (and (listp elm) (equal (car elm) "\\s|"))) | 573 | php (cl-remove-if (lambda (elm) (and (listp elm) (equal (car elm) "\\s|"))) |
| 680 | (c-lang-const c-basic-matchers-before php))) | 574 | (c-lang-const c-basic-matchers-before php))) |
| 681 | 575 | ||
| 576 | (c-lang-defconst c-basic-matchers-after | ||
| 577 | php (cl-remove-if (lambda (elm) (and (listp elm) (memq 'c-annotation-face elm))) | ||
| 578 | (c-lang-const c-basic-matchers-after php))) | ||
| 579 | |||
| 580 | (c-lang-defconst c-opt-<>-sexp-key | ||
| 581 | php nil) | ||
| 582 | |||
| 682 | (defun php-lineup-cascaded-calls (langelem) | 583 | (defun php-lineup-cascaded-calls (langelem) |
| 683 | "Line up chained methods using `c-lineup-cascaded-calls', | 584 | "Line up chained methods using `c-lineup-cascaded-calls', |
| 684 | but only if the setting is enabled" | 585 | but only if the setting is enabled" |
| @@ -788,10 +689,10 @@ but only if the setting is enabled" | |||
| 788 | "Move to the beginning of the ARGth PHP function from point. | 689 | "Move to the beginning of the ARGth PHP function from point. |
| 789 | Implements PHP version of `beginning-of-defun-function'." | 690 | Implements PHP version of `beginning-of-defun-function'." |
| 790 | (interactive "p") | 691 | (interactive "p") |
| 791 | (let ((arg (or arg 1))) | 692 | (let (found-p (arg (or arg 1))) |
| 792 | (while (> arg 0) | 693 | (while (> arg 0) |
| 793 | (re-search-backward php-beginning-of-defun-regexp | 694 | (setq found-p (re-search-backward php-beginning-of-defun-regexp |
| 794 | nil 'noerror) | 695 | nil 'noerror)) |
| 795 | (setq arg (1- arg))) | 696 | (setq arg (1- arg))) |
| 796 | (while (< arg 0) | 697 | (while (< arg 0) |
| 797 | (end-of-line 1) | 698 | (end-of-line 1) |
| @@ -800,9 +701,10 @@ Implements PHP version of `beginning-of-defun-function'." | |||
| 800 | (forward-list 2) | 701 | (forward-list 2) |
| 801 | (forward-line 1) | 702 | (forward-line 1) |
| 802 | (if (eq opoint (point)) | 703 | (if (eq opoint (point)) |
| 803 | (re-search-forward php-beginning-of-defun-regexp | 704 | (setq found-p (re-search-forward php-beginning-of-defun-regexp |
| 804 | nil 'noerror)) | 705 | nil 'noerror))) |
| 805 | (setq arg (1+ arg)))))) | 706 | (setq arg (1+ arg)))) |
| 707 | (not (null found-p)))) | ||
| 806 | 708 | ||
| 807 | (defun php-end-of-defun (&optional arg) | 709 | (defun php-end-of-defun (&optional arg) |
| 808 | "Move the end of the ARGth PHP function from point. | 710 | "Move the end of the ARGth PHP function from point. |
| @@ -988,7 +890,7 @@ this ^ lineup" | |||
| 988 | "Build a regular expression for the end of a heredoc started by the string HEREDOC-START." | 890 | "Build a regular expression for the end of a heredoc started by the string HEREDOC-START." |
| 989 | ;; Extract just the identifier without <<< and quotes. | 891 | ;; Extract just the identifier without <<< and quotes. |
| 990 | (string-match "\\_<.+?\\_>" heredoc-start) | 892 | (string-match "\\_<.+?\\_>" heredoc-start) |
| 991 | (concat "^\\(" (match-string 0 heredoc-start) "\\)\\W")) | 893 | (concat "^\\s-*\\(" (match-string 0 heredoc-start) "\\)\\W")) |
| 992 | 894 | ||
| 993 | (defun php-syntax-propertize-function (start end) | 895 | (defun php-syntax-propertize-function (start end) |
| 994 | "Apply propertize rules from START to END." | 896 | "Apply propertize rules from START to END." |
| @@ -1000,12 +902,7 @@ this ^ lineup" | |||
| 1000 | (while (re-search-forward "['\"]" end t) | 902 | (while (re-search-forward "['\"]" end t) |
| 1001 | (when (php-in-comment-p) | 903 | (when (php-in-comment-p) |
| 1002 | (c-put-char-property (match-beginning 0) | 904 | (c-put-char-property (match-beginning 0) |
| 1003 | 'syntax-table (string-to-syntax "_")))) | 905 | 'syntax-table (string-to-syntax "_"))))) |
| 1004 | (funcall | ||
| 1005 | (syntax-propertize-rules | ||
| 1006 | ("\\(\"\\)\\(\\\\.\\|[^\"\n\\]\\)*\\(\"\\)" (1 "\"") (3 "\"")) | ||
| 1007 | ("\\('\\)\\(\\\\.\\|[^'\n\\]\\)*\\('\\)" (1 "\"") (3 "\""))) | ||
| 1008 | start end)) | ||
| 1009 | 906 | ||
| 1010 | (defun php-heredoc-syntax () | 907 | (defun php-heredoc-syntax () |
| 1011 | "Mark the boundaries of searched heredoc." | 908 | "Mark the boundaries of searched heredoc." |
| @@ -1041,106 +938,6 @@ this ^ lineup" | |||
| 1041 | (easy-menu-define php-mode-menu php-mode-map "PHP Mode Commands" | 938 | (easy-menu-define php-mode-menu php-mode-map "PHP Mode Commands" |
| 1042 | (cons "PHP" (c-lang-const c-mode-menu php))) | 939 | (cons "PHP" (c-lang-const c-mode-menu php))) |
| 1043 | 940 | ||
| 1044 | |||
| 1045 | ;; Faces | ||
| 1046 | |||
| 1047 | ;;;###autoload | ||
| 1048 | (defgroup php-faces nil | ||
| 1049 | "Faces used in PHP Mode" | ||
| 1050 | :tag "PHP Faces" | ||
| 1051 | :group 'php-mode | ||
| 1052 | :group 'faces) | ||
| 1053 | |||
| 1054 | (defface php-string '((t (:inherit font-lock-string-face))) | ||
| 1055 | "PHP Mode face used to highlight string literals." | ||
| 1056 | :group 'php-faces) | ||
| 1057 | |||
| 1058 | (defface php-keyword '((t (:inherit font-lock-keyword-face))) | ||
| 1059 | "PHP Mode face used to highlight keywords." | ||
| 1060 | :group 'php-faces) | ||
| 1061 | |||
| 1062 | (defface php-builtin '((t (:inherit font-lock-builtin-face))) | ||
| 1063 | "PHP Mode face used to highlight builtins." | ||
| 1064 | :group 'php-faces) | ||
| 1065 | |||
| 1066 | (defface php-function-name '((t (:inherit font-lock-function-name-face))) | ||
| 1067 | "PHP Mode face used to highlight function names." | ||
| 1068 | :group 'php-faces) | ||
| 1069 | |||
| 1070 | (defface php-function-call '((t (:inherit default))) | ||
| 1071 | "PHP Mode face used to highlight function names in calles." | ||
| 1072 | :group 'php-faces) | ||
| 1073 | |||
| 1074 | (defface php-method-call '((t (:inherit php-function-call))) | ||
| 1075 | "PHP Mode face used to highlight method names in calles." | ||
| 1076 | :group 'php-faces) | ||
| 1077 | |||
| 1078 | (defface php-static-method-call '((t (:inherit php-method-call))) | ||
| 1079 | "PHP Mode face used to highlight static method names in calles." | ||
| 1080 | :group 'php-faces) | ||
| 1081 | |||
| 1082 | (defface php-variable-name '((t (:inherit font-lock-variable-name-face))) | ||
| 1083 | "PHP Mode face used to highlight variable names." | ||
| 1084 | :group 'php-faces) | ||
| 1085 | |||
| 1086 | (defface php-property-name '((t (:inherit php-variable-name))) | ||
| 1087 | "PHP Mode face used to highlight property names." | ||
| 1088 | :group 'php-faces) | ||
| 1089 | |||
| 1090 | (defface php-variable-sigil '((t (:inherit default))) | ||
| 1091 | "PHP Mode face used to highlight variable sigils ($)." | ||
| 1092 | :group 'php-faces) | ||
| 1093 | |||
| 1094 | (defface php-object-op '((t (:inherit default))) | ||
| 1095 | "PHP Mode face used to object operators (->)." | ||
| 1096 | :group 'php-faces) | ||
| 1097 | |||
| 1098 | (defface php-paamayim-nekudotayim '((t (:inherit default))) | ||
| 1099 | "PHP Mode face used to highlight \"Paamayim Nekudotayim\" scope resolution operators (::)." | ||
| 1100 | :group 'php-faces) | ||
| 1101 | |||
| 1102 | (defface php-type '((t (:inherit font-lock-type-face))) | ||
| 1103 | "PHP Mode face used to highlight types." | ||
| 1104 | :group 'php-faces) | ||
| 1105 | |||
| 1106 | (defface php-constant '((t (:inherit font-lock-constant-face))) | ||
| 1107 | "PHP Mode face used to highlight constants." | ||
| 1108 | :group 'php-faces) | ||
| 1109 | |||
| 1110 | (defface php-$this '((t (:inherit php-constant))) | ||
| 1111 | "PHP Mode face used to highlight $this variables." | ||
| 1112 | :group 'php-faces) | ||
| 1113 | |||
| 1114 | (defface php-$this-sigil '((t (:inherit php-constant))) | ||
| 1115 | "PHP Mode face used to highlight sigils($) of $this variable." | ||
| 1116 | :group 'php-faces) | ||
| 1117 | |||
| 1118 | (defface php-php-tag '((t (:inherit font-lock-preprocessor-face))) | ||
| 1119 | "PHP Mode face used to highlight PHP tags." | ||
| 1120 | :group 'php-faces) | ||
| 1121 | |||
| 1122 | (defface php-doc-annotation-tag '((t . (:inherit font-lock-constant-face))) | ||
| 1123 | "Face used to highlight annotation tags in doc-comment." | ||
| 1124 | :group 'php-faces) | ||
| 1125 | |||
| 1126 | (defface php-doc-variable-sigil '((t (:inherit font-lock-variable-name-face))) | ||
| 1127 | "PHP Mode face used to highlight variable sigils($)." | ||
| 1128 | :group 'php-faces) | ||
| 1129 | |||
| 1130 | (defface php-doc-$this '((t (:inherit php-type))) | ||
| 1131 | "PHP Mode face used to highlight $this variable in doc-comment." | ||
| 1132 | :group 'php-faces) | ||
| 1133 | |||
| 1134 | (defface php-doc-$this-sigil '((t (:inherit php-type))) | ||
| 1135 | "PHP Mode face used to highlight sigil of $this variable in doc-comment." | ||
| 1136 | :group 'php-faces) | ||
| 1137 | |||
| 1138 | (defface php-doc-class-name '((t (:inherit php-string))) | ||
| 1139 | "Face used to class names in doc-comment." | ||
| 1140 | :group 'php-faces) | ||
| 1141 | |||
| 1142 | (define-obsolete-face-alias 'php-annotations-annotation-face 'php-doc-annotation-tag "1.19.0") | ||
| 1143 | |||
| 1144 | (defvar-local php-mode--delayed-set-style nil) | 941 | (defvar-local php-mode--delayed-set-style nil) |
| 1145 | 942 | ||
| 1146 | (defun php-set-style (stylename &optional dont-override) | 943 | (defun php-set-style (stylename &optional dont-override) |
| @@ -1199,70 +996,6 @@ After setting the stylevars run hooks according to STYLENAME | |||
| 1199 | (prog1 (php-set-style (symbol-name coding-style)) | 996 | (prog1 (php-set-style (symbol-name coding-style)) |
| 1200 | (remove-hook 'hack-local-variables-hook #'php-mode-set-style-delay))))) | 997 | (remove-hook 'hack-local-variables-hook #'php-mode-set-style-delay))))) |
| 1201 | 998 | ||
| 1202 | (defun php-mode-debug--buffer (&optional command &rest args) | ||
| 1203 | "Return buffer for php-mode-debug, and execute `COMMAND' with `ARGS'." | ||
| 1204 | (with-current-buffer (get-buffer-create "*PHP Mode DEBUG*") | ||
| 1205 | (cl-case command | ||
| 1206 | (init (erase-buffer) | ||
| 1207 | (goto-address-mode)) | ||
| 1208 | (top (goto-char (point-min))) | ||
| 1209 | (insert (goto-char (point-max)) | ||
| 1210 | (apply #'insert args))) | ||
| 1211 | (current-buffer))) | ||
| 1212 | |||
| 1213 | (defun php-mode-debug--message (format-string &rest args) | ||
| 1214 | "Write message `FORMAT-STRING' and `ARGS' to debug buffer, like `message'." | ||
| 1215 | (declare (indent 1)) | ||
| 1216 | (php-mode-debug--buffer 'insert (apply #'format format-string args) "\n")) | ||
| 1217 | |||
| 1218 | (declare-function custom-group-members "cus-edit" (symbol groups-only)) | ||
| 1219 | |||
| 1220 | (defun php-mode-debug () | ||
| 1221 | "Display informations useful for debugging PHP Mode." | ||
| 1222 | (interactive) | ||
| 1223 | (require 'cus-edit) | ||
| 1224 | (require 'pkg-info nil t) | ||
| 1225 | (php-mode-debug--buffer 'init) | ||
| 1226 | (php-mode-debug--message "Feel free to report on GitHub what you noticed!") | ||
| 1227 | (php-mode-debug--message "https://github.com/emacs-php/php-mode/issues/new") | ||
| 1228 | (php-mode-debug--message "") | ||
| 1229 | (php-mode-debug--message "Pasting the following information on the issue will help us to investigate the cause.") | ||
| 1230 | (php-mode-debug--message "```") | ||
| 1231 | (php-mode-debug--message "--- PHP-MODE DEBUG BEGIN ---") | ||
| 1232 | (php-mode-debug--message "versions: %s; %s" (emacs-version) (php-mode-version)) | ||
| 1233 | (php-mode-debug--message "package-version: %s" | ||
| 1234 | (if (fboundp 'pkg-info) | ||
| 1235 | (pkg-info-version-info 'php-mode) | ||
| 1236 | (let ((pkg (and (boundp 'package-alist) | ||
| 1237 | (cadr (assq 'php-mode package-alist))))) | ||
| 1238 | (when (and pkg (member (package-desc-status pkg) '("unsigned" "dependency"))) | ||
| 1239 | (package-version-join (package-desc-version pkg)))))) | ||
| 1240 | |||
| 1241 | (php-mode-debug--message "major-mode: %s" major-mode) | ||
| 1242 | (php-mode-debug--message "minor-modes: %s" | ||
| 1243 | (cl-loop for s in minor-mode-list | ||
| 1244 | unless (string-match-p "global" (symbol-name s)) | ||
| 1245 | if (and (boundp s) (symbol-value s)) | ||
| 1246 | collect s)) | ||
| 1247 | (php-mode-debug--message "variables: %s" | ||
| 1248 | (cl-loop for v in '(indent-tabs-mode tab-width) | ||
| 1249 | collect (list v (symbol-value v)))) | ||
| 1250 | (php-mode-debug--message "custom variables: %s" | ||
| 1251 | (cl-loop for (v type) in (custom-group-members 'php nil) | ||
| 1252 | if (eq type 'custom-variable) | ||
| 1253 | collect (list v (symbol-value v)))) | ||
| 1254 | (php-mode-debug--message "c-indentation-style: %s" c-indentation-style) | ||
| 1255 | (php-mode-debug--message "c-style-variables: %s" | ||
| 1256 | (cl-loop for v in c-style-variables | ||
| 1257 | unless (memq v '(c-doc-comment-style c-offsets-alist)) | ||
| 1258 | collect (list v (symbol-value v)))) | ||
| 1259 | (php-mode-debug--message "c-doc-comment-style: %s" c-doc-comment-style) | ||
| 1260 | (php-mode-debug--message "c-offsets-alist: %s" c-offsets-alist) | ||
| 1261 | (php-mode-debug--message "--- PHP-MODE DEBUG END ---") | ||
| 1262 | (php-mode-debug--message "```\n") | ||
| 1263 | (php-mode-debug--message "Thank you!") | ||
| 1264 | (pop-to-buffer (php-mode-debug--buffer 'top))) | ||
| 1265 | |||
| 1266 | ;;;###autoload | 999 | ;;;###autoload |
| 1267 | (define-derived-mode php-mode c-mode "PHP" | 1000 | (define-derived-mode php-mode c-mode "PHP" |
| 1268 | "Major mode for editing PHP code. | 1001 | "Major mode for editing PHP code. |
| @@ -1657,21 +1390,16 @@ a completion list." | |||
| 1657 | ;; Highlight variables, e.g. 'var' in '$var' and '$obj->var', but | 1390 | ;; Highlight variables, e.g. 'var' in '$var' and '$obj->var', but |
| 1658 | ;; not in $obj->var() | 1391 | ;; not in $obj->var() |
| 1659 | ("\\(->\\)\\(\\sw+\\)\\s-*(" (1 'php-object-op) (2 'php-method-call)) | 1392 | ("\\(->\\)\\(\\sw+\\)\\s-*(" (1 'php-object-op) (2 'php-method-call)) |
| 1393 | ("\\<\\(const\\)\\s-+\\(\\_<.+?\\_>\\)" (1 'php-keyword) (2 'php-constant-assign)) | ||
| 1660 | 1394 | ||
| 1661 | ;; Highlight special variables | 1395 | ;; Highlight special variables |
| 1662 | ("\\(\\$\\)\\(this\\|that\\)\\_>" (1 'php-$this-sigil) (2 'php-$this)) | 1396 | ("\\(\\$\\)\\(this\\)\\>" (1 'php-$this-sigil) (2 'php-$this)) |
| 1663 | ("\\(\\$\\)\\([a-zA-Z0-9_]+\\)" (1 'php-variable-sigil) (2 'php-variable-name)) | 1397 | ("\\(\\$+\\)\\(\\sw+\\)" (1 'php-variable-sigil) (2 'php-variable-name)) |
| 1664 | ("\\(->\\)\\([a-zA-Z0-9_]+\\)" (1 'php-object-op) (2 'php-property-name)) | 1398 | ("\\(->\\)\\([a-zA-Z0-9_]+\\)" (1 'php-object-op) (2 'php-property-name)) |
| 1665 | 1399 | ||
| 1666 | ;; Highlight function/method names | 1400 | ;; Highlight function/method names |
| 1667 | ("\\<function\\s-+&?\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1 'php-function-name) | 1401 | ("\\<function\\s-+&?\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1 'php-function-name) |
| 1668 | 1402 | ||
| 1669 | ;; The dollar sign should not get a variable-name face, below | ||
| 1670 | ;; pattern resets the face to default in case cc-mode sets the | ||
| 1671 | ;; variable-name face (cc-mode does this for variables prefixed | ||
| 1672 | ;; with type, like in arglist) | ||
| 1673 | ("\\(\\$\\)\\(\\sw+\\)" 1 'php-variable-sigil) | ||
| 1674 | |||
| 1675 | ;; 'array' and 'callable' are keywords, except in the following situations: | 1403 | ;; 'array' and 'callable' are keywords, except in the following situations: |
| 1676 | ;; - when used as a type hint | 1404 | ;; - when used as a type hint |
| 1677 | ;; - when used as a return type | 1405 | ;; - when used as a return type |
| @@ -1681,12 +1409,17 @@ a completion list." | |||
| 1681 | ;; - when used as cast, so that (int) and (array) look the same | 1409 | ;; - when used as cast, so that (int) and (array) look the same |
| 1682 | ("(\\(array\\))" 1 font-lock-type-face) | 1410 | ("(\\(array\\))" 1 font-lock-type-face) |
| 1683 | 1411 | ||
| 1412 | (,(regexp-opt php-magical-constants 'symbols) (1 'php-magical-constant)) | ||
| 1684 | ;; namespaces | 1413 | ;; namespaces |
| 1685 | ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)[^:a-zA-Z0-9_\\\\]" 1 'font-lock-type-face) | 1414 | ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)[^:a-zA-Z0-9_\\\\]" 1 'font-lock-type-face) |
| 1686 | ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)::" 1 'php-constant) | 1415 | ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)::" 1 'php-constant) |
| 1687 | 1416 | ||
| 1688 | ;; Support the ::class constant in PHP5.6 | 1417 | ;; Support the ::class constant in PHP5.6 |
| 1689 | ("\\sw+\\(::\\)\\(class\\)\\b" (1 'php-paamayim-nekudotayim) (2 'php-constant)) | 1418 | ("\\sw+\\(::\\)\\(class\\)\\b" (1 'php-paamayim-nekudotayim) (2 'php-magical-constant)) |
| 1419 | |||
| 1420 | ;; Highlight static method calls as such. This is necessary for method | ||
| 1421 | ;; names which are identical to keywords to be highlighted correctly. | ||
| 1422 | ("\\sw+::\\(\\sw+\\)(" 1 'php-static-method-call) | ||
| 1690 | 1423 | ||
| 1691 | ;; While c-opt-cpp-* highlights the <?php opening tags, it is not | 1424 | ;; While c-opt-cpp-* highlights the <?php opening tags, it is not |
| 1692 | ;; possible to make it highlight short open tags and closing tags | 1425 | ;; possible to make it highlight short open tags and closing tags |
| @@ -1711,6 +1444,7 @@ a completion list." | |||
| 1711 | ;; already fontified by another pattern. Note that using OVERRIDE | 1444 | ;; already fontified by another pattern. Note that using OVERRIDE |
| 1712 | ;; is usually overkill. | 1445 | ;; is usually overkill. |
| 1713 | `( | 1446 | `( |
| 1447 | ("\\<\\(@\\)" 1 'php-errorcontrol-op) | ||
| 1714 | ;; Highlight all upper-cased symbols as constant | 1448 | ;; Highlight all upper-cased symbols as constant |
| 1715 | ("\\<\\([A-Z_][A-Z0-9_]+\\)\\>" 1 'php-constant) | 1449 | ("\\<\\([A-Z_][A-Z0-9_]+\\)\\>" 1 'php-constant) |
| 1716 | 1450 | ||
| @@ -1756,34 +1490,12 @@ a completion list." | |||
| 1756 | (defvar php-font-lock-keywords php-font-lock-keywords-3 | 1490 | (defvar php-font-lock-keywords php-font-lock-keywords-3 |
| 1757 | "Default expressions to highlight in PHP Mode.") | 1491 | "Default expressions to highlight in PHP Mode.") |
| 1758 | 1492 | ||
| 1759 | ;;; Provide support for Flymake so that users can see warnings and | 1493 | (add-to-list |
| 1760 | ;;; errors in real-time as they write code. | 1494 | (eval-when-compile |
| 1761 | 1495 | (if (boundp 'flymake-proc-allowed-file-name-masks) | |
| 1762 | (defun php-flymake-php-init () | 1496 | 'flymake-proc-allowed-file-name-masks |
| 1763 | "PHP specific init-cleanup routines. | 1497 | 'flymake-allowed-file-name-masks)) |
| 1764 | 1498 | '("\\.php[345s]?\\'" php-flymake-php-init)) | |
| 1765 | This is an alternative function of `flymake-php-init'. | ||
| 1766 | Look at the `php-executable' variable instead of the constant \"php\" command." | ||
| 1767 | (let* ((temp-file | ||
| 1768 | (funcall | ||
| 1769 | (eval-when-compile | ||
| 1770 | (if (fboundp 'flymake-proc-init-create-temp-buffer-copy) | ||
| 1771 | 'flymake-proc-init-create-temp-buffer-copy | ||
| 1772 | 'flymake-init-create-temp-buffer-copy)) | ||
| 1773 | 'flymake-create-temp-inplace)) | ||
| 1774 | (local-file (file-relative-name | ||
| 1775 | temp-file | ||
| 1776 | (file-name-directory buffer-file-name)))) | ||
| 1777 | (list php-executable (list "-f" local-file "-l")))) | ||
| 1778 | |||
| 1779 | (add-to-list 'flymake-allowed-file-name-masks | ||
| 1780 | '("\\.php[345s]?\\'" | ||
| 1781 | php-flymake-php-init | ||
| 1782 | flymake-simple-cleanup | ||
| 1783 | flymake-get-real-file-name)) | ||
| 1784 | |||
| 1785 | (add-to-list 'flymake-err-line-patterns | ||
| 1786 | '("\\(Parse\\|Fatal\\) error: \\(.*?\\) in \\(.*?\\) on line \\([0-9]+\\)" 3 4 nil 2)) | ||
| 1787 | 1499 | ||
| 1788 | 1500 | ||
| 1789 | (defun php-send-region (start end) | 1501 | (defun php-send-region (start end) |
| @@ -1836,46 +1548,6 @@ The output will appear in the buffer *PHP*." | |||
| 1836 | 1548 | ||
| 1837 | (ad-activate 'fixup-whitespace) | 1549 | (ad-activate 'fixup-whitespace) |
| 1838 | 1550 | ||
| 1839 | |||
| 1840 | (defcustom php-class-suffix-when-insert "::" | ||
| 1841 | "Suffix for inserted class." | ||
| 1842 | :group 'php | ||
| 1843 | :type 'string) | ||
| 1844 | |||
| 1845 | (defcustom php-namespace-suffix-when-insert "\\" | ||
| 1846 | "Suffix for inserted namespace." | ||
| 1847 | :group 'php | ||
| 1848 | :type 'string) | ||
| 1849 | |||
| 1850 | (defvar php--re-namespace-pattern | ||
| 1851 | (php-create-regexp-for-classlike "namespace")) | ||
| 1852 | |||
| 1853 | (defvar php--re-classlike-pattern | ||
| 1854 | (php-create-regexp-for-classlike (regexp-opt '("class" "interface" "trait")))) | ||
| 1855 | |||
| 1856 | (defun php-get-current-element (re-pattern) | ||
| 1857 | "Return backward matched element by RE-PATTERN." | ||
| 1858 | (save-excursion | ||
| 1859 | (when (re-search-backward re-pattern nil t) | ||
| 1860 | (match-string-no-properties 1)))) | ||
| 1861 | |||
| 1862 | ;;;###autoload | ||
| 1863 | (defun php-current-class () | ||
| 1864 | "Insert current class name if cursor in class context." | ||
| 1865 | (interactive) | ||
| 1866 | (let ((matched (php-get-current-element php--re-classlike-pattern))) | ||
| 1867 | (when matched | ||
| 1868 | (insert (concat matched php-class-suffix-when-insert))))) | ||
| 1869 | |||
| 1870 | ;;;###autoload | ||
| 1871 | (defun php-current-namespace () | ||
| 1872 | "Insert current namespace if cursor in namespace context." | ||
| 1873 | (interactive) | ||
| 1874 | (let ((matched (php-get-current-element php--re-namespace-pattern))) | ||
| 1875 | (when matched | ||
| 1876 | (insert (concat matched php-namespace-suffix-when-insert))))) | ||
| 1877 | |||
| 1878 | |||
| 1879 | ;;;###autoload | 1551 | ;;;###autoload |
| 1880 | (add-to-list 'auto-mode-alist | 1552 | (add-to-list 'auto-mode-alist |
| 1881 | (cons | 1553 | (cons |
diff --git a/.emacs.d/lisp/php-project.el b/.emacs.d/lisp/php-project.el index a2aa253..e12d83a 100644 --- a/.emacs.d/lisp/php-project.el +++ b/.emacs.d/lisp/php-project.el | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ;; Author: USAMI Kenta <tadsan@zonu.me> | 5 | ;; Author: USAMI Kenta <tadsan@zonu.me> |
| 6 | ;; Keywords: tools, files | 6 | ;; Keywords: tools, files |
| 7 | ;; URL: https://github.com/emacs-php/php-mode | 7 | ;; URL: https://github.com/emacs-php/php-mode |
| 8 | ;; Version: 1.21.0 | 8 | ;; Version: 1.21.2 |
| 9 | ;; Package-Requires: ((emacs "24.3") (cl-lib "0.5")) | 9 | ;; Package-Requires: ((emacs "24.3") (cl-lib "0.5")) |
| 10 | ;; License: GPL-3.0-or-later | 10 | ;; License: GPL-3.0-or-later |
| 11 | 11 | ||
diff --git a/.emacs.d/lisp/php.el b/.emacs.d/lisp/php.el new file mode 100644 index 0000000..db9e46d --- /dev/null +++ b/.emacs.d/lisp/php.el | |||
| @@ -0,0 +1,207 @@ | |||
| 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.21.2 | ||
| 8 | ;; Keywords: languages, php | ||
| 9 | ;; Homepage: https://github.com/emacs-php/php-mode | ||
| 10 | ;; Package-Requires: ((emacs "24.3") (cl-lib "0.5")) | ||
| 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 'flymake) | ||
| 32 | |||
| 33 | ;;;###autoload | ||
| 34 | (defgroup php nil | ||
| 35 | "Language support for PHP." | ||
| 36 | :tag "PHP" | ||
| 37 | :group 'languages | ||
| 38 | :link '(url-link :tag "Official Site" "https://github.com/emacs-php/php-mode") | ||
| 39 | :link '(url-link :tag "PHP Mode Wiki" "https://github.com/emacs-php/php-mode/wiki")) | ||
| 40 | |||
| 41 | (defcustom php-executable (or (executable-find "php") "/usr/bin/php") | ||
| 42 | "The location of the PHP executable." | ||
| 43 | :type 'string) | ||
| 44 | |||
| 45 | (defcustom php-site-url "https://php.net/" | ||
| 46 | "Default PHP.net site URL. | ||
| 47 | |||
| 48 | The URL to use open PHP manual and search word." | ||
| 49 | :type 'string) | ||
| 50 | |||
| 51 | (defcustom php-manual-url 'en | ||
| 52 | "URL at which to find PHP manual. | ||
| 53 | You can replace \"en\" with your ISO language code." | ||
| 54 | :type '(choice (const :tag "English" 'en) | ||
| 55 | (const :tag "Brazilian Portuguese" 'pt_BR) | ||
| 56 | (const :tag "Chinese (Simplified)" 'zh) | ||
| 57 | (const :tag "French" 'fr) | ||
| 58 | (const :tag "German" 'de) | ||
| 59 | (const :tag "Japanese" 'ja) | ||
| 60 | (const :tag "Romanian" 'ro) | ||
| 61 | (const :tag "Russian" 'ru) | ||
| 62 | (const :tag "Spanish" 'es) | ||
| 63 | (const :tag "Turkish" 'tr) | ||
| 64 | (string :tag "PHP manual URL"))) | ||
| 65 | |||
| 66 | (defcustom php-search-url nil | ||
| 67 | "URL at which to search for documentation on a word." | ||
| 68 | :group 'php | ||
| 69 | :type '(choice (string :tag "URL to search PHP documentation") | ||
| 70 | (const :tag "Use `php-site-url' variable" nil))) | ||
| 71 | |||
| 72 | (defcustom php-class-suffix-when-insert "::" | ||
| 73 | "Suffix for inserted class." | ||
| 74 | :group 'php | ||
| 75 | :type 'string) | ||
| 76 | |||
| 77 | (defcustom php-namespace-suffix-when-insert "\\" | ||
| 78 | "Suffix for inserted namespace." | ||
| 79 | :group 'php | ||
| 80 | :type 'string) | ||
| 81 | |||
| 82 | ;;; PHP Keywords | ||
| 83 | (defconst php-magical-constants | ||
| 84 | (list "__LINE__" "__FILE__" "__FUNCTION__" "__CLASS__" "__TRAIT__" "__METHOD__" "__NAMESPACE__") | ||
| 85 | "Magical keyword that is expanded at compile time. | ||
| 86 | |||
| 87 | These are different from \"constants\" in strict terms. | ||
| 88 | see https://www.php.net/manual/language.constants.predefined.php") | ||
| 89 | |||
| 90 | ;;; Utillity for locate language construction | ||
| 91 | (defsubst php-in-string-p () | ||
| 92 | "Return non-nil if inside a string. | ||
| 93 | it is the character that will terminate the string, or t if the string should be terminated by a generic string delimiter." | ||
| 94 | (nth 3 (syntax-ppss))) | ||
| 95 | |||
| 96 | (defsubst php-in-comment-p () | ||
| 97 | "Return nil if outside a comment, t if inside a non-nestable comment, else an integer (the current comment nesting)." | ||
| 98 | (nth 4 (syntax-ppss))) | ||
| 99 | |||
| 100 | (defsubst php-in-string-or-comment-p () | ||
| 101 | "Return character address of start of comment or string; nil if not in one." | ||
| 102 | (nth 8 (syntax-ppss))) | ||
| 103 | |||
| 104 | (defun php-create-regexp-for-method (visibility) | ||
| 105 | "Make a regular expression for methods with the given VISIBILITY. | ||
| 106 | |||
| 107 | VISIBILITY must be a string that names the visibility for a PHP | ||
| 108 | method, e.g. 'public'. The parameter VISIBILITY can itself also | ||
| 109 | be a regular expression. | ||
| 110 | |||
| 111 | The regular expression this function returns will check for other | ||
| 112 | keywords that can appear in method signatures, e.g. 'final' and | ||
| 113 | 'static'. The regular expression will have one capture group | ||
| 114 | which will be the name of the method." | ||
| 115 | (concat | ||
| 116 | ;; Initial space with possible 'abstract' or 'final' keywords | ||
| 117 | "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?" | ||
| 118 | ;; 'static' keyword may come either before or after visibility | ||
| 119 | "\\(?:" visibility "\\(?:\\s-+static\\)?\\|\\(?:static\\s-+\\)?" visibility "\\)\\s-+" | ||
| 120 | ;; Make sure 'function' comes next with some space after | ||
| 121 | "function\\s-+" | ||
| 122 | ;; Capture the name as the first group and the regexp and make sure | ||
| 123 | ;; by the end we see the opening parenthesis for the parameters. | ||
| 124 | "\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(")) | ||
| 125 | |||
| 126 | (defun php-create-regexp-for-classlike (type) | ||
| 127 | "Accepts a `TYPE' of a 'classlike' object as a string, such as | ||
| 128 | 'class' or 'interface', and returns a regexp as a string which | ||
| 129 | can be used to match against definitions for that classlike." | ||
| 130 | (concat | ||
| 131 | ;; First see if 'abstract' or 'final' appear, although really these | ||
| 132 | ;; are not valid for all values of `type' that the function | ||
| 133 | ;; accepts. | ||
| 134 | "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?" | ||
| 135 | ;; The classlike type | ||
| 136 | type | ||
| 137 | ;; Its name, which is the first captured group in the regexp. We | ||
| 138 | ;; allow backslashes in the name to handle namespaces, but again | ||
| 139 | ;; this is not necessarily correct for all values of `type'. | ||
| 140 | "\\s-+\\(\\(?:\\sw\\|\\\\\\|\\s_\\)+\\)")) | ||
| 141 | |||
| 142 | (defvar php-imenu-generic-expression | ||
| 143 | `(("Namespaces" | ||
| 144 | ,(php-create-regexp-for-classlike "namespace") 1) | ||
| 145 | ("Classes" | ||
| 146 | ,(php-create-regexp-for-classlike "class") 1) | ||
| 147 | ("Interfaces" | ||
| 148 | ,(php-create-regexp-for-classlike "interface") 1) | ||
| 149 | ("Traits" | ||
| 150 | ,(php-create-regexp-for-classlike "trait") 1) | ||
| 151 | ("All Methods" | ||
| 152 | ,(php-create-regexp-for-method "\\(?:\\sw\\|\\s_\\)+") 1) | ||
| 153 | ("Private Methods" | ||
| 154 | ,(php-create-regexp-for-method "private") 1) | ||
| 155 | ("Protected Methods" | ||
| 156 | ,(php-create-regexp-for-method "protected") 1) | ||
| 157 | ("Public Methods" | ||
| 158 | ,(php-create-regexp-for-method "public") 1) | ||
| 159 | ("Anonymous Functions" | ||
| 160 | "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*function\\s-*(" 1) | ||
| 161 | ("Named Functions" | ||
| 162 | "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1)) | ||
| 163 | "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.") | ||
| 164 | |||
| 165 | (defvar php--re-namespace-pattern | ||
| 166 | (php-create-regexp-for-classlike "namespace")) | ||
| 167 | |||
| 168 | (defvar php--re-classlike-pattern | ||
| 169 | (php-create-regexp-for-classlike (regexp-opt '("class" "interface" "trait")))) | ||
| 170 | |||
| 171 | (defun php-get-current-element (re-pattern) | ||
| 172 | "Return backward matched element by RE-PATTERN." | ||
| 173 | (save-excursion | ||
| 174 | (when (re-search-backward re-pattern nil t) | ||
| 175 | (match-string-no-properties 1)))) | ||
| 176 | |||
| 177 | ;;; Provide support for Flymake so that users can see warnings and | ||
| 178 | ;;; errors in real-time as they write code. | ||
| 179 | (defun php-flymake-php-init () | ||
| 180 | "PHP specific init-cleanup routines. | ||
| 181 | |||
| 182 | This is an alternative function of `flymake-php-init'. | ||
| 183 | Look at the `php-executable' variable instead of the constant \"php\" command." | ||
| 184 | (let* ((init (funcall (eval-when-compile | ||
| 185 | (if (fboundp 'flymake-proc-php-init) | ||
| 186 | 'flymake-proc-php-init | ||
| 187 | 'flymake-php-init))))) | ||
| 188 | (list php-executable (cdr init)))) | ||
| 189 | |||
| 190 | ;;;###autoload | ||
| 191 | (defun php-current-class () | ||
| 192 | "Insert current class name if cursor in class context." | ||
| 193 | (interactive) | ||
| 194 | (let ((matched (php-get-current-element php--re-classlike-pattern))) | ||
| 195 | (when matched | ||
| 196 | (insert (concat matched php-class-suffix-when-insert))))) | ||
| 197 | |||
| 198 | ;;;###autoload | ||
| 199 | (defun php-current-namespace () | ||
| 200 | "Insert current namespace if cursor in namespace context." | ||
| 201 | (interactive) | ||
| 202 | (let ((matched (php-get-current-element php--re-namespace-pattern))) | ||
| 203 | (when matched | ||
| 204 | (insert (concat matched php-namespace-suffix-when-insert))))) | ||
| 205 | |||
| 206 | (provide 'php) | ||
| 207 | ;;; php.el ends here | ||
diff --git a/.emacs.d/lisp/yasnippet.el b/.emacs.d/lisp/yasnippet.el index 065e709..9951940 100644 --- a/.emacs.d/lisp/yasnippet.el +++ b/.emacs.d/lisp/yasnippet.el | |||
| @@ -413,15 +413,25 @@ This can be used as a key definition in keymaps to bind a key to | |||
| 413 | `yas-clear-field' only when at the beginning of an | 413 | `yas-clear-field' only when at the beginning of an |
| 414 | unmodified snippet field.") | 414 | unmodified snippet field.") |
| 415 | 415 | ||
| 416 | (defvar yas-keymap (let ((map (make-sparse-keymap))) | 416 | (defun yas-filtered-definition (def) |
| 417 | (define-key map [(tab)] 'yas-next-field-or-maybe-expand) | 417 | "Return a condition key definition. |
| 418 | (define-key map (kbd "TAB") 'yas-next-field-or-maybe-expand) | 418 | The condition will respect the value of `yas-keymap-disable-hook'." |
| 419 | (define-key map [(shift tab)] 'yas-prev-field) | 419 | `(menu-item "" ,def |
| 420 | (define-key map [backtab] 'yas-prev-field) | 420 | :filter ,(lambda (cmd) (unless (run-hook-with-args-until-success |
| 421 | (define-key map (kbd "C-g") 'yas-abort-snippet) | 421 | 'yas-keymap-disable-hook) |
| 422 | (define-key map (kbd "C-d") yas-maybe-skip-and-clear-field) | 422 | cmd)))) |
| 423 | (define-key map (kbd "DEL") yas-maybe-clear-field) | 423 | |
| 424 | map) | 424 | (defvar yas-keymap |
| 425 | (let ((map (make-sparse-keymap))) | ||
| 426 | (define-key map [(tab)] (yas-filtered-definition 'yas-next-field-or-maybe-expand)) | ||
| 427 | (define-key map (kbd "TAB") (yas-filtered-definition 'yas-next-field-or-maybe-expand)) | ||
| 428 | (define-key map [(shift tab)] (yas-filtered-definition 'yas-prev-field)) | ||
| 429 | (define-key map [backtab] (yas-filtered-definition 'yas-prev-field)) | ||
| 430 | (define-key map (kbd "C-g") (yas-filtered-definition 'yas-abort-snippet)) | ||
| 431 | ;; Yes, filters can be chained! | ||
| 432 | (define-key map (kbd "C-d") (yas-filtered-definition yas-maybe-skip-and-clear-field)) | ||
| 433 | (define-key map (kbd "DEL") (yas-filtered-definition yas-maybe-clear-field)) | ||
| 434 | map) | ||
| 425 | "The active keymap while a snippet expansion is in progress.") | 435 | "The active keymap while a snippet expansion is in progress.") |
| 426 | 436 | ||
| 427 | (defvar yas-key-syntaxes (list #'yas-try-key-from-whitespace | 437 | (defvar yas-key-syntaxes (list #'yas-try-key-from-whitespace |
| @@ -481,10 +491,8 @@ Attention: These hooks are not run when exiting nested/stacked snippet expansion | |||
| 481 | "Hooks to run just before expanding a snippet.") | 491 | "Hooks to run just before expanding a snippet.") |
| 482 | 492 | ||
| 483 | (defconst yas-not-string-or-comment-condition | 493 | (defconst yas-not-string-or-comment-condition |
| 484 | '(if (and (let ((ppss (syntax-ppss))) | 494 | '(if (let ((ppss (syntax-ppss))) |
| 485 | (or (nth 3 ppss) (nth 4 ppss))) | 495 | (or (nth 3 ppss) (nth 4 ppss))) |
| 486 | (memq this-command '(yas-expand yas-expand-from-trigger-key | ||
| 487 | yas-expand-from-keymap))) | ||
| 488 | '(require-snippet-condition . force-in-comment) | 496 | '(require-snippet-condition . force-in-comment) |
| 489 | t) | 497 | t) |
| 490 | "Disables snippet expansion in strings and comments. | 498 | "Disables snippet expansion in strings and comments. |
| @@ -547,12 +555,28 @@ conditions. | |||
| 547 | (const :tag "Disable all snippet expansion" nil) | 555 | (const :tag "Disable all snippet expansion" nil) |
| 548 | sexp)) | 556 | sexp)) |
| 549 | 557 | ||
| 558 | (defcustom yas-keymap-disable-hook nil | ||
| 559 | "The `yas-keymap' bindings are disabled if any function in this list returns non-nil. | ||
| 560 | This is useful to control whether snippet navigation bindings | ||
| 561 | override bindings from other packages (e.g., `company-mode')." | ||
| 562 | :type 'hook) | ||
| 563 | |||
| 550 | (defcustom yas-overlay-priority 100 | 564 | (defcustom yas-overlay-priority 100 |
| 551 | "Priority to use for yasnippets overlays. | 565 | "Priority to use for yasnippets overlays. |
| 552 | This is useful to control whether snippet navigation bindings | 566 | This is useful to control whether snippet navigation bindings |
| 553 | override bindings from other packages (e.g., `company-mode')." | 567 | override `keymap' overlay property bindings from other packages." |
| 554 | :type 'integer) | 568 | :type 'integer) |
| 555 | 569 | ||
| 570 | (defcustom yas-inhibit-overlay-modification-protection nil | ||
| 571 | "If nil, changing text outside the active field aborts the snippet. | ||
| 572 | This protection is intended to prevent yasnippet from ending up | ||
| 573 | in an inconsistent state. However, some packages (e.g., the | ||
| 574 | company completion package) may trigger this protection when it | ||
| 575 | is not needed. In that case, setting this variable to non-nil | ||
| 576 | can be useful." | ||
| 577 | ;; See also `yas--on-protection-overlay-modification'. | ||
| 578 | :type 'boolean) | ||
| 579 | |||
| 556 | 580 | ||
| 557 | ;;; Internal variables | 581 | ;;; Internal variables |
| 558 | 582 | ||
| @@ -918,9 +942,12 @@ activate snippets associated with that mode." | |||
| 918 | (remove mode | 942 | (remove mode |
| 919 | yas--extra-modes))) | 943 | yas--extra-modes))) |
| 920 | 944 | ||
| 945 | (defun yas-temp-buffer-p (&optional buffer) | ||
| 946 | (eq (aref (buffer-name buffer) 0) ?\s)) | ||
| 947 | |||
| 921 | (define-obsolete-variable-alias 'yas-dont-activate | 948 | (define-obsolete-variable-alias 'yas-dont-activate |
| 922 | 'yas-dont-activate-functions "0.9.2") | 949 | 'yas-dont-activate-functions "0.9.2") |
| 923 | (defvar yas-dont-activate-functions (list #'minibufferp) | 950 | (defvar yas-dont-activate-functions (list #'minibufferp #'yas-temp-buffer-p) |
| 924 | "Special hook to control which buffers `yas-global-mode' affects. | 951 | "Special hook to control which buffers `yas-global-mode' affects. |
| 925 | Functions are called with no argument, and should return non-nil to prevent | 952 | Functions are called with no argument, and should return non-nil to prevent |
| 926 | `yas-global-mode' from enabling yasnippet in this buffer. | 953 | `yas-global-mode' from enabling yasnippet in this buffer. |
| @@ -1665,10 +1692,8 @@ Here's a list of currently recognized directives: | |||
| 1665 | (let ((where (if (region-active-p) | 1692 | (let ((where (if (region-active-p) |
| 1666 | (cons (region-beginning) (region-end)) | 1693 | (cons (region-beginning) (region-end)) |
| 1667 | (cons (point) (point))))) | 1694 | (cons (point) (point))))) |
| 1668 | (yas-expand-snippet (yas--template-content yas--current-template) | 1695 | (yas-expand-snippet yas--current-template |
| 1669 | (car where) | 1696 | (car where) (cdr where))))))) |
| 1670 | (cdr where) | ||
| 1671 | (yas--template-expand-env yas--current-template))))))) | ||
| 1672 | 1697 | ||
| 1673 | (defun yas--key-from-desc (text) | 1698 | (defun yas--key-from-desc (text) |
| 1674 | "Return a yasnippet key from a description string TEXT." | 1699 | "Return a yasnippet key from a description string TEXT." |
| @@ -2345,6 +2370,10 @@ object satisfying `yas--field-p' to restrict the expansion to." | |||
| 2345 | (yas--fallback)))) | 2370 | (yas--fallback)))) |
| 2346 | 2371 | ||
| 2347 | (defun yas--maybe-expand-from-keymap-filter (cmd) | 2372 | (defun yas--maybe-expand-from-keymap-filter (cmd) |
| 2373 | "Check whether a snippet may be expanded. | ||
| 2374 | If there are expandable snippets, return CMD (this is useful for | ||
| 2375 | conditional keybindings) or the list of expandable snippet | ||
| 2376 | template objects if CMD is nil (this is useful as a more general predicate)." | ||
| 2348 | (let* ((yas--condition-cache-timestamp (current-time)) | 2377 | (let* ((yas--condition-cache-timestamp (current-time)) |
| 2349 | (vec (cl-subseq (this-command-keys-vector) | 2378 | (vec (cl-subseq (this-command-keys-vector) |
| 2350 | (if current-prefix-arg | 2379 | (if current-prefix-arg |
| @@ -2369,14 +2398,12 @@ object satisfying `yas--field-p' to restrict the expansion to." | |||
| 2369 | Prompt the user if TEMPLATES has more than one element, else | 2398 | Prompt the user if TEMPLATES has more than one element, else |
| 2370 | expand immediately. Common gateway for | 2399 | expand immediately. Common gateway for |
| 2371 | `yas-expand-from-trigger-key' and `yas-expand-from-keymap'." | 2400 | `yas-expand-from-trigger-key' and `yas-expand-from-keymap'." |
| 2372 | (let ((yas--current-template (or (and (cl-rest templates) ;; more than one | 2401 | (let ((yas--current-template |
| 2373 | (yas--prompt-for-template (mapcar #'cdr templates))) | 2402 | (or (and (cl-rest templates) ;; more than one |
| 2374 | (cdar templates)))) | 2403 | (yas--prompt-for-template (mapcar #'cdr templates))) |
| 2404 | (cdar templates)))) | ||
| 2375 | (when yas--current-template | 2405 | (when yas--current-template |
| 2376 | (yas-expand-snippet (yas--template-content yas--current-template) | 2406 | (yas-expand-snippet yas--current-template start end)))) |
| 2377 | start | ||
| 2378 | end | ||
| 2379 | (yas--template-expand-env yas--current-template))))) | ||
| 2380 | 2407 | ||
| 2381 | ;; Apropos the trigger key and the fallback binding: | 2408 | ;; Apropos the trigger key and the fallback binding: |
| 2382 | ;; | 2409 | ;; |
| @@ -2521,10 +2548,7 @@ by condition." | |||
| 2521 | (cons (region-beginning) (region-end)) | 2548 | (cons (region-beginning) (region-end)) |
| 2522 | (cons (point) (point))))) | 2549 | (cons (point) (point))))) |
| 2523 | (if yas--current-template | 2550 | (if yas--current-template |
| 2524 | (yas-expand-snippet (yas--template-content yas--current-template) | 2551 | (yas-expand-snippet yas--current-template (car where) (cdr where)) |
| 2525 | (car where) | ||
| 2526 | (cdr where) | ||
| 2527 | (yas--template-expand-env yas--current-template)) | ||
| 2528 | (yas--message 1 "No snippets can be inserted here!")))) | 2552 | (yas--message 1 "No snippets can be inserted here!")))) |
| 2529 | 2553 | ||
| 2530 | (defun yas-visit-snippet-file () | 2554 | (defun yas-visit-snippet-file () |
| @@ -2812,17 +2836,17 @@ DEBUG is for debugging the YASnippet engine itself." | |||
| 2812 | :name (nth 2 parsed) | 2836 | :name (nth 2 parsed) |
| 2813 | :expand-env (nth 5 parsed))))) | 2837 | :expand-env (nth 5 parsed))))) |
| 2814 | (cond (yas--current-template | 2838 | (cond (yas--current-template |
| 2815 | (let ((buffer-name (format "*testing snippet: %s*" (yas--template-name yas--current-template)))) | 2839 | (let ((buffer-name |
| 2840 | (format "*testing snippet: %s*" | ||
| 2841 | (yas--template-name yas--current-template)))) | ||
| 2816 | (kill-buffer (get-buffer-create buffer-name)) | 2842 | (kill-buffer (get-buffer-create buffer-name)) |
| 2817 | (switch-to-buffer (get-buffer-create buffer-name)) | 2843 | (switch-to-buffer (get-buffer-create buffer-name)) |
| 2818 | (setq buffer-undo-list nil) | 2844 | (setq buffer-undo-list nil) |
| 2819 | (condition-case nil (funcall test-mode) (error nil)) | 2845 | (condition-case nil (funcall test-mode) (error nil)) |
| 2820 | (yas-minor-mode 1) | 2846 | (yas-minor-mode 1) |
| 2821 | (setq buffer-read-only nil) | 2847 | (setq buffer-read-only nil) |
| 2822 | (yas-expand-snippet (yas--template-content yas--current-template) | 2848 | (yas-expand-snippet yas--current-template |
| 2823 | (point-min) | 2849 | (point-min) (point-max)) |
| 2824 | (point-max) | ||
| 2825 | (yas--template-expand-env yas--current-template)) | ||
| 2826 | (when (and debug | 2850 | (when (and debug |
| 2827 | (require 'yasnippet-debug nil t)) | 2851 | (require 'yasnippet-debug nil t)) |
| 2828 | (yas-debug-snippets "*YASnippet trace*" 'snippet-navigation) | 2852 | (yas-debug-snippets "*YASnippet trace*" 'snippet-navigation) |
| @@ -3502,10 +3526,7 @@ This renders the snippet as ordinary text." | |||
| 3502 | (dolist (snippet snippets) | 3526 | (dolist (snippet snippets) |
| 3503 | (yas--snippet-map-markers | 3527 | (yas--snippet-map-markers |
| 3504 | (lambda (m) | 3528 | (lambda (m) |
| 3505 | (goto-char m) | 3529 | (prog1 (cons m (yas--snapshot-line-location m)) |
| 3506 | (beginning-of-line) | ||
| 3507 | (prog1 (cons (count-lines (point-min) (point)) | ||
| 3508 | (yas--snapshot-marker-location m)) | ||
| 3509 | (set-marker m nil))) | 3530 | (set-marker m nil))) |
| 3510 | snippet) | 3531 | snippet) |
| 3511 | (let ((ctrl-ov (yas--snapshot-overlay-line-location | 3532 | (let ((ctrl-ov (yas--snapshot-overlay-line-location |
| @@ -3513,23 +3534,27 @@ This renders the snippet as ordinary text." | |||
| 3513 | (push (list ctrl-ov dst-base-line snippet) to-move) | 3534 | (push (list ctrl-ov dst-base-line snippet) to-move) |
| 3514 | (delete-overlay (car ctrl-ov)))) | 3535 | (delete-overlay (car ctrl-ov)))) |
| 3515 | (with-current-buffer buf | 3536 | (with-current-buffer buf |
| 3516 | (setq yas--snippets-to-move (nconc to-move yas--snippets-to-move)))))) | 3537 | (cl-callf2 nconc to-move yas--snippets-to-move))))) |
| 3517 | 3538 | ||
| 3518 | (defun yas--on-buffer-kill () | 3539 | (defun yas--on-buffer-kill () |
| 3519 | ;; Org mode uses temp buffers for fontification and "native tab", | 3540 | ;; Org mode uses temp buffers for fontification and "native tab", |
| 3520 | ;; move all the snippets to the original org-mode buffer when it's | 3541 | ;; move all the snippets to the original org-mode buffer when it's |
| 3521 | ;; killed. | 3542 | ;; killed. |
| 3522 | (let ((org-marker nil)) | 3543 | (let ((org-marker nil) |
| 3544 | (org-buffer nil)) | ||
| 3523 | (when (and yas-minor-mode | 3545 | (when (and yas-minor-mode |
| 3524 | (or (bound-and-true-p org-edit-src-from-org-mode) | 3546 | (or (bound-and-true-p org-edit-src-from-org-mode) |
| 3525 | (bound-and-true-p org-src--from-org-mode)) | 3547 | (bound-and-true-p org-src--from-org-mode)) |
| 3526 | (markerp | 3548 | (markerp |
| 3527 | (setq org-marker | 3549 | (setq org-marker |
| 3528 | (or (bound-and-true-p org-edit-src-beg-marker) | 3550 | (or (bound-and-true-p org-edit-src-beg-marker) |
| 3529 | (bound-and-true-p org-src--beg-marker))))) | 3551 | (bound-and-true-p org-src--beg-marker)))) |
| 3552 | ;; If the org source buffer is killed before the temp | ||
| 3553 | ;; fontification one, org-marker might point nowhere. | ||
| 3554 | (setq org-buffer (marker-buffer org-marker))) | ||
| 3530 | (yas--prepare-snippets-for-move | 3555 | (yas--prepare-snippets-for-move |
| 3531 | (point-min) (point-max) | 3556 | (point-min) (point-max) |
| 3532 | (marker-buffer org-marker) org-marker)))) | 3557 | org-buffer org-marker)))) |
| 3533 | 3558 | ||
| 3534 | (add-hook 'kill-buffer-hook #'yas--on-buffer-kill) | 3559 | (add-hook 'kill-buffer-hook #'yas--on-buffer-kill) |
| 3535 | 3560 | ||
| @@ -3539,18 +3564,16 @@ This renders the snippet as ordinary text." | |||
| 3539 | for base-pos = (progn (goto-char (point-min)) | 3564 | for base-pos = (progn (goto-char (point-min)) |
| 3540 | (forward-line base-line) (point)) | 3565 | (forward-line base-line) (point)) |
| 3541 | do (yas--snippet-map-markers | 3566 | do (yas--snippet-map-markers |
| 3542 | (lambda (l-m-r-w) | 3567 | (lambda (saved-location) |
| 3543 | (goto-char base-pos) | 3568 | (let ((m (pop saved-location))) |
| 3544 | (forward-line (nth 0 l-m-r-w)) | 3569 | (set-marker m (yas--goto-saved-line-location |
| 3545 | (save-restriction | 3570 | base-pos saved-location)) |
| 3546 | (narrow-to-region (line-beginning-position) | 3571 | m)) |
| 3547 | (line-end-position)) | ||
| 3548 | (yas--restore-marker-location (cdr l-m-r-w))) | ||
| 3549 | (nth 1 l-m-r-w)) | ||
| 3550 | snippet) | 3572 | snippet) |
| 3551 | (goto-char base-pos) | 3573 | (goto-char base-pos) |
| 3552 | (yas--restore-overlay-location ctrl-ov) | 3574 | (yas--restore-overlay-line-location base-pos ctrl-ov) |
| 3553 | (yas--maybe-move-to-active-field snippet)) | 3575 | (yas--maybe-move-to-active-field snippet) |
| 3576 | (push snippet yas--active-snippets)) | ||
| 3554 | (setq yas--snippets-to-move nil)) | 3577 | (setq yas--snippets-to-move nil)) |
| 3555 | 3578 | ||
| 3556 | (defun yas--safely-call-fun (fun) | 3579 | (defun yas--safely-call-fun (fun) |
| @@ -3755,13 +3778,49 @@ BEG, END and LENGTH like overlay modification hooks." | |||
| 3755 | (= beg (yas--field-start field)) ; Insertion at field start? | 3778 | (= beg (yas--field-start field)) ; Insertion at field start? |
| 3756 | (not (yas--field-modified-p field)))) | 3779 | (not (yas--field-modified-p field)))) |
| 3757 | 3780 | ||
| 3781 | |||
| 3782 | (defun yas--merge-and-drop-dups (list1 list2 cmp key) | ||
| 3783 | ;; `delete-consecutive-dups' + `cl-merge'. | ||
| 3784 | (funcall (if (fboundp 'delete-consecutive-dups) | ||
| 3785 | #'delete-consecutive-dups ; 24.4 | ||
| 3786 | #'delete-dups) | ||
| 3787 | (cl-merge 'list list1 list2 cmp :key key))) | ||
| 3788 | |||
| 3789 | (defvar yas--before-change-modified-snippets nil) | ||
| 3790 | (make-variable-buffer-local 'yas--before-change-modified-snippets) | ||
| 3791 | |||
| 3792 | (defun yas--gather-active-snippets (overlay beg end then-delete) | ||
| 3793 | ;; Add active snippets in BEG..END into an OVERLAY keyed entry of | ||
| 3794 | ;; `yas--before-change-modified-snippets'. Return accumulated list. | ||
| 3795 | ;; If THEN-DELETE is non-nil, delete the entry. | ||
| 3796 | (let ((new (yas-active-snippets beg end)) | ||
| 3797 | (old (assq overlay yas--before-change-modified-snippets))) | ||
| 3798 | (prog1 (cond ((and new old) | ||
| 3799 | (setf (cdr old) | ||
| 3800 | (yas--merge-and-drop-dups | ||
| 3801 | (cdr old) new | ||
| 3802 | ;; Sort like `yas-active-snippets'. | ||
| 3803 | #'>= #'yas--snippet-id))) | ||
| 3804 | (new (unless then-delete | ||
| 3805 | ;; Don't add new entry if we're about to | ||
| 3806 | ;; remove it anyway. | ||
| 3807 | (push (cons overlay new) | ||
| 3808 | yas--before-change-modified-snippets)) | ||
| 3809 | new) | ||
| 3810 | (old (cdr old)) | ||
| 3811 | (t nil)) | ||
| 3812 | (when then-delete | ||
| 3813 | (cl-callf2 delq old yas--before-change-modified-snippets))))) | ||
| 3814 | |||
| 3815 | (defvar yas--todo-snippet-indent nil nil) | ||
| 3816 | (make-variable-buffer-local 'yas--todo-snippet-indent) | ||
| 3817 | |||
| 3758 | (defun yas--on-field-overlay-modification (overlay after? beg end &optional length) | 3818 | (defun yas--on-field-overlay-modification (overlay after? beg end &optional length) |
| 3759 | "Clears the field and updates mirrors, conditionally. | 3819 | "Clears the field and updates mirrors, conditionally. |
| 3760 | 3820 | ||
| 3761 | Only clears the field if it hasn't been modified and point is at | 3821 | Only clears the field if it hasn't been modified and point is at |
| 3762 | field start. This hook does nothing if an undo is in progress." | 3822 | field start. This hook does nothing if an undo is in progress." |
| 3763 | (unless (or (not after?) | 3823 | (unless (or yas--inhibit-overlay-hooks |
| 3764 | yas--inhibit-overlay-hooks | ||
| 3765 | (not (overlayp yas--active-field-overlay)) ; Avoid Emacs bug #21824. | 3824 | (not (overlayp yas--active-field-overlay)) ; Avoid Emacs bug #21824. |
| 3766 | ;; If a single change hits multiple overlays of the same | 3825 | ;; If a single change hits multiple overlays of the same |
| 3767 | ;; snippet, then we delete the snippet the first time, | 3826 | ;; snippet, then we delete the snippet the first time, |
| @@ -3774,28 +3833,52 @@ field start. This hook does nothing if an undo is in progress." | |||
| 3774 | (field (overlay-get overlay 'yas--field)) | 3833 | (field (overlay-get overlay 'yas--field)) |
| 3775 | (snippet (overlay-get yas--active-field-overlay 'yas--snippet))) | 3834 | (snippet (overlay-get yas--active-field-overlay 'yas--snippet))) |
| 3776 | (if (yas--snippet-live-p snippet) | 3835 | (if (yas--snippet-live-p snippet) |
| 3777 | (save-match-data | 3836 | (if after? |
| 3778 | (yas--letenv (yas--snippet-expand-env snippet) | 3837 | (save-match-data |
| 3779 | (when (yas--skip-and-clear-field-p field beg end length) | 3838 | (yas--letenv (yas--snippet-expand-env snippet) |
| 3780 | ;; We delete text starting from the END of insertion. | 3839 | (when (yas--skip-and-clear-field-p field beg end length) |
| 3781 | (yas--skip-and-clear field end)) | 3840 | ;; We delete text starting from the END of insertion. |
| 3782 | (setf (yas--field-modified-p field) t) | 3841 | (yas--skip-and-clear field end)) |
| 3783 | ;; Adjust any pending active fields in case of stacked | 3842 | (setf (yas--field-modified-p field) t) |
| 3784 | ;; expansion. | 3843 | ;; Adjust any pending active fields in case of stacked |
| 3785 | (let ((pfield field) | 3844 | ;; expansion. |
| 3786 | (psnippets (yas-active-snippets beg end))) | 3845 | (let ((pfield field) |
| 3787 | (while (and pfield psnippets) | 3846 | (psnippets (yas--gather-active-snippets |
| 3788 | (let ((psnippet (pop psnippets))) | 3847 | overlay beg end t))) |
| 3789 | (cl-assert (memq pfield (yas--snippet-fields psnippet))) | 3848 | (while (and pfield psnippets) |
| 3790 | (yas--advance-end-maybe pfield (overlay-end overlay)) | 3849 | (let ((psnippet (pop psnippets))) |
| 3791 | (setq pfield (yas--snippet-previous-active-field psnippet))))) | 3850 | (cl-assert (memq pfield (yas--snippet-fields psnippet))) |
| 3792 | (save-excursion | 3851 | (yas--advance-end-maybe pfield (overlay-end overlay)) |
| 3793 | (yas--field-update-display field)) | 3852 | (setq pfield (yas--snippet-previous-active-field psnippet))))) |
| 3794 | (yas--update-mirrors snippet))) | 3853 | ;; Update fields now, but delay auto indentation until |
| 3854 | ;; post-command. We don't want to run indentation on | ||
| 3855 | ;; the intermediate state where field text might be | ||
| 3856 | ;; removed (and hence the field could be deleted along | ||
| 3857 | ;; with leading indentation). | ||
| 3858 | (let ((yas-indent-line nil)) | ||
| 3859 | (save-excursion | ||
| 3860 | (yas--field-update-display field)) | ||
| 3861 | (yas--update-mirrors snippet)) | ||
| 3862 | (unless (or (not (eq yas-indent-line 'auto)) | ||
| 3863 | (memq snippet yas--todo-snippet-indent)) | ||
| 3864 | (push snippet yas--todo-snippet-indent)))) | ||
| 3865 | ;; Remember active snippets to use for after the change. | ||
| 3866 | (yas--gather-active-snippets overlay beg end nil)) | ||
| 3795 | (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!") | 3867 | (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!") |
| 3796 | (delete-overlay overlay))))) | 3868 | (delete-overlay overlay))))) |
| 3797 | 3869 | ||
| 3870 | (defun yas--do-todo-snippet-indent () | ||
| 3871 | ;; Do pending indentation of snippet fields, called from | ||
| 3872 | ;; `yas--post-command-handler'. | ||
| 3873 | (when yas--todo-snippet-indent | ||
| 3874 | (save-excursion | ||
| 3875 | (cl-loop for snippet in yas--todo-snippet-indent | ||
| 3876 | do (yas--indent-mirrors-of-snippet | ||
| 3877 | snippet (yas--snippet-field-mirrors snippet))) | ||
| 3878 | (setq yas--todo-snippet-indent nil)))) | ||
| 3879 | |||
| 3798 | (defun yas--auto-fill () | 3880 | (defun yas--auto-fill () |
| 3881 | ;; Preserve snippet markers during auto-fill. | ||
| 3799 | (let* ((orig-point (point)) | 3882 | (let* ((orig-point (point)) |
| 3800 | (end (progn (forward-paragraph) (point))) | 3883 | (end (progn (forward-paragraph) (point))) |
| 3801 | (beg (progn (backward-paragraph) (point))) | 3884 | (beg (progn (backward-paragraph) (point))) |
| @@ -3805,57 +3888,59 @@ field start. This hook does nothing if an undo is in progress." | |||
| 3805 | (dolist (snippet snippets) | 3888 | (dolist (snippet snippets) |
| 3806 | (dolist (m (yas--collect-snippet-markers snippet)) | 3889 | (dolist (m (yas--collect-snippet-markers snippet)) |
| 3807 | (when (and (<= beg m) (<= m end)) | 3890 | (when (and (<= beg m) (<= m end)) |
| 3808 | (push (yas--snapshot-marker-location m beg end) remarkers))) | 3891 | (push (cons m (yas--snapshot-location m beg end)) remarkers))) |
| 3809 | (push (yas--snapshot-overlay-location | 3892 | (push (yas--snapshot-overlay-location |
| 3810 | (yas--snippet-control-overlay snippet) beg end) | 3893 | (yas--snippet-control-overlay snippet) beg end) |
| 3811 | reoverlays)) | 3894 | reoverlays)) |
| 3812 | (goto-char orig-point) | 3895 | (goto-char orig-point) |
| 3813 | (let ((yas--inhibit-overlay-hooks t)) | 3896 | (let ((yas--inhibit-overlay-hooks t)) |
| 3814 | (if (null yas--original-auto-fill-function) | 3897 | (if yas--original-auto-fill-function |
| 3815 | ;; Try to get more info on #873/919. | 3898 | (funcall yas--original-auto-fill-function) |
| 3816 | (let ((yas--fill-fun-values `((t ,(default-value 'yas--original-auto-fill-function)))) | 3899 | ;; Shouldn't happen, gather more info about it (see #873/919). |
| 3817 | (fill-fun-values `((t ,(default-value 'auto-fill-function)))) | 3900 | (let ((yas--fill-fun-values `((t ,(default-value 'yas--original-auto-fill-function)))) |
| 3818 | ;; Listing 2 buffers with the same value is enough | 3901 | (fill-fun-values `((t ,(default-value 'auto-fill-function)))) |
| 3819 | (print-length 3)) | 3902 | ;; Listing 2 buffers with the same value is enough |
| 3820 | (save-current-buffer | 3903 | (print-length 3)) |
| 3821 | (dolist (buf (let ((bufs (buffer-list))) | 3904 | (save-current-buffer |
| 3822 | ;; List the current buffer first. | 3905 | (dolist (buf (let ((bufs (buffer-list))) |
| 3823 | (setq bufs (cons (current-buffer) | 3906 | ;; List the current buffer first. |
| 3824 | (remq (current-buffer) bufs))))) | 3907 | (setq bufs (cons (current-buffer) |
| 3825 | (set-buffer buf) | 3908 | (remq (current-buffer) bufs))))) |
| 3826 | (let* ((yf-cell (assq yas--original-auto-fill-function | 3909 | (set-buffer buf) |
| 3827 | yas--fill-fun-values)) | 3910 | (let* ((yf-cell (assq yas--original-auto-fill-function |
| 3828 | (af-cell (assq auto-fill-function fill-fun-values))) | 3911 | yas--fill-fun-values)) |
| 3829 | (when (local-variable-p 'yas--original-auto-fill-function) | 3912 | (af-cell (assq auto-fill-function fill-fun-values))) |
| 3830 | (if yf-cell (setcdr yf-cell (cons buf (cdr yf-cell))) | 3913 | (when (local-variable-p 'yas--original-auto-fill-function) |
| 3831 | (push (list yas--original-auto-fill-function buf) yas--fill-fun-values))) | 3914 | (if yf-cell (setcdr yf-cell (cons buf (cdr yf-cell))) |
| 3832 | (when (local-variable-p 'auto-fill-function) | 3915 | (push (list yas--original-auto-fill-function buf) yas--fill-fun-values))) |
| 3833 | (if af-cell (setcdr af-cell (cons buf (cdr af-cell))) | 3916 | (when (local-variable-p 'auto-fill-function) |
| 3834 | (push (list auto-fill-function buf) fill-fun-values)))))) | 3917 | (if af-cell (setcdr af-cell (cons buf (cdr af-cell))) |
| 3835 | (lwarn '(yasnippet auto-fill bug) :error | 3918 | (push (list auto-fill-function buf) fill-fun-values)))))) |
| 3836 | "`yas--original-auto-fill-function' unexpectedly nil in %S! Disabling auto-fill. | 3919 | (lwarn '(yasnippet auto-fill bug) :error |
| 3920 | "`yas--original-auto-fill-function' unexpectedly nil in %S! Disabling auto-fill. | ||
| 3837 | %S | 3921 | %S |
| 3838 | `auto-fill-function': %S\n%s" | 3922 | `auto-fill-function': %S\n%s" |
| 3839 | (current-buffer) yas--fill-fun-values fill-fun-values | 3923 | (current-buffer) yas--fill-fun-values fill-fun-values |
| 3840 | (if (fboundp 'backtrace--print-frame) | 3924 | (if (fboundp 'backtrace--print-frame) |
| 3841 | (with-output-to-string | 3925 | (with-output-to-string |
| 3842 | (mapc (lambda (frame) | 3926 | (mapc (lambda (frame) |
| 3843 | (apply #'backtrace--print-frame frame)) | 3927 | (apply #'backtrace--print-frame frame)) |
| 3844 | yas--watch-auto-fill-backtrace)) | 3928 | yas--watch-auto-fill-backtrace)) |
| 3845 | "")) | 3929 | "")) |
| 3846 | ;; Try to avoid repeated triggering of this bug. | 3930 | ;; Try to avoid repeated triggering of this bug. |
| 3847 | (auto-fill-mode -1) | 3931 | (auto-fill-mode -1) |
| 3848 | ;; Don't pop up more than once in a session (still log though). | 3932 | ;; Don't pop up more than once in a session (still log though). |
| 3849 | (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'. | 3933 | (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'. |
| 3850 | (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))) | 3934 | (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))) |
| 3851 | (funcall yas--original-auto-fill-function))) | ||
| 3852 | (save-excursion | 3935 | (save-excursion |
| 3853 | (setq end (progn (forward-paragraph) (point))) | 3936 | (setq end (progn (forward-paragraph) (point))) |
| 3854 | (setq beg (progn (backward-paragraph) (point)))) | 3937 | (setq beg (progn (backward-paragraph) (point)))) |
| 3855 | (save-excursion | 3938 | (save-excursion |
| 3856 | (save-restriction | 3939 | (save-restriction |
| 3857 | (narrow-to-region beg end) | 3940 | (narrow-to-region beg end) |
| 3858 | (mapc #'yas--restore-marker-location remarkers) | 3941 | (dolist (remarker remarkers) |
| 3942 | (set-marker (car remarker) | ||
| 3943 | (yas--goto-saved-location (cdr remarker)))) | ||
| 3859 | (mapc #'yas--restore-overlay-location reoverlays)) | 3944 | (mapc #'yas--restore-overlay-location reoverlays)) |
| 3860 | (mapc (lambda (snippet) | 3945 | (mapc (lambda (snippet) |
| 3861 | (yas--letenv (yas--snippet-expand-env snippet) | 3946 | (yas--letenv (yas--snippet-expand-env snippet) |
| @@ -3909,6 +3994,7 @@ Move the overlays, or create them if they do not exit." | |||
| 3909 | (defun yas--on-protection-overlay-modification (_overlay after? beg end &optional length) | 3994 | (defun yas--on-protection-overlay-modification (_overlay after? beg end &optional length) |
| 3910 | "Commit the snippet if the protection overlay is being killed." | 3995 | "Commit the snippet if the protection overlay is being killed." |
| 3911 | (unless (or yas--inhibit-overlay-hooks | 3996 | (unless (or yas--inhibit-overlay-hooks |
| 3997 | yas-inhibit-overlay-modification-protection | ||
| 3912 | (not after?) | 3998 | (not after?) |
| 3913 | (= length (- end beg)) ; deletion or insertion | 3999 | (= length (- end beg)) ; deletion or insertion |
| 3914 | (yas--undo-in-progress)) | 4000 | (yas--undo-in-progress)) |
| @@ -4334,35 +4420,54 @@ Meant to be called in a narrowed buffer, does various passes" | |||
| 4334 | ;; current paragraph instead of line. | 4420 | ;; current paragraph instead of line. |
| 4335 | ;; | 4421 | ;; |
| 4336 | ;; 2. Moving snippets from an `org-src' temp buffer into the main org | 4422 | ;; 2. Moving snippets from an `org-src' temp buffer into the main org |
| 4337 | ;; buffer, in this case we need to count the line offsets (because org | 4423 | ;; buffer, in this case we need to count the relative line number |
| 4338 | ;; may add indentation on each line making character positions | 4424 | ;; (because org may add indentation on each line making character |
| 4339 | ;; unreliable). | 4425 | ;; positions unreliable). |
| 4426 | ;; | ||
| 4427 | ;; Data formats: | ||
| 4428 | ;; (LOCATION) = (REGEXP WS-COUNT) | ||
| 4429 | ;; MARKER -> (MARKER . (LOCATION)) | ||
| 4430 | ;; OVERLAY -> (OVERLAY LOCATION-BEG LOCATION-END) | ||
| 4431 | ;; | ||
| 4432 | ;; For `org-src' temp buffer, add a line number to format: | ||
| 4433 | ;; (LINE-LOCATION) = (LINE . (LOCATION)) | ||
| 4434 | ;; MARKER@LINE -> (MARKER . (LINE-LOCATION)) | ||
| 4435 | ;; OVERLAY@LINE -> (OVERLAY LINE-LOCATION-BEG LINE-LOCATION-END) | ||
| 4340 | ;; | 4436 | ;; |
| 4341 | ;; This is all best-effort heuristic stuff, but it should cover 99% of | 4437 | ;; This is all best-effort heuristic stuff, but it should cover 99% of |
| 4342 | ;; use-cases. | 4438 | ;; use-cases. |
| 4343 | 4439 | ||
| 4344 | (defun yas--snapshot-marker-location (marker &optional beg end) | 4440 | (defun yas--snapshot-location (position &optional beg end) |
| 4345 | "Returns info for restoring MARKER's location after indent. | 4441 | "Returns info for restoring POSITIONS's location after indent. |
| 4346 | The returned value is a list of the form (MARKER REGEXP WS-COUNT)." | 4442 | The returned value is a list of the form (REGEXP WS-COUNT). |
| 4443 | POSITION may be either a marker or just a buffer position. The | ||
| 4444 | REGEXP matches text between BEG..END which default to the current | ||
| 4445 | line if omitted." | ||
| 4446 | (goto-char position) | ||
| 4347 | (unless beg (setq beg (line-beginning-position))) | 4447 | (unless beg (setq beg (line-beginning-position))) |
| 4348 | (unless end (setq end (line-end-position))) | 4448 | (unless end (setq end (line-end-position))) |
| 4349 | (let ((before (split-string (buffer-substring-no-properties beg marker) | 4449 | (let ((before (split-string (buffer-substring-no-properties beg position) |
| 4350 | "[[:space:]\n]+" t)) | 4450 | "[[:space:]\n]+" t)) |
| 4351 | (after (split-string (buffer-substring-no-properties marker end) | 4451 | (after (split-string (buffer-substring-no-properties position end) |
| 4352 | "[[:space:]\n]+" t))) | 4452 | "[[:space:]\n]+" t))) |
| 4353 | (list marker | 4453 | (list (concat "[[:space:]\n]*" |
| 4354 | (concat "[[:space:]\n]*" | ||
| 4355 | (mapconcat (lambda (s) | 4454 | (mapconcat (lambda (s) |
| 4356 | (if (eq s marker) "\\(\\)" | 4455 | (if (eq s position) "\\(\\)" |
| 4357 | (regexp-quote s))) | 4456 | (regexp-quote s))) |
| 4358 | (nconc before (list marker) after) | 4457 | (nconc before (list position) after) |
| 4359 | "[[:space:]\n]*")) | 4458 | "[[:space:]\n]*")) |
| 4360 | (progn (goto-char marker) | 4459 | (progn (skip-chars-forward "[:space:]\n" end) |
| 4361 | (skip-chars-forward "[:space:]\n" end) | 4460 | (- (point) position))))) |
| 4362 | (- (point) marker))))) | 4461 | |
| 4462 | (defun yas--snapshot-line-location (position &optional beg end) | ||
| 4463 | "Like `yas--snapshot-location', but return also line number. | ||
| 4464 | Returned format is (LINE REGEXP WS-COUNT)." | ||
| 4465 | (goto-char position) | ||
| 4466 | (cons (count-lines (point-min) (line-beginning-position)) | ||
| 4467 | (yas--snapshot-location position beg end))) | ||
| 4363 | 4468 | ||
| 4364 | (defun yas--snapshot-overlay-location (overlay beg end) | 4469 | (defun yas--snapshot-overlay-location (overlay beg end) |
| 4365 | "Like `yas--snapshot-marker-location' for overlays. | 4470 | "Like `yas--snapshot-location' for overlays. |
| 4366 | The returned format is (OVERLAY (RE WS) (RE WS)). Either of | 4471 | The returned format is (OVERLAY (RE WS) (RE WS)). Either of |
| 4367 | the (RE WS) lists may be nil if the start or end, respectively, | 4472 | the (RE WS) lists may be nil if the start or end, respectively, |
| 4368 | of the overlay is outside the range BEG .. END." | 4473 | of the overlay is outside the range BEG .. END." |
| @@ -4370,67 +4475,59 @@ of the overlay is outside the range BEG .. END." | |||
| 4370 | (oend (overlay-end overlay))) | 4475 | (oend (overlay-end overlay))) |
| 4371 | (list overlay | 4476 | (list overlay |
| 4372 | (when (and (<= beg obeg) (< obeg end)) | 4477 | (when (and (<= beg obeg) (< obeg end)) |
| 4373 | (cdr (yas--snapshot-marker-location obeg beg end))) | 4478 | (yas--snapshot-location obeg beg end)) |
| 4374 | (when (and (<= beg oend) (< oend end)) | 4479 | (when (and (<= beg oend) (< oend end)) |
| 4375 | (cdr (yas--snapshot-marker-location oend beg end)))))) | 4480 | (yas--snapshot-location oend beg end))))) |
| 4376 | 4481 | ||
| 4377 | (defun yas--snapshot-overlay-line-location (overlay) | 4482 | (defun yas--snapshot-overlay-line-location (overlay) |
| 4378 | "Return info for restoring OVERLAY's line based location. | 4483 | "Return info for restoring OVERLAY's line based location. |
| 4379 | The returned format is (OVERLAY (LINE RE WS) (LINE RE WS))." | 4484 | The returned format is (OVERLAY (LINE RE WS) (LINE RE WS))." |
| 4380 | (let ((loc-beg (progn (goto-char (overlay-start overlay)) | 4485 | (list overlay |
| 4381 | (yas--snapshot-marker-location (point)))) | 4486 | (yas--snapshot-line-location (overlay-start overlay)) |
| 4382 | (loc-end (progn (goto-char (overlay-end overlay)) | 4487 | (yas--snapshot-line-location (overlay-end overlay)))) |
| 4383 | (yas--snapshot-marker-location (point))))) | ||
| 4384 | (setcar loc-beg (count-lines (point-min) (progn (goto-char (car loc-beg)) | ||
| 4385 | (line-beginning-position)))) | ||
| 4386 | (setcar loc-end (count-lines (point-min) (progn (goto-char (car loc-end)) | ||
| 4387 | (line-beginning-position)))) | ||
| 4388 | (list overlay loc-beg loc-end))) | ||
| 4389 | |||
| 4390 | (defun yas--goto-saved-location (regexp ws-count) | ||
| 4391 | "Move point to location saved by `yas--snapshot-marker-location'. | ||
| 4392 | Buffer must be narrowed to BEG..END used to create the snapshot info." | ||
| 4393 | (goto-char (point-min)) | ||
| 4394 | (if (not (looking-at regexp)) | ||
| 4395 | (lwarn '(yasnippet re-marker) :warning | ||
| 4396 | "Couldn't find: %S" regexp) | ||
| 4397 | (goto-char (match-beginning 1)) | ||
| 4398 | (skip-chars-forward "[:space:]\n") | ||
| 4399 | (skip-chars-backward "[:space:]\n" (- (point) ws-count)))) | ||
| 4400 | 4488 | ||
| 4401 | (defun yas--restore-marker-location (re-marker) | 4489 | (defun yas--goto-saved-location (re-count) |
| 4402 | "Restores marker based on info from `yas--snapshot-marker-location'. | 4490 | "Move to and return point saved by `yas--snapshot-location'. |
| 4403 | Buffer must be narrowed to BEG..END used to create the snapshot info." | 4491 | Buffer must be narrowed to BEG..END used to create the snapshot info." |
| 4404 | (apply #'yas--goto-saved-location (cdr re-marker)) | 4492 | (let ((regexp (pop re-count)) |
| 4405 | (set-marker (car re-marker) (point))) | 4493 | (ws-count (pop re-count))) |
| 4494 | (goto-char (point-min)) | ||
| 4495 | (if (not (looking-at regexp)) | ||
| 4496 | (lwarn '(yasnippet re-marker) :warning | ||
| 4497 | "Couldn't find: %S" regexp) | ||
| 4498 | (goto-char (match-beginning 1)) | ||
| 4499 | (skip-chars-forward "[:space:]\n") | ||
| 4500 | (skip-chars-backward "[:space:]\n" (- (point) ws-count))) | ||
| 4501 | (point))) | ||
| 4406 | 4502 | ||
| 4407 | (defun yas--restore-overlay-location (ov-locations) | 4503 | (defun yas--restore-overlay-location (ov-locations) |
| 4408 | "Restores marker based on info from `yas--snapshot-marker-location'. | 4504 | "Restores marker based on info from `yas--snapshot-overlay-location'. |
| 4409 | Buffer must be narrowed to BEG..END used to create the snapshot info." | 4505 | Buffer must be narrowed to BEG..END used to create the snapshot info." |
| 4410 | (cl-destructuring-bind (overlay loc-beg loc-end) ov-locations | 4506 | (cl-destructuring-bind (overlay loc-beg loc-end) ov-locations |
| 4411 | (move-overlay overlay | 4507 | (move-overlay overlay |
| 4412 | (if (not loc-beg) (overlay-start overlay) | 4508 | (if (not loc-beg) (overlay-start overlay) |
| 4413 | (apply #'yas--goto-saved-location loc-beg) | 4509 | (yas--goto-saved-location loc-beg)) |
| 4414 | (point)) | ||
| 4415 | (if (not loc-end) (overlay-end overlay) | 4510 | (if (not loc-end) (overlay-end overlay) |
| 4416 | (apply #'yas--goto-saved-location loc-end) | 4511 | (yas--goto-saved-location loc-end))))) |
| 4417 | (point))))) | ||
| 4418 | 4512 | ||
| 4419 | 4513 | (defun yas--goto-saved-line-location (base-pos l-re-count) | |
| 4420 | (defun yas--restore-overlay-line-location (ov-locations) | 4514 | "Move to and return point saved by `yas--snapshot-line-location'. |
| 4421 | "Restores overlay based on info from `yas--snapshot-overlay-line-location'." | 4515 | Additionally requires BASE-POS to tell where the line numbers are |
| 4516 | relative to." | ||
| 4517 | (goto-char base-pos) | ||
| 4518 | (forward-line (pop l-re-count)) | ||
| 4422 | (save-restriction | 4519 | (save-restriction |
| 4423 | (move-overlay (car ov-locations) | 4520 | (narrow-to-region (line-beginning-position) |
| 4424 | (save-excursion | 4521 | (line-end-position)) |
| 4425 | (forward-line (car (nth 1 ov-locations))) | 4522 | (yas--goto-saved-location l-re-count))) |
| 4426 | (narrow-to-region (line-beginning-position) (line-end-position)) | 4523 | |
| 4427 | (apply #'yas--goto-saved-location (cdr (nth 1 ov-locations))) | 4524 | (defun yas--restore-overlay-line-location (base-pos ov-locations) |
| 4428 | (point)) | 4525 | "Restores marker based on info from `yas--snapshot-overlay-line-location'." |
| 4429 | (save-excursion | 4526 | (cl-destructuring-bind (overlay beg-l-r-w end-l-r-w) |
| 4430 | (forward-line (car (nth 2 ov-locations))) | 4527 | ov-locations |
| 4431 | (narrow-to-region (line-beginning-position) (line-end-position)) | 4528 | (move-overlay overlay |
| 4432 | (apply #'yas--goto-saved-location (cdr (nth 2 ov-locations))) | 4529 | (yas--goto-saved-line-location base-pos beg-l-r-w) |
| 4433 | (point))))) | 4530 | (yas--goto-saved-line-location base-pos end-l-r-w)))) |
| 4434 | 4531 | ||
| 4435 | (defun yas--indent-region (from to snippet) | 4532 | (defun yas--indent-region (from to snippet) |
| 4436 | "Indent the lines between FROM and TO with `indent-according-to-mode'. | 4533 | "Indent the lines between FROM and TO with `indent-according-to-mode'. |
| @@ -4449,14 +4546,16 @@ The SNIPPET's markers are preserved." | |||
| 4449 | (let ((remarkers nil)) | 4546 | (let ((remarkers nil)) |
| 4450 | (dolist (m snippet-markers) | 4547 | (dolist (m snippet-markers) |
| 4451 | (when (and (<= bol m) (<= m eol)) | 4548 | (when (and (<= bol m) (<= m eol)) |
| 4452 | (push (yas--snapshot-marker-location m bol eol) | 4549 | (push (cons m (yas--snapshot-location m bol eol)) |
| 4453 | remarkers))) | 4550 | remarkers))) |
| 4454 | (unwind-protect | 4551 | (unwind-protect |
| 4455 | (progn (back-to-indentation) | 4552 | (progn (back-to-indentation) |
| 4456 | (indent-according-to-mode)) | 4553 | (indent-according-to-mode)) |
| 4457 | (save-restriction | 4554 | (save-restriction |
| 4458 | (narrow-to-region bol (line-end-position)) | 4555 | (narrow-to-region bol (line-end-position)) |
| 4459 | (mapc #'yas--restore-marker-location remarkers)))) | 4556 | (dolist (remarker remarkers) |
| 4557 | (set-marker (car remarker) | ||
| 4558 | (yas--goto-saved-location (cdr remarker))))))) | ||
| 4460 | while (and (zerop (forward-line 1)) | 4559 | while (and (zerop (forward-line 1)) |
| 4461 | (< (point) to))))))) | 4560 | (< (point) to))))))) |
| 4462 | 4561 | ||
| @@ -4754,46 +4853,58 @@ When multiple expressions are found, only the last one counts." | |||
| 4754 | (parent 1) | 4853 | (parent 1) |
| 4755 | (t 0)))))) | 4854 | (t 0)))))) |
| 4756 | 4855 | ||
| 4856 | (defun yas--snippet-field-mirrors (snippet) | ||
| 4857 | ;; Make a list of (FIELD . MIRROR). | ||
| 4858 | (cl-sort | ||
| 4859 | (cl-mapcan (lambda (field) | ||
| 4860 | (mapcar (lambda (mirror) | ||
| 4861 | (cons field mirror)) | ||
| 4862 | (yas--field-mirrors field))) | ||
| 4863 | (yas--snippet-fields snippet)) | ||
| 4864 | ;; Then sort this list so that entries with mirrors with | ||
| 4865 | ;; parent fields appear before. This was important for | ||
| 4866 | ;; fixing #290, and also handles the case where a mirror in | ||
| 4867 | ;; a field causes another mirror to need reupdating. | ||
| 4868 | #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm))))) | ||
| 4869 | |||
| 4870 | (defun yas--indent-mirrors-of-snippet (snippet &optional f-ms) | ||
| 4871 | ;; Indent mirrors of SNIPPET. F-MS is the return value of | ||
| 4872 | ;; (yas--snippet-field-mirrors SNIPPET). | ||
| 4873 | (when (eq yas-indent-line 'auto) | ||
| 4874 | (let ((yas--inhibit-overlay-hooks t)) | ||
| 4875 | (cl-loop for (beg . end) in | ||
| 4876 | (cl-sort (mapcar (lambda (f-m) | ||
| 4877 | (let ((mirror (cdr f-m))) | ||
| 4878 | (cons (yas--mirror-start mirror) | ||
| 4879 | (yas--mirror-end mirror)))) | ||
| 4880 | (or f-ms | ||
| 4881 | (yas--snippet-field-mirrors snippet))) | ||
| 4882 | #'< :key #'car) | ||
| 4883 | do (yas--indent-region beg end snippet))))) | ||
| 4884 | |||
| 4757 | (defun yas--update-mirrors (snippet) | 4885 | (defun yas--update-mirrors (snippet) |
| 4758 | "Update all the mirrors of SNIPPET." | 4886 | "Update all the mirrors of SNIPPET." |
| 4759 | (yas--save-restriction-and-widen | 4887 | (yas--save-restriction-and-widen |
| 4760 | (save-excursion | 4888 | (save-excursion |
| 4761 | (cl-loop | 4889 | (let ((f-ms (yas--snippet-field-mirrors snippet))) |
| 4762 | for (field . mirror) | 4890 | (cl-loop |
| 4763 | in (cl-sort | 4891 | for (field . mirror) in f-ms |
| 4764 | ;; Make a list of (FIELD . MIRROR). | 4892 | ;; Before updating a mirror with a parent-field, maybe advance |
| 4765 | (cl-mapcan (lambda (field) | 4893 | ;; its start (#290). |
| 4766 | (mapcar (lambda (mirror) | 4894 | do (let ((parent-field (yas--mirror-parent-field mirror))) |
| 4767 | (cons field mirror)) | 4895 | (when parent-field |
| 4768 | (yas--field-mirrors field))) | 4896 | (yas--advance-start-maybe mirror (yas--fom-start parent-field)))) |
| 4769 | (yas--snippet-fields snippet)) | 4897 | ;; Update this mirror. |
| 4770 | ;; Then sort this list so that entries with mirrors with | 4898 | do (yas--mirror-update-display mirror field) |
| 4771 | ;; parent fields appear before. This was important for | 4899 | ;; `yas--place-overlays' is needed since the active field and |
| 4772 | ;; fixing #290, and also handles the case where a mirror in | 4900 | ;; protected overlays might have been changed because of insertions |
| 4773 | ;; a field causes another mirror to need reupdating. | 4901 | ;; in `yas--mirror-update-display'. |
| 4774 | #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm)))) | 4902 | do (let ((active-field (yas--snippet-active-field snippet))) |
| 4775 | ;; Before updating a mirror with a parent-field, maybe advance | 4903 | (when active-field (yas--place-overlays snippet active-field)))) |
| 4776 | ;; its start (#290). | 4904 | ;; Delay indenting until we're done all mirrors. We must do |
| 4777 | do (let ((parent-field (yas--mirror-parent-field mirror))) | 4905 | ;; this to avoid losing whitespace between fields that are |
| 4778 | (when parent-field | 4906 | ;; still empty (i.e., they will be non-empty after updating). |
| 4779 | (yas--advance-start-maybe mirror (yas--fom-start parent-field)))) | 4907 | (yas--indent-mirrors-of-snippet snippet f-ms))))) |
| 4780 | ;; Update this mirror. | ||
| 4781 | do (yas--mirror-update-display mirror field) | ||
| 4782 | ;; Delay indenting until we're done all mirrors. We must do | ||
| 4783 | ;; this to avoid losing whitespace between fields that are | ||
| 4784 | ;; still empty (i.e., they will be non-empty after updating). | ||
| 4785 | when (eq yas-indent-line 'auto) | ||
| 4786 | collect (cons (yas--mirror-start mirror) (yas--mirror-end mirror)) | ||
| 4787 | into indent-regions | ||
| 4788 | ;; `yas--place-overlays' is needed since the active field and | ||
| 4789 | ;; protected overlays might have been changed because of insertions | ||
| 4790 | ;; in `yas--mirror-update-display'. | ||
| 4791 | do (let ((active-field (yas--snippet-active-field snippet))) | ||
| 4792 | (when active-field (yas--place-overlays snippet active-field))) | ||
| 4793 | finally do | ||
| 4794 | (let ((yas--inhibit-overlay-hooks t)) | ||
| 4795 | (cl-loop for (beg . end) in (cl-sort indent-regions #'< :key #'car) | ||
| 4796 | do (yas--indent-region beg end snippet))))))) | ||
| 4797 | 4908 | ||
| 4798 | (defun yas--mirror-update-display (mirror field) | 4909 | (defun yas--mirror-update-display (mirror field) |
| 4799 | "Update MIRROR according to FIELD (and mirror transform)." | 4910 | "Update MIRROR according to FIELD (and mirror transform)." |
| @@ -4851,6 +4962,7 @@ When multiple expressions are found, only the last one counts." | |||
| 4851 | ;; Don't pop up more than once in a session (still log though). | 4962 | ;; Don't pop up more than once in a session (still log though). |
| 4852 | (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'. | 4963 | (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'. |
| 4853 | (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))) | 4964 | (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))) |
| 4965 | (yas--do-todo-snippet-indent) | ||
| 4854 | (condition-case err | 4966 | (condition-case err |
| 4855 | (progn (yas--finish-moving-snippets) | 4967 | (progn (yas--finish-moving-snippets) |
| 4856 | (cond ((eq 'undo this-command) | 4968 | (cond ((eq 'undo this-command) |
