summaryrefslogtreecommitdiff
path: root/.emacs.d
diff options
context:
space:
mode:
Diffstat (limited to '.emacs.d')
-rw-r--r--.emacs.d/lisp/php-face.el142
-rw-r--r--.emacs.d/lisp/php-mode.el462
-rw-r--r--.emacs.d/lisp/php-project.el2
-rw-r--r--.emacs.d/lisp/php.el207
-rw-r--r--.emacs.d/lisp/yasnippet.el532
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
233VISIBILITY must be a string that names the visibility for a PHP
234method, e.g. 'public'. The parameter VISIBILITY can itself also
235be a regular expression.
236
237The regular expression this function returns will check for other
238keywords that can appear in method signatures, e.g. 'final' and
239'static'. The regular expression will have one capture group
240which 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
255can 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
299enabled." 215enabled."
300 :type 'boolean) 216 :type 'boolean)
301 217
302(defcustom php-site-url "https://secure.php.net/"
303 "Default PHP.net site URL.
304
305The URL to use open PHP manual and search word.
306You 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.
312You 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',
684but only if the setting is enabled" 585but 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.
789Implements PHP version of `beginning-of-defun-function'." 690Implements 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))
1765This is an alternative function of `flymake-php-init'.
1766Look 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
48The 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.
53You 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
87These are different from \"constants\" in strict terms.
88see 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.
93it 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
107VISIBILITY must be a string that names the visibility for a PHP
108method, e.g. 'public'. The parameter VISIBILITY can itself also
109be a regular expression.
110
111The regular expression this function returns will check for other
112keywords that can appear in method signatures, e.g. 'final' and
113'static'. The regular expression will have one capture group
114which 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
129can 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
182This is an alternative function of `flymake-php-init'.
183Look 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
414unmodified snippet field.") 414unmodified 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) 418The 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.
560This is useful to control whether snippet navigation bindings
561override 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.
552This is useful to control whether snippet navigation bindings 566This is useful to control whether snippet navigation bindings
553override bindings from other packages (e.g., `company-mode')." 567override `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.
572This protection is intended to prevent yasnippet from ending up
573in an inconsistent state. However, some packages (e.g., the
574company completion package) may trigger this protection when it
575is not needed. In that case, setting this variable to non-nil
576can 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.
925Functions are called with no argument, and should return non-nil to prevent 952Functions 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.
2374If there are expandable snippets, return CMD (this is useful for
2375conditional keybindings) or the list of expandable snippet
2376template 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."
2369Prompt the user if TEMPLATES has more than one element, else 2398Prompt the user if TEMPLATES has more than one element, else
2370expand immediately. Common gateway for 2399expand 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
3761Only clears the field if it hasn't been modified and point is at 3821Only clears the field if it hasn't been modified and point is at
3762field start. This hook does nothing if an undo is in progress." 3822field 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.
4346The returned value is a list of the form (MARKER REGEXP WS-COUNT)." 4442The returned value is a list of the form (REGEXP WS-COUNT).
4443POSITION may be either a marker or just a buffer position. The
4444REGEXP matches text between BEG..END which default to the current
4445line 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.
4464Returned 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.
4366The returned format is (OVERLAY (RE WS) (RE WS)). Either of 4471The returned format is (OVERLAY (RE WS) (RE WS)). Either of
4367the (RE WS) lists may be nil if the start or end, respectively, 4472the (RE WS) lists may be nil if the start or end, respectively,
4368of the overlay is outside the range BEG .. END." 4473of 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.
4379The returned format is (OVERLAY (LINE RE WS) (LINE RE WS))." 4484The 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'.
4392Buffer 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'.
4403Buffer must be narrowed to BEG..END used to create the snapshot info." 4491Buffer 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'.
4409Buffer must be narrowed to BEG..END used to create the snapshot info." 4505Buffer 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'." 4515Additionally requires BASE-POS to tell where the line numbers are
4516relative 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)