summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.emacs7
-rw-r--r--.emacs.d/lisp/php-mode.el225
-rw-r--r--.emacs.d/lisp/yaml-mode.el82
-rw-r--r--.emacs.d/lisp/yasnippet.el479
4 files changed, 479 insertions, 314 deletions
diff --git a/.emacs b/.emacs
index c1824cd..fe066af 100644
--- a/.emacs
+++ b/.emacs
@@ -1,6 +1,13 @@
1;; Set up the keyboard so the delete key on both the regular keyboard 1;; Set up the keyboard so the delete key on both the regular keyboard
2;; and the keypad delete the character under the cursor and to the right 2;; and the keypad delete the character under the cursor and to the right
3;; under X, instead of the default, backspace behavior. 3;; under X, instead of the default, backspace behavior.
4
5;; Added by Package.el. This must come before configurations of
6;; installed packages. Don't delete this line. If you don't want it,
7;; just comment it out by adding a semicolon to the start of the line.
8;; You may delete these explanatory comments.
9;;(package-initialize)
10
4(global-set-key [delete] 'delete-char) 11(global-set-key [delete] 'delete-char)
5(global-set-key [kp-delete] 'delete-char) 12(global-set-key [kp-delete] 'delete-char)
6 13
diff --git a/.emacs.d/lisp/php-mode.el b/.emacs.d/lisp/php-mode.el
index 5cbc0d1..d568d90 100644
--- a/.emacs.d/lisp/php-mode.el
+++ b/.emacs.d/lisp/php-mode.el
@@ -5,18 +5,19 @@
5;; 2011, 2012, 2013, 2014, 2015, 2016, 2017 Eric James Michael Ritz 5;; 2011, 2012, 2013, 2014, 2015, 2016, 2017 Eric James Michael Ritz
6 6
7;; Author: Eric James Michael Ritz 7;; Author: Eric James Michael Ritz
8;; Maintainer: USAMI Kenta <tadsan@zonu.me>
8;; URL: https://github.com/ejmr/php-mode 9;; URL: https://github.com/ejmr/php-mode
9;; Version: 1.18.3 10;; Keywords: languages php
11;; Version: 1.18.4
10;; Package-Requires: ((emacs "24") (cl-lib "0.5")) 12;; Package-Requires: ((emacs "24") (cl-lib "0.5"))
13;; License: GPL-3.0-or-later
11 14
12(defconst php-mode-version-number "1.18.3" 15(defconst php-mode-version-number "1.18.4"
13 "PHP Mode version number.") 16 "PHP Mode version number.")
14 17
15(defconst php-mode-modified "2017-06-22" 18(defconst php-mode-modified "2018-01-30"
16 "PHP Mode build date.") 19 "PHP Mode build date.")
17 20
18;;; License
19
20;; This file is free software; you can redistribute it and/or 21;; This file is free software; you can redistribute it and/or
21;; modify it under the terms of the GNU General Public License 22;; modify it under the terms of the GNU General Public License
22;; as published by the Free Software Foundation; either version 3 23;; as published by the Free Software Foundation; either version 3
@@ -32,14 +33,24 @@
32;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 33;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33;; 02110-1301, USA. 34;; 02110-1301, USA.
34 35
35;;; Usage 36;;; Commentary:
36 37
37;; Put this file in your Emacs lisp path (eg. site-lisp) and add to 38;; PHP Mode is a major mode for editing PHP source code. It's an
39;; extension of C mode; thus it inherits all C mode's navigation
40;; functionality. But it colors according to the PHP grammar and
41;; indents according to the PEAR coding guidelines. It also includes
42;; a couple handy IDE-type features such as documentation search and a
43;; source and class browser.
44
45;; ## Usage
46
47;; Put this file in your Emacs Lisp path (eg. site-lisp) and add to
38;; your .emacs file: 48;; your .emacs file:
39;; 49
40;; (require 'php-mode) 50;; (require 'php-mode)
41 51
42;; To use abbrev-mode, add lines like this: 52;; To use abbrev-mode, add lines like this:
53
43;; (add-hook 'php-mode-hook 54;; (add-hook 'php-mode-hook
44;; '(lambda () (define-abbrev php-mode-abbrev-table "ex" "extends"))) 55;; '(lambda () (define-abbrev php-mode-abbrev-table "ex" "extends")))
45 56
@@ -47,19 +58,10 @@
47 58
48;; Many options available under Help:Customize 59;; Many options available under Help:Customize
49;; Options specific to php-mode are in 60;; Options specific to php-mode are in
50;; Programming/Languages/Php 61;; Programming/Languages/PHP
51;; Since it inherits much functionality from c-mode, look there too 62;; Since it inherits much functionality from c-mode, look there too
52;; Programming/Languages/C 63;; Programming/Languages/C
53 64
54;;; Commentary:
55
56;; PHP Mode is a major mode for editing PHP source code. It's an
57;; extension of C mode; thus it inherits all C mode's navigation
58;; functionality. But it colors according to the PHP grammar and
59;; indents according to the PEAR coding guidelines. It also includes
60;; a couple handy IDE-type features such as documentation search and a
61;; source and class browser.
62
63;;; Code: 65;;; Code:
64 66
65(require 'cc-mode) 67(require 'cc-mode)
@@ -79,8 +81,10 @@
79(require 'flymake) 81(require 'flymake)
80(require 'etags) 82(require 'etags)
81(require 'speedbar) 83(require 'speedbar)
84(require 'imenu)
82 85
83(require 'cl-lib) 86(require 'cl-lib)
87(require 'mode-local)
84 88
85(eval-when-compile 89(eval-when-compile
86 (require 'regexp-opt) 90 (require 'regexp-opt)
@@ -114,7 +118,7 @@
114;; Local variables 118;; Local variables
115;;;###autoload 119;;;###autoload
116(defgroup php nil 120(defgroup php nil
117 "Major mode `php-mode' for editing PHP code." 121 "Major mode for editing PHP code."
118 :tag "PHP" 122 :tag "PHP"
119 :prefix "php-" 123 :prefix "php-"
120 :group 'languages 124 :group 'languages
@@ -171,7 +175,7 @@ Turning this on will open it whenever `php-mode' is loaded."
171 "\\)\\>[^_]?")) 175 "\\)\\>[^_]?"))
172 176
173(defun php-mode-extra-constants-set(sym value) 177(defun php-mode-extra-constants-set(sym value)
174 "Apply the list of extra constant keywords VALUE. 178 "Apply the list of extra constant keywords `VALUE'.
175 179
176This function is called when the custom variable php-extra-constants 180This function is called when the custom variable php-extra-constants
177is updated. The web-mode-extra-constants list is appended to the list 181is updated. The web-mode-extra-constants list is appended to the list
@@ -187,7 +191,7 @@ of constants when set."
187 (set sym value)) 191 (set sym value))
188 192
189(defcustom php-lineup-cascaded-calls nil 193(defcustom php-lineup-cascaded-calls nil
190 "Indent chained method calls to the previous line" 194 "Indent chained method calls to the previous line."
191 :type 'boolean) 195 :type 'boolean)
192 196
193;;;###autoload 197;;;###autoload
@@ -219,7 +223,7 @@ which will be the name of the method."
219 "\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(")) 223 "\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*("))
220 224
221(defun php-create-regexp-for-classlike (type) 225(defun php-create-regexp-for-classlike (type)
222 "Accepts a `type' of a 'classlike' object as a string, such as 226 "Accepts a `TYPE' of a 'classlike' object as a string, such as
223'class' or 'interface', and returns a regexp as a string which 227'class' or 'interface', and returns a regexp as a string which
224can be used to match against definitions for that classlike." 228can be used to match against definitions for that classlike."
225 (concat 229 (concat
@@ -255,15 +259,25 @@ can be used to match against definitions for that classlike."
255 "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*function\\s-*(" 1) 259 "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*function\\s-*(" 1)
256 ("Named Functions" 260 ("Named Functions"
257 "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1)) 261 "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1))
258 "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.") 262 "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.")
259 263
260(defcustom php-site-url "http://php.net/" 264(defcustom php-do-not-use-semantic-imenu t
265 "Customize `imenu-create-index-function' for `php-mode'.
266
267If using `semantic-mode' `imenu-create-index-function' will be
268set to `semantic-create-imenu-index' due to `c-mode' being its
269parent. Set this variable to t if you want to use
270`imenu-default-create-index-function' even with `semantic-mode'
271enabled."
272 :type 'boolean)
273
274(defcustom php-site-url "https://secure.php.net/"
261 "Default PHP.net site URL. 275 "Default PHP.net site URL.
262 276
263The URL to use open PHP manual and search word. 277The URL to use open PHP manual and search word.
264You can find a mirror site closer to you." 278You can find a mirror site closer to you."
265 :type 'string 279 :type 'string
266 :link '(url-link :tag "List of Mirror Sites" "http://php.net/mirrors.php")) 280 :link '(url-link :tag "List of Mirror Sites" "https://secure.php.net/mirrors.php"))
267 281
268(defcustom php-manual-url 'en 282(defcustom php-manual-url 'en
269 "URL at which to find PHP manual. 283 "URL at which to find PHP manual.
@@ -335,7 +349,7 @@ Turning this on will force PEAR rules on all PHP files."
335mumamo-mode turned on. Detects if there are any HTML tags in the 349mumamo-mode turned on. Detects if there are any HTML tags in the
336buffer before warning, but this is is not very smart; e.g. if you 350buffer before warning, but this is is not very smart; e.g. if you
337have any tags inside a PHP string, it will be fooled." 351have any tags inside a PHP string, it will be fooled."
338 :type '(choice (const :tag "Warg" t) (const "Don't warn" nil))) 352 :type '(choice (const :tag "Warn" t) (const "Don't warn" nil)))
339 353
340(defcustom php-mode-coding-style 'pear 354(defcustom php-mode-coding-style 'pear
341 "Select default coding style to use with php-mode. 355 "Select default coding style to use with php-mode.
@@ -373,6 +387,31 @@ This variable can take one of the following symbol values:
373 (message "PHP Mode %s of %s" 387 (message "PHP Mode %s of %s"
374 php-mode-version-number php-mode-modified)) 388 php-mode-version-number php-mode-modified))
375 389
390(defvar php-available-project-root-files
391 '((projectile ".projectile")
392 (composer "composer.json" "composer.lock")
393 (git ".git")
394 (mercurial ".hg")
395 (subversion ".svn")
396 ;; NOTICE: This method does not detect the top level of .editorconfig
397 ;; However, we can integrate it by adding the editorconfig.el's API.
398 ;;(editorconfig . ".editorconfig")
399 ))
400
401;;;###autoload
402(progn
403 (defvar php-project-root 'auto
404 "Method of searching for the top level directory.
405
406`auto' (default)
407 Try to search file in order of `php-available-project-root-files'.
408
409SYMBOL
410 Key of `php-available-project-root-files'.")
411 (make-variable-buffer-local 'php-project-root)
412 (put 'php-project-root 'safe-local-variable
413 #'(lambda (v) (assq v php-available-project-root-files))))
414
376(defvar php-mode-map 415(defvar php-mode-map
377 (let ((map (make-sparse-keymap))) 416 (let ((map (make-sparse-keymap)))
378 ;; (define-key map [menu-bar php] 417 ;; (define-key map [menu-bar php]
@@ -427,7 +466,7 @@ This variable can take one of the following symbol values:
427 ;; choice. 466 ;; choice.
428 (define-key map [tab] 'indent-for-tab-command) 467 (define-key map [tab] 'indent-for-tab-command)
429 map) 468 map)
430 "Keymap for `php-mode'") 469 "Keymap for `php-mode'.")
431 470
432(c-lang-defconst c-mode-menu 471(c-lang-defconst c-mode-menu
433 php (append '(["Complete function name" php-complete-function t] 472 php (append '(["Complete function name" php-complete-function t]
@@ -442,6 +481,16 @@ This variable can take one of the following symbol values:
442(c-lang-defconst c-vsemi-status-unknown-p-fn 481(c-lang-defconst c-vsemi-status-unknown-p-fn
443 php 'php-c-vsemi-status-unknown-p) 482 php 'php-c-vsemi-status-unknown-p)
444 483
484(c-lang-defconst c-get-state-before-change-functions
485 php nil)
486
487(c-lang-defconst c-before-font-lock-functions
488 php (let (functions)
489 (when (fboundp #'c-change-expand-fl-region)
490 (cl-pushnew 'c-change-expand-fl-region functions))
491 (when (fboundp #'c-depropertize-new-text)
492 (cl-pushnew 'c-depropertize-new-text functions))))
493
445;; Make php-mode recognize opening tags as preprocessor macro's. 494;; Make php-mode recognize opening tags as preprocessor macro's.
446;; 495;;
447;; This is a workaround, the tags must be recognized as something 496;; This is a workaround, the tags must be recognized as something
@@ -653,8 +702,7 @@ but only if the setting is enabled"
653 (tab-width . 4))) 702 (tab-width . 4)))
654 703
655(defun php-enable-pear-coding-style () 704(defun php-enable-pear-coding-style ()
656 "Sets up php-mode to use the coding styles preferred for PEAR 705 "Set up php-mode to use the coding styles preferred for PEAR code and modules."
657code and modules."
658 (interactive) 706 (interactive)
659 (php-set-style "pear")) 707 (php-set-style "pear"))
660 708
@@ -668,8 +716,7 @@ code and modules."
668 (php-style-delete-trailing-whitespace . t))) 716 (php-style-delete-trailing-whitespace . t)))
669 717
670(defun php-enable-drupal-coding-style () 718(defun php-enable-drupal-coding-style ()
671 "Makes php-mode use coding styles that are preferable for 719 "Make php-mode use coding styles that are preferable for working with Drupal."
672working with Drupal."
673 (interactive) 720 (interactive)
674 (php-set-style "drupal")) 721 (php-set-style "drupal"))
675 722
@@ -683,8 +730,7 @@ working with Drupal."
683 (fill-column . 78))) 730 (fill-column . 78)))
684 731
685(defun php-enable-wordpress-coding-style () 732(defun php-enable-wordpress-coding-style ()
686 "Makes php-mode use coding styles that are preferable for 733 "Make php-mode use coding styles that are preferable for working with Wordpress."
687working with Wordpress."
688 (interactive) 734 (interactive)
689 (php-set-style "wordpress")) 735 (php-set-style "wordpress"))
690 736
@@ -697,8 +743,7 @@ working with Wordpress."
697 (require-final-newline . t))) 743 (require-final-newline . t)))
698 744
699(defun php-enable-symfony2-coding-style () 745(defun php-enable-symfony2-coding-style ()
700 "Makes php-mode use coding styles that are preferable for 746 "Make php-mode use coding styles that are preferable for working with Symfony2."
701working with Symfony2."
702 (interactive) 747 (interactive)
703 (php-set-style "symfony2")) 748 (php-set-style "symfony2"))
704 749
@@ -713,7 +758,7 @@ working with Symfony2."
713 (php-style-delete-trailing-whitespace . t))) 758 (php-style-delete-trailing-whitespace . t)))
714 759
715(defun php-enable-psr2-coding-style () 760(defun php-enable-psr2-coding-style ()
716 "Makes php-mode comply to the PSR-2 coding style" 761 "Make php-mode comply to the PSR-2 coding style."
717 (interactive) 762 (interactive)
718 (php-set-style "psr2")) 763 (php-set-style "psr2"))
719 764
@@ -882,7 +927,7 @@ This is was done due to the problem reported here:
882 ) 927 )
883 928
884(defun php-lineup-string-cont (langelem) 929(defun php-lineup-string-cont (langelem)
885 "Line up string toward equal sign or dot 930 "Line up string toward equal sign or dot.
886e.g. 931e.g.
887$str = 'some' 932$str = 'some'
888 . 'string'; 933 . 'string';
@@ -916,22 +961,19 @@ this ^ lineup"
916 (beginning-of-line) 961 (beginning-of-line)
917 (if (looking-at-p "\\s-*;\\s-*$") 0 '+))) 962 (if (looking-at-p "\\s-*;\\s-*$") 0 '+)))
918 963
919(defconst php-heredoc-start-re 964(eval-and-compile
920 "<<<\\(?:\\w+\\|'\\w+'\\)$" 965 (defconst php-heredoc-start-re
921 "Regular expression for the start of a PHP heredoc.") 966 "<<<\\(?:\\w+\\|'\\w+'\\)$"
967 "Regular expression for the start of a PHP heredoc."))
922 968
923(defun php-heredoc-end-re (heredoc-start) 969(defun php-heredoc-end-re (heredoc-start)
924 "Build a regular expression for the end of a heredoc started by 970 "Build a regular expression for the end of a heredoc started by the string HEREDOC-START."
925the string HEREDOC-START."
926 ;; Extract just the identifier without <<< and quotes. 971 ;; Extract just the identifier without <<< and quotes.
927 (string-match "\\w+" heredoc-start) 972 (string-match "\\w+" heredoc-start)
928 (concat "^\\(" (match-string 0 heredoc-start) "\\)\\W")) 973 (concat "^\\(" (match-string 0 heredoc-start) "\\)\\W"))
929 974
930(defun php-syntax-propertize-function (start end) 975(defun php-syntax-propertize-function (start end)
931 "Apply propertize rules from START to END." 976 "Apply propertize rules from START to END."
932 ;; (defconst php-syntax-propertize-function
933 ;; (syntax-propertize-rules
934 ;; (php-heredoc-start-re (0 (ignore (php-heredoc-syntax))))))
935 (goto-char start) 977 (goto-char start)
936 (while (and (< (point) end) 978 (while (and (< (point) end)
937 (re-search-forward php-heredoc-start-re end t)) 979 (re-search-forward php-heredoc-start-re end t))
@@ -940,7 +982,12 @@ the string HEREDOC-START."
940 (while (re-search-forward "['\"]" end t) 982 (while (re-search-forward "['\"]" end t)
941 (when (php-in-comment-p) 983 (when (php-in-comment-p)
942 (c-put-char-property (match-beginning 0) 984 (c-put-char-property (match-beginning 0)
943 'syntax-table (string-to-syntax "_"))))) 985 'syntax-table (string-to-syntax "_"))))
986 (funcall
987 (syntax-propertize-rules
988 ("\\(\"\\)\\(\\\\.\\|[^\"\n\\]\\)*\\(\"\\)" (1 "\"") (3 "\""))
989 ("\\('\\)\\(\\\\.\\|[^'\n\\]\\)*\\('\\)" (1 "\"") (3 "\"")))
990 start end))
944 991
945(defun php-heredoc-syntax () 992(defun php-heredoc-syntax ()
946 "Mark the boundaries of searched heredoc." 993 "Mark the boundaries of searched heredoc."
@@ -953,8 +1000,7 @@ the string HEREDOC-START."
953 (c-put-char-property (1- (point)) 'syntax-table (string-to-syntax "|"))) 1000 (c-put-char-property (1- (point)) 'syntax-table (string-to-syntax "|")))
954 1001
955(defun php-syntax-propertize-extend-region (start end) 1002(defun php-syntax-propertize-extend-region (start end)
956 "Extend the propertize region if START or END falls inside a 1003 "Extend the propertize region if START or END falls inside a PHP heredoc."
957PHP heredoc."
958 (let ((new-start) 1004 (let ((new-start)
959 (new-end)) 1005 (new-end))
960 (goto-char start) 1006 (goto-char start)
@@ -1105,6 +1151,28 @@ After setting the stylevars run hooks according to STYLENAME
1105 1151
1106(put 'php-set-style 'interactive-form (interactive-form 'c-set-style)) 1152(put 'php-set-style 'interactive-form (interactive-form 'c-set-style))
1107 1153
1154(defun php-mode-debug ()
1155 "Display informations useful for debugging PHP Mode."
1156 (interactive)
1157 (message "--- PHP-MODE DEBUG BEGIN ---")
1158 (message "versions: %s; %s" (emacs-version) (php-mode-version))
1159 (message "major-mode: %s" major-mode)
1160 (message "minor-modes: %s" (cl-remove-if
1161 (lambda (s) (string-match-p "global" (symbol-name s)))
1162 minor-mode-list))
1163 (message "variables: %s"
1164 (cl-loop for v in '(indent-tabs-mode tab-width)
1165 collect (list v (symbol-value v))))
1166 (message "custom variables: %s"
1167 (cl-loop for (v type) in (custom-group-members 'php nil)
1168 if (eq type 'custom-variable)
1169 collect (list v (symbol-value v))))
1170 (message "c-indentation-style: %s" c-indentation-style)
1171 (message "c-style-variables: %s" (c-get-style-variables c-indentation-style nil))
1172 (message "--- PHP-MODE DEBUG END ---")
1173 (switch-to-buffer "*Messages*")
1174 (goto-char (point-max)))
1175
1108;;;###autoload 1176;;;###autoload
1109(define-derived-mode php-mode c-mode "PHP" 1177(define-derived-mode php-mode c-mode "PHP"
1110 "Major mode for editing PHP code. 1178 "Major mode for editing PHP code.
@@ -1129,14 +1197,9 @@ After setting the stylevars run hooks according to STYLENAME
1129 (modify-syntax-entry ?\n "> b" php-mode-syntax-table) 1197 (modify-syntax-entry ?\n "> b" php-mode-syntax-table)
1130 (modify-syntax-entry ?$ "'" php-mode-syntax-table) 1198 (modify-syntax-entry ?$ "'" php-mode-syntax-table)
1131 1199
1132 (set (make-local-variable 'syntax-propertize-via-font-lock) 1200 (set (make-local-variable 'syntax-propertize-function) #'php-syntax-propertize-function)
1133 '(("\\(\"\\)\\(\\\\.\\|[^\"\n\\]\\)*\\(\"\\)" (1 "\"") (3 "\""))
1134 ("\\(\'\\)\\(\\\\.\\|[^\'\n\\]\\)*\\(\'\\)" (1 "\"") (3 "\""))))
1135
1136 (add-to-list (make-local-variable 'syntax-propertize-extend-region-functions) 1201 (add-to-list (make-local-variable 'syntax-propertize-extend-region-functions)
1137 #'php-syntax-propertize-extend-region) 1202 #'php-syntax-propertize-extend-region)
1138 (set (make-local-variable 'syntax-propertize-function)
1139 #'php-syntax-propertize-function)
1140 1203
1141 (setq imenu-generic-expression php-imenu-generic-expression) 1204 (setq imenu-generic-expression php-imenu-generic-expression)
1142 1205
@@ -1151,11 +1214,10 @@ After setting the stylevars run hooks according to STYLENAME
1151 1214
1152 (php-set-style (symbol-name php-mode-coding-style)) 1215 (php-set-style (symbol-name php-mode-coding-style))
1153 1216
1154 (if (or php-mode-force-pear 1217 (when (or php-mode-force-pear
1155 (and (stringp buffer-file-name) 1218 (and (stringp buffer-file-name)
1156 (string-match "PEAR\\|pear" 1219 (string-match "PEAR\\|pear" buffer-file-name)
1157 (buffer-file-name)) 1220 (string-match "\\.php\\'" buffer-file-name)))
1158 (string-match "\\.php$" (buffer-file-name))))
1159 (php-set-style "pear")) 1221 (php-set-style "pear"))
1160 1222
1161 (setq indent-line-function 'php-cautious-indent-line) 1223 (setq indent-line-function 'php-cautious-indent-line)
@@ -1191,6 +1253,13 @@ After setting the stylevars run hooks according to STYLENAME
1191 (save-excursion 1253 (save-excursion
1192 (php-syntax-propertize-function (point-min) (point-max)))))) 1254 (php-syntax-propertize-function (point-min) (point-max))))))
1193 1255
1256(defvar-mode-local php-mode imenu-create-index-function
1257 (if php-do-not-use-semantic-imenu
1258 #'imenu-default-create-index-function
1259 (require 'semantic/imenu)
1260 #'semantic-create-imenu-index)
1261 "Imenu index function for PHP.")
1262
1194 1263
1195;; Define function name completion function 1264;; Define function name completion function
1196(defvar php-completion-table nil 1265(defvar php-completion-table nil
@@ -1476,8 +1545,8 @@ a completion list."
1476 1545
1477(defvar php-phpdoc-font-lock-keywords 1546(defvar php-phpdoc-font-lock-keywords
1478 `((,(lambda (limit) 1547 `((,(lambda (limit)
1479 (c-font-lock-doc-comments "/\\*\\*" limit 1548 (c-font-lock-doc-comments "/\\*\\*" limit
1480 php-phpdoc-font-lock-doc-comments))))) 1549 php-phpdoc-font-lock-doc-comments)))))
1481 1550
1482(defconst php-font-lock-keywords-1 (c-lang-const c-matchers-1 php) 1551(defconst php-font-lock-keywords-1 (c-lang-const c-matchers-1 php)
1483 "Basic highlighting for PHP Mode.") 1552 "Basic highlighting for PHP Mode.")
@@ -1515,9 +1584,13 @@ a completion list."
1515 ;; - when used as a type hint 1584 ;; - when used as a type hint
1516 ;; - when used as a return type 1585 ;; - when used as a return type
1517 ("(\\(array\\))" 1 font-lock-type-face) 1586 ("(\\(array\\))" 1 font-lock-type-face)
1518 ("\\b\\(array\\)\\s-+\\$" 1 font-lock-type-face) 1587 ("\\b\\(array\\)\\s-+&?\\$" 1 font-lock-type-face)
1519 (")\\s-*:\\s-*\\??\\(array\\)\\b" 1 font-lock-type-face) 1588 (")\\s-*:\\s-*\\??\\(array\\)\\b" 1 font-lock-type-face)
1520 1589
1590 ;; namespaces
1591 ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)[^:a-zA-Z0-9_\\\\]" 1 'font-lock-type-face)
1592 ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)::" 1 'php-constant)
1593
1521 ;; Support the ::class constant in PHP5.6 1594 ;; Support the ::class constant in PHP5.6
1522 ("\\sw+\\(::\\)\\(class\\)\\b" (1 'php-paamayim-nekudotayim) (2 'php-constant))) 1595 ("\\sw+\\(::\\)\\(class\\)\\b" (1 'php-paamayim-nekudotayim) (2 'php-constant)))
1523 1596
@@ -1610,7 +1683,7 @@ Look at the `php-executable' variable instead of the constant \"php\" command."
1610 1683
1611 1684
1612(defun php-send-region (start end) 1685(defun php-send-region (start end)
1613 "Send the region between `start' and `end' to PHP for execution. 1686 "Send the region between `START' and `END' to PHP for execution.
1614The output will appear in the buffer *PHP*." 1687The output will appear in the buffer *PHP*."
1615 (interactive "r") 1688 (interactive "r")
1616 (let ((php-buffer (get-buffer-create "*PHP*")) 1689 (let ((php-buffer (get-buffer-create "*PHP*"))
@@ -1658,20 +1731,6 @@ The output will appear in the buffer *PHP*."
1658 (delete-char 1)))) 1731 (delete-char 1))))
1659 1732
1660(ad-activate 'fixup-whitespace) 1733(ad-activate 'fixup-whitespace)
1661
1662;; Advice `font-lock-fontify-keywords-region' to support namespace
1663;; separators in class names. Use word syntax for backslashes when
1664;; doing keyword fontification, but not when doing syntactic
1665;; fontification because that breaks \ as escape character in strings.
1666;;
1667;; Special care is taken to restore the original syntax, because we
1668;; want \ not to be word for functions like forward-word.
1669(defadvice font-lock-fontify-keywords-region (around backslash-as-word activate)
1670 "Fontify keywords with backslash as word character."
1671 (let ((old-syntax (string (char-syntax ?\\))))
1672 (modify-syntax-entry ?\\ "w")
1673 ad-do-it
1674 (modify-syntax-entry ?\\ old-syntax)))
1675 1734
1676 1735
1677(defcustom php-class-suffix-when-insert "::" 1736(defcustom php-class-suffix-when-insert "::"
@@ -1697,6 +1756,18 @@ The output will appear in the buffer *PHP*."
1697 (match-string-no-properties 1)))) 1756 (match-string-no-properties 1))))
1698 1757
1699;;;###autoload 1758;;;###autoload
1759(defun php-project-get-root-dir ()
1760 "Return path to current PHP project."
1761 (let ((detect-method (if (stringp php-project-root)
1762 (list php-project-root)
1763 (if (eq php-project-root 'auto)
1764 (cl-loop for m in php-available-project-root-files
1765 append (cdr m))
1766 (cdr-safe (assq php-project-root php-available-project-root-files))))))
1767 (cl-loop for m in detect-method
1768 thereis (locate-dominating-file default-directory m))))
1769
1770;;;###autoload
1700(defun php-current-class () 1771(defun php-current-class ()
1701 "Insert current class name if cursor in class context." 1772 "Insert current class name if cursor in class context."
1702 (interactive) 1773 (interactive)
diff --git a/.emacs.d/lisp/yaml-mode.el b/.emacs.d/lisp/yaml-mode.el
index e257379..c3416dd 100644
--- a/.emacs.d/lisp/yaml-mode.el
+++ b/.emacs.d/lisp/yaml-mode.el
@@ -234,18 +234,19 @@ that key is pressed to begin a block literal."
234;; Font-lock support 234;; Font-lock support
235 235
236(defvar yaml-font-lock-keywords 236(defvar yaml-font-lock-keywords
237 `((,yaml-constant-scalars-re . (1 font-lock-constant-face)) 237 `((yaml-font-lock-block-literals 0 font-lock-string-face)
238 (,yaml-constant-scalars-re . (1 font-lock-constant-face))
238 (,yaml-tag-re . (0 font-lock-type-face)) 239 (,yaml-tag-re . (0 font-lock-type-face))
239 (,yaml-node-anchor-alias-re . (0 font-lock-function-name-face)) 240 (,yaml-node-anchor-alias-re . (0 font-lock-function-name-face))
240 (,yaml-hash-key-re . (1 font-lock-variable-name-face)) 241 (,yaml-hash-key-re . (1 font-lock-variable-name-face))
241 (,yaml-document-delimiter-re . (0 font-lock-comment-face)) 242 (,yaml-document-delimiter-re . (0 font-lock-comment-face))
242 (,yaml-directive-re . (1 font-lock-builtin-face)) 243 (,yaml-directive-re . (1 font-lock-builtin-face))
243 (yaml-font-lock-block-literals 0 font-lock-string-face)
244 ("^[\t]+" 0 'yaml-tab-face t)) 244 ("^[\t]+" 0 'yaml-tab-face t))
245 "Additional expressions to highlight in YAML mode.") 245 "Additional expressions to highlight in YAML mode.")
246 246
247(defun yaml-mode-syntax-propertize-function (beg end) 247(defun yaml-mode-syntax-propertize-function (beg end)
248 "Unhighlight foo#bar tokens between BEG and END." 248 "Override buffer's syntax table for special syntactic constructs."
249 ;; Unhighlight foo#bar tokens between BEG and END.
249 (save-excursion 250 (save-excursion
250 (goto-char beg) 251 (goto-char beg)
251 (while (search-forward "#" end t) 252 (while (search-forward "#" end t)
@@ -255,7 +256,27 @@ that key is pressed to begin a block literal."
255 (when (and (not (bolp)) 256 (when (and (not (bolp))
256 (not (memq (preceding-char) '(?\s ?\t)))) 257 (not (memq (preceding-char) '(?\s ?\t))))
257 (put-text-property (point) (1+ (point)) 258 (put-text-property (point) (1+ (point))
258 'syntax-table (string-to-syntax "_"))))))) 259 'syntax-table (string-to-syntax "_"))))))
260
261 ;; If quote is detected as a syntactic string start but appeared
262 ;; after a non-whitespace character, then mark it as syntactic word.
263 (save-excursion
264 (goto-char beg)
265 (while (re-search-forward "['\"]" end t)
266 (when (get-text-property (point) 'yaml-block-literal)
267 (put-text-property (1- (point)) (point)
268 'syntax-table (string-to-syntax "w")))
269 (when (nth 8 (syntax-ppss))
270 (save-excursion
271 (forward-char -1)
272 (cond ((and (char-equal ?' (char-before (point)))
273 (char-equal ?' (char-after (point)))
274 (put-text-property (1- (point)) (1+ (point))
275 'syntax-table (string-to-syntax "w"))))
276 ((and (not (bolp))
277 (char-equal ?w (char-syntax (char-before (point)))))
278 (put-text-property (point) (1+ (point))
279 'syntax-table (string-to-syntax "w")))))))))
259 280
260(defun yaml-font-lock-block-literals (bound) 281(defun yaml-font-lock-block-literals (bound)
261 "Find lines within block literals. 282 "Find lines within block literals.
@@ -272,29 +293,36 @@ artificially limitted to the value of
272 (let ((begin (point)) 293 (let ((begin (point))
273 (end (min (1+ (point-at-eol)) bound))) 294 (end (min (1+ (point-at-eol)) bound)))
274 (goto-char (point-at-bol)) 295 (goto-char (point-at-bol))
275 (while (and (looking-at yaml-blank-line-re) (not (bobp))) 296 (while (and (looking-at yaml-blank-line-re)
297 (not (bobp)))
276 (forward-line -1)) 298 (forward-line -1))
277 (let ((nlines yaml-block-literal-search-lines) 299 (let ((nlines yaml-block-literal-search-lines)
278 (min-level (current-indentation))) 300 (min-level (current-indentation)))
279 (forward-line -1) 301 (forward-line -1)
280 (while (and (/= nlines 0) 302 (while (and (/= nlines 0)
281 (/= min-level 0) 303 (/= min-level 0)
282 (not (looking-at yaml-block-literal-re)) 304 (not (looking-at yaml-block-literal-re))
283 (not (bobp))) 305 (not (bobp)))
284 (set 'nlines (1- nlines)) 306 (setq nlines (1- nlines))
285 (unless (looking-at yaml-blank-line-re) 307 (unless (looking-at yaml-blank-line-re)
286 (set 'min-level (min min-level (current-indentation)))) 308 (setq min-level (min min-level (current-indentation))))
287 (forward-line -1)) 309 (forward-line -1))
288 (cond 310 (cond
289 ((and (< (current-indentation) min-level) 311 ((and (< (current-indentation) min-level)
290 (looking-at yaml-block-literal-re)) 312 (looking-at yaml-block-literal-re))
291 (goto-char end) (set-match-data (list begin end)) t) 313 (goto-char end)
314 (put-text-property begin end 'yaml-block-literal t)
315 (set-match-data (list begin end))
316 t)
292 ((progn 317 ((progn
293 (goto-char begin) 318 (goto-char begin)
294 (re-search-forward (concat yaml-block-literal-re 319 (re-search-forward (concat yaml-block-literal-re
295 " *\\(.*\\)\n") 320 " *\\(.*\\)\n")
296 bound t)) 321 bound t))
297 (set-match-data (nthcdr 2 (match-data))) t)))))) 322 (let ((range (nthcdr 2 (match-data))))
323 (put-text-property (car range) (cadr range) 'yaml-block-literal t)
324 (set-match-data range))
325 t))))))
298 326
299 327
300;; Indentation and electric keys 328;; Indentation and electric keys
@@ -329,8 +357,8 @@ back-dent the line by `yaml-indent-offset' spaces. On reaching column
329 (if (and (equal last-command this-command) (/= ci 0)) 357 (if (and (equal last-command this-command) (/= ci 0))
330 (indent-to (* (/ (- ci 1) yaml-indent-offset) yaml-indent-offset)) 358 (indent-to (* (/ (- ci 1) yaml-indent-offset) yaml-indent-offset))
331 (indent-to need))) 359 (indent-to need)))
332 (if (< (current-column) (current-indentation)) 360 (if (< (current-column) (current-indentation))
333 (forward-to-indentation 0)))) 361 (forward-to-indentation 0))))
334 362
335(defun yaml-electric-backspace (arg) 363(defun yaml-electric-backspace (arg)
336 "Delete characters or back-dent the current line. 364 "Delete characters or back-dent the current line.
@@ -374,8 +402,8 @@ margin."
374 (self-insert-command (prefix-numeric-value arg)) 402 (self-insert-command (prefix-numeric-value arg))
375 (save-excursion 403 (save-excursion
376 (beginning-of-line) 404 (beginning-of-line)
377 (if (and (not arg) (looking-at yaml-document-delimiter-re)) 405 (when (and (not arg) (looking-at yaml-document-delimiter-re))
378 (delete-horizontal-space)))) 406 (delete-horizontal-space))))
379 407
380(defun yaml-narrow-to-block-literal () 408(defun yaml-narrow-to-block-literal ()
381 "Narrow the buffer to block literal if the point is in it, 409 "Narrow the buffer to block literal if the point is in it,
@@ -393,13 +421,13 @@ otherwise do nothing."
393 (/= min-level 0) 421 (/= min-level 0)
394 (not (looking-at-p yaml-block-literal-re)) 422 (not (looking-at-p yaml-block-literal-re))
395 (not (bobp))) 423 (not (bobp)))
396 (set 'nlines (1- nlines)) 424 (setq nlines (1- nlines))
397 (unless (looking-at-p yaml-blank-line-re) 425 (unless (looking-at-p yaml-blank-line-re)
398 (set 'min-level (min min-level (current-indentation)))) 426 (setq min-level (min min-level (current-indentation))))
399 (forward-line -1)) 427 (forward-line -1))
400 (when (and (< (current-indentation) min-level) 428 (when (and (< (current-indentation) min-level)
401 (looking-at-p yaml-block-literal-re)) 429 (looking-at-p yaml-block-literal-re))
402 (set 'min-level (current-indentation)) 430 (setq min-level (current-indentation))
403 (forward-line) 431 (forward-line)
404 (setq beg (point)) 432 (setq beg (point))
405 (while (and (not (eobp)) 433 (while (and (not (eobp))
diff --git a/.emacs.d/lisp/yasnippet.el b/.emacs.d/lisp/yasnippet.el
index b3c5c90..69b880a 100644
--- a/.emacs.d/lisp/yasnippet.el
+++ b/.emacs.d/lisp/yasnippet.el
@@ -157,16 +157,14 @@
157 (file-name-directory (or load-file-name buffer-file-name)) 157 (file-name-directory (or load-file-name buffer-file-name))
158 "Directory that yasnippet was loaded from.") 158 "Directory that yasnippet was loaded from.")
159 159
160(defvar yas-installed-snippets-dir nil) 160(defconst yas-installed-snippets-dir (expand-file-name "snippets" yas--loaddir))
161(setq yas-installed-snippets-dir 161(make-obsolete-variable 'yas-installed-snippets-dir "\
162 (expand-file-name "snippets" yas--loaddir)) 162Yasnippet no longer comes with installed snippets" "0.13")
163 163
164(defconst yas--default-user-snippets-dir 164(defconst yas--default-user-snippets-dir
165 (expand-file-name "snippets" user-emacs-directory)) 165 (expand-file-name "snippets" user-emacs-directory))
166 166
167(defcustom yas-snippet-dirs (remove nil 167(defcustom yas-snippet-dirs (list yas--default-user-snippets-dir)
168 (list yas--default-user-snippets-dir
169 'yas-installed-snippets-dir))
170 "List of top-level snippet directories. 168 "List of top-level snippet directories.
171 169
172Each element, a string or a symbol whose value is a string, 170Each element, a string or a symbol whose value is a string,
@@ -398,18 +396,26 @@ It must be set to nil before loading yasnippet to take effect."
398 396
399;;; User-visible variables 397;;; User-visible variables
400 398
399(defconst yas-maybe-skip-and-clear-field
400 '(menu-item "" yas-skip-and-clear-field
401 :filter yas--maybe-clear-field-filter)
402 "A conditional key definition.
403This can be used as a key definition in keymaps to bind a key to
404`yas-skip-and-clear-field' only when at the beginning of an
405unmodified snippey field.")
406
401(defvar yas-keymap (let ((map (make-sparse-keymap))) 407(defvar yas-keymap (let ((map (make-sparse-keymap)))
402 (define-key map [(tab)] 'yas-next-field-or-maybe-expand) 408 (define-key map [(tab)] 'yas-next-field-or-maybe-expand)
403 (define-key map (kbd "TAB") 'yas-next-field-or-maybe-expand) 409 (define-key map (kbd "TAB") 'yas-next-field-or-maybe-expand)
404 (define-key map [(shift tab)] 'yas-prev-field) 410 (define-key map [(shift tab)] 'yas-prev-field)
405 (define-key map [backtab] 'yas-prev-field) 411 (define-key map [backtab] 'yas-prev-field)
406 (define-key map (kbd "C-g") 'yas-abort-snippet) 412 (define-key map (kbd "C-g") 'yas-abort-snippet)
407 (define-key map (kbd "C-d") 'yas-skip-and-clear-or-delete-char) 413 (define-key map (kbd "C-d") yas-maybe-skip-and-clear-field)
408 map) 414 map)
409 "The active keymap while a snippet expansion is in progress.") 415 "The active keymap while a snippet expansion is in progress.")
410 416
411(defvar yas-key-syntaxes (list "w" "w_" "w_." "w_.()" 417(defvar yas-key-syntaxes (list #'yas-try-key-from-whitespace
412 #'yas-try-key-from-whitespace) 418 "w_.()" "w_." "w_" "w")
413 "Syntaxes and functions to help look for trigger keys before point. 419 "Syntaxes and functions to help look for trigger keys before point.
414 420
415Each element in this list specifies how to skip buffer positions 421Each element in this list specifies how to skip buffer positions
@@ -953,14 +959,25 @@ Honour `yas-dont-activate-functions', which see."
953 "The keymap used when `snippet-mode' is active.") 959 "The keymap used when `snippet-mode' is active.")
954 960
955 961
956;;;###autoload 962
957(define-derived-mode snippet-mode text-mode "Snippet" 963;;;###autoload(autoload 'snippet-mode "yasnippet" "A mode for editing yasnippets" t nil)
958 "A mode for editing yasnippets" 964(eval-and-compile
959 (setq font-lock-defaults '(yas--font-lock-keywords)) 965 (if (fboundp 'prog-mode)
960 (set (make-local-variable 'require-final-newline) nil) 966 ;; `prog-mode' is new in 24.1.
961 (set (make-local-variable 'comment-start) "#") 967 (define-derived-mode snippet-mode prog-mode "Snippet"
962 (set (make-local-variable 'comment-start-skip) "#+[\t ]*") 968 "A mode for editing yasnippets"
963 (add-hook 'after-save-hook #'yas-maybe-load-snippet-buffer nil t)) 969 (setq font-lock-defaults '(yas--font-lock-keywords))
970 (set (make-local-variable 'require-final-newline) nil)
971 (set (make-local-variable 'comment-start) "#")
972 (set (make-local-variable 'comment-start-skip) "#+[\t ]*")
973 (add-hook 'after-save-hook #'yas-maybe-load-snippet-buffer nil t))
974 (define-derived-mode snippet-mode fundamental-mode "Snippet"
975 "A mode for editing yasnippets"
976 (setq font-lock-defaults '(yas--font-lock-keywords))
977 (set (make-local-variable 'require-final-newline) nil)
978 (set (make-local-variable 'comment-start) "#")
979 (set (make-local-variable 'comment-start-skip) "#+[\t ]*")
980 (add-hook 'after-save-hook #'yas-maybe-load-snippet-buffer nil t))))
964 981
965(defun yas-snippet-mode-buffer-p () 982(defun yas-snippet-mode-buffer-p ()
966 "Return non-nil if current buffer should be in `snippet-mode'. 983 "Return non-nil if current buffer should be in `snippet-mode'.
@@ -1493,7 +1510,7 @@ Here's a list of currently recognized directives:
1493 expand-env 1510 expand-env
1494 binding 1511 binding
1495 uuid) 1512 uuid)
1496 (if (re-search-forward "^# --\n" nil t) 1513 (if (re-search-forward "^# --\\s-*\n" nil t)
1497 (progn (setq template 1514 (progn (setq template
1498 (buffer-substring-no-properties (point) 1515 (buffer-substring-no-properties (point)
1499 (point-max))) 1516 (point-max)))
@@ -1938,12 +1955,19 @@ prefix argument."
1938 (yas-direct-keymaps-reload) 1955 (yas-direct-keymaps-reload)
1939 1956
1940 (run-hooks 'yas-after-reload-hook) 1957 (run-hooks 'yas-after-reload-hook)
1941 (yas--message (if errors 2 3) 1958 (let ((no-snippets
1942 (if no-jit "Snippets loaded %s." 1959 (cl-every (lambda (table) (= (hash-table-count table) 0))
1943 "Prepared just-in-time loading of snippets %s.") 1960 (list yas--scheduled-jit-loads
1944 (if errors 1961 yas--parents yas--tables))))
1945 "with some errors. Check *Messages*" 1962 (yas--message (if (or no-snippets errors) 2 3)
1946 "successfully"))))) 1963 (if no-jit "Snippets loaded %s."
1964 "Prepared just-in-time loading of snippets %s.")
1965 (cond (errors
1966 "with some errors. Check *Messages*")
1967 (no-snippets
1968 "(but no snippets found)")
1969 (t
1970 "successfully")))))))
1947 1971
1948(defvar yas-after-reload-hook nil 1972(defvar yas-after-reload-hook nil
1949 "Hooks run after `yas-reload-all'.") 1973 "Hooks run after `yas-reload-all'.")
@@ -2388,18 +2412,17 @@ Honours `yas-choose-tables-first', `yas-choose-keys-first' and
2388 :key #'yas--template-name :test #'string=))) 2412 :key #'yas--template-name :test #'string=)))
2389 2413
2390(defun yas-lookup-snippet (name &optional mode noerror) 2414(defun yas-lookup-snippet (name &optional mode noerror)
2391 "Get the snippet content for the snippet NAME in MODE's tables. 2415 "Get the snippet named NAME in MODE's tables.
2392 2416
2393MODE defaults to the current buffer's `major-mode'. If NOERROR 2417MODE defaults to the current buffer's `major-mode'. If NOERROR
2394is non-nil, then don't signal an error if there isn't any snippet 2418is non-nil, then don't signal an error if there isn't any snippet
2395called NAME. 2419called NAME.
2396 2420
2397Honours `yas-buffer-local-condition'." 2421Honours `yas-buffer-local-condition'."
2398 (let ((snippet (yas--lookup-snippet-1 name mode))) 2422 (cond
2399 (cond 2423 ((yas--lookup-snippet-1 name mode))
2400 (snippet (yas--template-content snippet)) 2424 (noerror nil)
2401 (noerror nil) 2425 (t (error "No snippet named: %s" name))))
2402 (t (error "No snippet named: %s" name)))))
2403 2426
2404(defun yas-insert-snippet (&optional no-condition) 2427(defun yas-insert-snippet (&optional no-condition)
2405 "Choose a snippet to expand, pop-up a list of choices according 2428 "Choose a snippet to expand, pop-up a list of choices according
@@ -2495,10 +2518,11 @@ where snippets of table might exist."
2495 (tables (if table (list table) 2518 (tables (if table (list table)
2496 (yas--get-snippet-tables)))) 2519 (yas--get-snippet-tables))))
2497 ;; HACK! the snippet table created here is actually registered! 2520 ;; HACK! the snippet table created here is actually registered!
2498 ;; 2521 (unless table
2499 (unless (or table (gethash major-mode yas--tables)) 2522 ;; The major mode is probably the best guess, put it first.
2500 (push (yas--table-get-create major-mode) 2523 (let ((major-mode-table (yas--table-get-create major-mode)))
2501 tables)) 2524 (cl-callf2 delq major-mode-table tables)
2525 (push major-mode-table tables)))
2502 2526
2503 (mapcar #'(lambda (table) 2527 (mapcar #'(lambda (table)
2504 (cons table 2528 (cons table
@@ -2689,8 +2713,11 @@ and `kill-buffer' instead."
2689 (save-buffer))) 2713 (save-buffer)))
2690 (quit-window kill))) 2714 (quit-window kill)))
2691 2715
2716(declare-function yas-debug-snippets "yasnippet-debug")
2717
2692(defun yas-tryout-snippet (&optional debug) 2718(defun yas-tryout-snippet (&optional debug)
2693 "Test current buffer's snippet template in other buffer." 2719 "Test current buffer's snippet template in other buffer.
2720DEBUG is for debugging the YASnippet engine itself."
2694 (interactive "P") 2721 (interactive "P")
2695 (let* ((major-mode-and-parent (yas--compute-major-mode-and-parents buffer-file-name)) 2722 (let* ((major-mode-and-parent (yas--compute-major-mode-and-parents buffer-file-name))
2696 (parsed (yas--parse-template)) 2723 (parsed (yas--parse-template))
@@ -2720,9 +2747,9 @@ and `kill-buffer' instead."
2720 (point-max) 2747 (point-max)
2721 (yas--template-expand-env yas--current-template)) 2748 (yas--template-expand-env yas--current-template))
2722 (when (and debug 2749 (when (and debug
2723 (require 'yasnippet-debug nil t) 2750 (require 'yasnippet-debug nil t))
2724 (fboundp 'yas-debug-snippet-vars)) 2751 (yas-debug-snippets "*YASnippet trace*" 'snippet-navigation)
2725 (add-hook 'post-command-hook #'yas-debug-snippet-vars nil t)))) 2752 (display-buffer "*YASnippet trace*"))))
2726 (t 2753 (t
2727 (yas--message 1 "Cannot test snippet for unknown major mode"))))) 2754 (yas--message 1 "Cannot test snippet for unknown major mode")))))
2728 2755
@@ -3527,22 +3554,37 @@ holds the keymap."
3527 (overlay-put overlay 'yas--snippet snippet) 3554 (overlay-put overlay 'yas--snippet snippet)
3528 overlay)) 3555 overlay))
3529 3556
3557(defun yas-current-field ()
3558 "Return the currently active field."
3559 (and yas--active-field-overlay
3560 (overlay-buffer yas--active-field-overlay)
3561 (overlay-get yas--active-field-overlay 'yas--field)))
3562
3563(defun yas--maybe-clear-field-filter (cmd)
3564 "Return CMD if at start of unmodified snippet field.
3565Use as a `:filter' argument for a conditional keybinding."
3566 (let ((field (yas-current-field)))
3567 (when (and field
3568 (not (yas--field-modified-p field))
3569 (eq (point) (marker-position (yas--field-start field))))
3570 cmd)))
3571
3572(defun yas-skip-and-clear-field (&optional field)
3573 "Clears unmodified FIELD if at field start, skips to next tab."
3574 (interactive)
3575 (yas--skip-and-clear (or field (yas-current-field)))
3576 (yas-next-field 1))
3577
3530(defun yas-skip-and-clear-or-delete-char (&optional field) 3578(defun yas-skip-and-clear-or-delete-char (&optional field)
3531 "Clears unmodified field if at field start, skips to next tab. 3579 "Clears unmodified field if at field start, skips to next tab.
3532 3580
3533Otherwise deletes a character normally by calling `delete-char'." 3581Otherwise deletes a character normally by calling `delete-char'."
3534 (interactive) 3582 (interactive)
3535 (let ((field (or field 3583 (declare (obsolete "Bind to `yas-maybe-skip-and-clear-field' instead." "0.13"))
3536 (and yas--active-field-overlay 3584 (cond ((yas--maybe-clear-field-filter t)
3537 (overlay-buffer yas--active-field-overlay) 3585 (yas--skip-and-clear (or field (yas-current-field)))
3538 (overlay-get yas--active-field-overlay 'yas--field))))) 3586 (yas-next-field 1))
3539 (cond ((and field 3587 (t (call-interactively 'delete-char))))
3540 (not (yas--field-modified-p field))
3541 (eq (point) (marker-position (yas--field-start field))))
3542 (yas--skip-and-clear field)
3543 (yas-next-field 1))
3544 (t
3545 (call-interactively 'delete-char)))))
3546 3588
3547(defun yas--skip-and-clear (field &optional from) 3589(defun yas--skip-and-clear (field &optional from)
3548 "Deletes the region of FIELD and sets it's modified state to t. 3590 "Deletes the region of FIELD and sets it's modified state to t.
@@ -3740,124 +3782,100 @@ Move the overlays, or create them if they do not exit."
3740;; running, but if managed correctly (including overlay priorities) 3782;; running, but if managed correctly (including overlay priorities)
3741;; they should account for all situations... 3783;; they should account for all situations...
3742 3784
3743(defvar yas--first-indent-undo nil 3785(defun yas-expand-snippet (snippet &optional start end expand-env)
3744 "Internal variable for indent undo entries. 3786 "Expand SNIPPET at current point.
3745Used to pass info from `yas--indent-region' to `yas-expand-snippet'.")
3746(defvar yas--get-indent-undo-pos nil
3747 "Record undo info for line beginning at given position.
3748We bind this when first creating a snippet. See also
3749`yas--first-indent-undo'.")
3750
3751(defun yas-expand-snippet (content &optional start end expand-env)
3752 "Expand snippet CONTENT at current point.
3753 3787
3754Text between START and END will be deleted before inserting 3788Text between START and END will be deleted before inserting
3755template. EXPAND-ENV is a list of (SYM VALUE) let-style dynamic bindings 3789template. EXPAND-ENV is a list of (SYM VALUE) let-style dynamic
3756considered when expanding the snippet." 3790bindings considered when expanding the snippet. If omitted, use
3791SNIPPET's expand-env field.
3792
3793SNIPPET may be a snippet structure (e.g., as returned by
3794`yas-lookup-snippet'), or just a snippet body (which is a string
3795for normal snippets, and a list for command snippets)."
3757 (cl-assert (and yas-minor-mode 3796 (cl-assert (and yas-minor-mode
3758 (memq 'yas--post-command-handler post-command-hook)) 3797 (memq 'yas--post-command-handler post-command-hook))
3759 nil 3798 nil
3760 "[yas] `yas-expand-snippet' needs properly setup `yas-minor-mode'") 3799 "[yas] `yas-expand-snippet' needs properly setup `yas-minor-mode'")
3761 (run-hooks 'yas-before-expand-snippet-hook) 3800 (run-hooks 'yas-before-expand-snippet-hook)
3762 3801
3763 ;; 3802 (let* ((clear-field
3764 (let* ((yas-selected-text (or yas-selected-text 3803 (let ((field (and yas--active-field-overlay
3765 (and (region-active-p) 3804 (overlay-buffer yas--active-field-overlay)
3766 (buffer-substring-no-properties (region-beginning) 3805 (overlay-get yas--active-field-overlay 'yas--field))))
3767 (region-end))))) 3806 (and field (yas--skip-and-clear-field-p
3768 (start (or start 3807 field (point) (point) 0)
3769 (and (region-active-p) 3808 field)))
3770 (region-beginning)) 3809 (start (cond (start)
3771 (point))) 3810 ((region-active-p)
3772 (end (or end 3811 (region-beginning))
3773 (and (region-active-p) 3812 (clear-field
3774 (region-end)) 3813 (yas--field-start clear-field))
3775 (point))) 3814 (t (point))))
3776 (to-delete (and start 3815 (end (cond (end)
3777 end 3816 ((region-active-p)
3817 (region-end))
3818 (clear-field
3819 (yas--field-end clear-field))
3820 (t (point))))
3821 (to-delete (and (> end start)
3778 (buffer-substring-no-properties start end))) 3822 (buffer-substring-no-properties start end)))
3779 (yas--first-indent-undo nil) 3823 (yas-selected-text
3780 snippet) 3824 (cond (yas-selected-text)
3825 ((and (region-active-p)
3826 (not clear-field))
3827 to-delete))))
3781 (goto-char start) 3828 (goto-char start)
3782 (setq yas--indent-original-column (current-column)) 3829 (setq yas--indent-original-column (current-column))
3783 ;; Delete the region to delete, this *does* get undo-recorded. 3830 ;; Delete the region to delete, this *does* get undo-recorded.
3784 ;; 3831 (when to-delete
3785 (when (and to-delete
3786 (> end start))
3787 (delete-region start end)) 3832 (delete-region start end))
3788 3833
3789 (cond ((listp content) 3834 (let ((content (if (yas--template-p snippet)
3790 ;; x) This is a snippet-command 3835 (yas--template-content snippet)
3791 ;; 3836 snippet)))
3792 (yas--eval-for-effect content)) 3837 (when (and (not expand-env) (yas--template-p snippet))
3793 (t 3838 (setq expand-env (yas--template-expand-env snippet)))
3794 ;; x) This is a snippet-snippet :-) 3839 (cond ((listp content)
3795 ;; 3840 ;; x) This is a snippet-command.
3796 ;; Narrow the region down to the content, shoosh the 3841 (yas--eval-for-effect content))
3797 ;; `buffer-undo-list', and create the snippet, the new 3842 (t
3798 ;; snippet updates its mirrors once, so we are left with 3843 ;; x) This is a snippet-snippet :-)
3799 ;; some plain text. The undo action for deleting this
3800 ;; plain text will get recorded at the end.
3801 ;;
3802 ;; stacked expansion: also shoosh the overlay modification hooks
3803 (let ((buffer-undo-list t)
3804 (yas--get-indent-undo-pos (line-beginning-position)))
3805 ;; snippet creation might evaluate users elisp, which
3806 ;; might generate errors, so we have to be ready to catch
3807 ;; them mostly to make the undo information
3808 ;;
3809 (setq yas--start-column (current-column)) 3844 (setq yas--start-column (current-column))
3845 ;; Stacked expansion: also shoosh the overlay modification hooks.
3810 (let ((yas--inhibit-overlay-hooks t)) 3846 (let ((yas--inhibit-overlay-hooks t))
3811 (insert content)
3812 (setq snippet 3847 (setq snippet
3813 (yas--snippet-create expand-env start (point))))) 3848 (yas--snippet-create content expand-env start (point))))
3814 3849
3815 ;; stacked-expansion: This checks for stacked expansion, save the 3850 ;; Stacked-expansion: This checks for stacked expansion, save the
3816 ;; `yas--previous-active-field' and advance its boundary. 3851 ;; `yas--previous-active-field' and advance its boundary.
3817 ;; 3852 (let ((existing-field (and yas--active-field-overlay
3818 (let ((existing-field (and yas--active-field-overlay 3853 (overlay-buffer yas--active-field-overlay)
3819 (overlay-buffer yas--active-field-overlay) 3854 (overlay-get yas--active-field-overlay 'yas--field))))
3820 (overlay-get yas--active-field-overlay 'yas--field)))) 3855 (when existing-field
3821 (when existing-field 3856 (setf (yas--snippet-previous-active-field snippet) existing-field)
3822 (setf (yas--snippet-previous-active-field snippet) existing-field) 3857 (yas--advance-end-maybe existing-field (overlay-end yas--active-field-overlay))))
3823 (yas--advance-end-maybe existing-field (overlay-end yas--active-field-overlay))))
3824 3858
3825 ;; Exit the snippet immediately if no fields 3859 ;; Exit the snippet immediately if no fields.
3826 ;; 3860 (unless (yas--snippet-fields snippet)
3827 (unless (yas--snippet-fields snippet) 3861 (yas-exit-snippet snippet))
3828 (yas-exit-snippet snippet))
3829 3862
3830 ;; Undo actions from indent of snippet's 1st line. 3863 ;; Now, schedule a move to the first field.
3831 (setq buffer-undo-list 3864 (let ((first-field (car (yas--snippet-fields snippet))))
3832 (nconc yas--first-indent-undo buffer-undo-list)) 3865 (when first-field
3833 ;; Undo action for the expand snippet contents. 3866 (sit-for 0) ;; fix issue 125
3834 (push (cons (overlay-start (yas--snippet-control-overlay snippet)) 3867 (yas--letenv (yas--snippet-expand-env snippet)
3835 (overlay-end (yas--snippet-control-overlay snippet))) 3868 (yas--move-to-field snippet first-field))
3836 buffer-undo-list) 3869 (when (and (eq (yas--field-number first-field) 0)
3837 ;; Follow up with `yas--take-care-of-redo' on the newly 3870 (> (length (yas--field-text-for-display
3838 ;; inserted snippet boundaries. 3871 first-field))
3839 (push `(apply yas--take-care-of-redo ,start 3872 0))
3840 ,(overlay-end (yas--snippet-control-overlay snippet)) 3873 ;; Keep region for ${0:exit text}.
3841 ,snippet) 3874 (setq deactivate-mark nil))))
3842 buffer-undo-list) 3875 (yas--message 4 "snippet %d expanded." (yas--snippet-id snippet))
3876 t)))))
3843 3877
3844 ;; Now, schedule a move to the first field 3878(defun yas--take-care-of-redo (snippet)
3845 ;;
3846 (let ((first-field (car (yas--snippet-fields snippet))))
3847 (when first-field
3848 (sit-for 0) ;; fix issue 125
3849 (yas--letenv (yas--snippet-expand-env snippet)
3850 (yas--move-to-field snippet first-field))
3851 (when (and (eq (yas--field-number first-field) 0)
3852 (> (length (yas--field-text-for-display
3853 first-field))
3854 0))
3855 ;; Keep region for ${0:exit text}.
3856 (setq deactivate-mark nil))))
3857 (yas--message 4 "snippet %d expanded." (yas--snippet-id snippet))
3858 t))))
3859
3860(defun yas--take-care-of-redo (_beg _end snippet)
3861 "Commits SNIPPET, which in turn pushes an undo action for reviving it. 3879 "Commits SNIPPET, which in turn pushes an undo action for reviving it.
3862 3880
3863Meant to exit in the `buffer-undo-list'." 3881Meant to exit in the `buffer-undo-list'."
@@ -3882,19 +3900,37 @@ After revival, push the `yas--take-care-of-redo' in the
3882 (when (yas--maybe-move-to-active-field snippet) 3900 (when (yas--maybe-move-to-active-field snippet)
3883 (setf (yas--snippet-control-overlay snippet) (yas--make-control-overlay snippet beg end)) 3901 (setf (yas--snippet-control-overlay snippet) (yas--make-control-overlay snippet beg end))
3884 (overlay-put (yas--snippet-control-overlay snippet) 'yas--snippet snippet) 3902 (overlay-put (yas--snippet-control-overlay snippet) 'yas--snippet snippet)
3885 (push `(apply yas--take-care-of-redo ,beg ,end ,snippet) 3903 (push `(apply yas--take-care-of-redo ,snippet)
3886 buffer-undo-list))) 3904 buffer-undo-list)))
3887 3905
3888(defun yas--snippet-create (expand-env begin end) 3906(defun yas--snippet-create (content expand-env begin end)
3889 "Create a snippet from a template inserted at BEGIN to END. 3907 "Create a snippet from a template inserted at BEGIN to END.
3890 3908
3891Returns the newly created snippet." 3909Returns the newly created snippet."
3892 (save-restriction 3910 (save-restriction
3893 (narrow-to-region begin end)
3894 (let ((snippet (yas--make-snippet expand-env))) 3911 (let ((snippet (yas--make-snippet expand-env)))
3895 (yas--letenv expand-env 3912 (yas--letenv expand-env
3896 (goto-char begin) 3913 ;; Put a single undo action for the expanded snippet's
3897 (yas--snippet-parse-create snippet) 3914 ;; content.
3915 (let ((buffer-undo-list t))
3916 ;; Some versions of cc-mode fail when inserting snippet
3917 ;; content in a narrowed buffer.
3918 (goto-char begin)
3919 (insert content)
3920 (setq end (+ end (length content)))
3921 (narrow-to-region begin end)
3922 (goto-char (point-min))
3923 (yas--snippet-parse-create snippet))
3924 (push (cons (point-min) (point-max))
3925 buffer-undo-list)
3926
3927 ;; Indent, collecting undo information normally.
3928 (yas--indent snippet)
3929
3930 ;; Follow up with `yas--take-care-of-redo' on the newly
3931 ;; inserted snippet boundaries.
3932 (push `(apply yas--take-care-of-redo ,snippet)
3933 buffer-undo-list)
3898 3934
3899 ;; Sort and link each field 3935 ;; Sort and link each field
3900 (yas--snippet-sort-fields snippet) 3936 (yas--snippet-sort-fields snippet)
@@ -3991,22 +4027,27 @@ has to be called before the $-constructs are deleted."
3991 (when soup 4027 (when soup
3992 (cl-reduce link-foms soup))))) 4028 (cl-reduce link-foms soup)))))
3993 4029
3994(defun yas--calculate-mirrors-in-fields (snippet mirror) 4030(defun yas--calculate-simple-fom-parentage (snippet fom)
3995 "Attempt to assign a parent field of SNIPPET to the mirror MIRROR. 4031 "Discover if FOM is parented by some field in SNIPPET.
3996 4032
3997Use the tightest containing field if more than one field contains 4033Use the tightest containing field if more than one field contains
3998the mirror. Intended to be called *before* the dollar-regions are 4034the mirror. Intended to be called *before* the dollar-regions are
3999deleted." 4035deleted."
4000 (let ((min (point-min)) 4036 (let ((min (point-min))
4001 (max (point-max))) 4037 (max (point-max)))
4002 (dolist (field (yas--snippet-fields snippet)) 4038 (dolist (field (remq fom (yas--snippet-fields snippet)))
4003 (when (and (<= (yas--field-start field) (yas--mirror-start mirror)) 4039 (when (and (<= (yas--field-start field) (yas--fom-start fom))
4004 (<= (yas--mirror-end mirror) (yas--field-end field)) 4040 (<= (yas--fom-end fom) (yas--field-end field))
4005 (< min (yas--field-start field)) 4041 (< min (yas--field-start field))
4006 (< (yas--field-end field) max)) 4042 (< (yas--field-end field) max))
4007 (setq min (yas--field-start field) 4043 (setq min (yas--field-start field)
4008 max (yas--field-end field)) 4044 max (yas--field-end field))
4009 (setf (yas--mirror-parent-field mirror) field))))) 4045 (cond ((yas--field-p fom)
4046 (setf (yas--field-parent-field fom) field))
4047 ((yas--mirror-p fom)
4048 (setf (yas--mirror-parent-field fom) field))
4049 (t ; it's an exit, so noop
4050 nil ))))))
4010 4051
4011(defun yas--advance-end-maybe (fom newend) 4052(defun yas--advance-end-maybe (fom newend)
4012 "Maybe advance FOM's end to NEWEND if it needs it. 4053 "Maybe advance FOM's end to NEWEND if it needs it.
@@ -4050,11 +4091,6 @@ next FOM. Works its way up recursively for parents of parents."
4050 "When expanding the snippet the \"parse-create\" functions add 4091 "When expanding the snippet the \"parse-create\" functions add
4051cons cells to this var.") 4092cons cells to this var.")
4052 4093
4053(defvar yas--backquote-markers-and-strings nil
4054 "List of (MARKER . STRING) marking where the values from
4055backquoted Lisp expressions should be inserted at the end of
4056expansion.")
4057
4058(defvar yas--indent-markers nil 4094(defvar yas--indent-markers nil
4059 "List of markers for manual indentation.") 4095 "List of markers for manual indentation.")
4060 4096
@@ -4063,21 +4099,22 @@ expansion.")
4063necessary fields, mirrors and exit points. 4099necessary fields, mirrors and exit points.
4064 4100
4065Meant to be called in a narrowed buffer, does various passes" 4101Meant to be called in a narrowed buffer, does various passes"
4066 (let ((parse-start (point))) 4102 (let ((saved-quotes nil)
4103 (parse-start (point)))
4067 ;; Avoid major-mode's syntax propertizing function, since we 4104 ;; Avoid major-mode's syntax propertizing function, since we
4068 ;; change the syntax-table while calling `scan-sexps'. 4105 ;; change the syntax-table while calling `scan-sexps'.
4069 (let ((syntax-propertize-function nil)) 4106 (let ((syntax-propertize-function nil))
4070 (setq yas--dollar-regions nil) ; Reset the yas--dollar-regions. 4107 (setq yas--dollar-regions nil) ; Reset the yas--dollar-regions.
4071 (yas--protect-escapes nil '(?`)) ; Protect just the backquotes. 4108 (yas--protect-escapes nil '(?`)) ; Protect just the backquotes.
4072 (goto-char parse-start) 4109 (goto-char parse-start)
4073 (yas--save-backquotes) ; Replace all backquoted expressions. 4110 (setq saved-quotes (yas--save-backquotes)) ; `expressions`.
4074 (yas--protect-escapes) ; Protect escaped characters. 4111 (yas--protect-escapes) ; Protect escaped characters.
4075 (goto-char parse-start) 4112 (goto-char parse-start)
4076 (yas--indent-parse-create) ; Parse indent markers: `$>'. 4113 (yas--indent-parse-create) ; Parse indent markers: `$>'.
4077 (goto-char parse-start) 4114 (goto-char parse-start)
4078 (yas--field-parse-create snippet) ; Parse fields with {}. 4115 (yas--field-parse-create snippet) ; Parse fields with {}.
4079 (goto-char parse-start) 4116 (goto-char parse-start)
4080 (yas--simple-mirror-parse-create snippet) ; Parse simple mirrors & fields. 4117 (yas--simple-fom-create snippet) ; Parse simple mirrors & fields.
4081 (goto-char parse-start) 4118 (goto-char parse-start)
4082 (yas--transform-mirror-parse-create snippet) ; Parse mirror transforms. 4119 (yas--transform-mirror-parse-create snippet) ; Parse mirror transforms.
4083 ;; Invalidate any syntax-propertizing done while 4120 ;; Invalidate any syntax-propertizing done while
@@ -4101,12 +4138,11 @@ Meant to be called in a narrowed buffer, does various passes"
4101 (get-register yas-wrap-around-region)) 4138 (get-register yas-wrap-around-region))
4102 (insert (prog1 (get-register yas-wrap-around-region) 4139 (insert (prog1 (get-register yas-wrap-around-region)
4103 (set-register yas-wrap-around-region nil))))) 4140 (set-register yas-wrap-around-region nil)))))
4104 (yas--restore-backquotes) ; Restore backquoted expression values. 4141 (yas--restore-backquotes saved-quotes) ; Restore `expression` values.
4105 (goto-char parse-start) 4142 (goto-char parse-start)
4106 (yas--restore-escapes) ; Restore escapes. 4143 (yas--restore-escapes) ; Restore escapes.
4107 (yas--update-mirrors snippet) ; Update mirrors for the first time. 4144 (yas--update-mirrors snippet) ; Update mirrors for the first time.
4108 (goto-char parse-start)) 4145 (goto-char parse-start)))
4109 (yas--indent snippet)) ; Indent the best we can.
4110 4146
4111;; HACK: Some implementations of `indent-line-function' (called via 4147;; HACK: Some implementations of `indent-line-function' (called via
4112;; `indent-according-to-mode') delete text before they insert (like 4148;; `indent-according-to-mode') delete text before they insert (like
@@ -4246,12 +4282,7 @@ The SNIPPET's markers are preserved."
4246 remarkers))) 4282 remarkers)))
4247 (unwind-protect 4283 (unwind-protect
4248 (progn (back-to-indentation) 4284 (progn (back-to-indentation)
4249 (if (eq yas--get-indent-undo-pos bol) 4285 (indent-according-to-mode))
4250 (let ((buffer-undo-list nil))
4251 (indent-according-to-mode)
4252 (setq yas--first-indent-undo
4253 (delq nil buffer-undo-list)))
4254 (indent-according-to-mode)))
4255 (save-restriction 4286 (save-restriction
4256 (narrow-to-region bol (line-end-position)) 4287 (narrow-to-region bol (line-end-position))
4257 (mapc #'yas--restore-marker-location remarkers)))) 4288 (mapc #'yas--restore-marker-location remarkers))))
@@ -4322,9 +4353,11 @@ With optional string TEXT do it in string instead of the buffer."
4322 changed-text)) 4353 changed-text))
4323 4354
4324(defun yas--save-backquotes () 4355(defun yas--save-backquotes ()
4325 "Save all the \"\\=`(lisp-expression)\\=`\"-style expressions 4356 "Save all \"\\=`(lisp-expression)\\=`\"-style expressions.
4326with their evaluated value into `yas--backquote-markers-and-strings'." 4357Return a list of (MARKER . STRING) entires for each backquoted
4327 (let* ((yas--snippet-buffer (current-buffer)) 4358Lisp expression."
4359 (let* ((saved-quotes nil)
4360 (yas--snippet-buffer (current-buffer))
4328 (yas--change-detected nil) 4361 (yas--change-detected nil)
4329 (detect-change (lambda (_beg _end) 4362 (detect-change (lambda (_beg _end)
4330 (when (eq (current-buffer) yas--snippet-buffer) 4363 (when (eq (current-buffer) yas--snippet-buffer)
@@ -4347,29 +4380,28 @@ with their evaluated value into `yas--backquote-markers-and-strings'."
4347 (insert "Y") ;; quite horrendous, I love it :) 4380 (insert "Y") ;; quite horrendous, I love it :)
4348 (set-marker marker (point)) 4381 (set-marker marker (point))
4349 (insert "Y")) 4382 (insert "Y"))
4350 (push (cons marker transformed) yas--backquote-markers-and-strings))))) 4383 (push (cons marker transformed) saved-quotes)))))
4351 (when yas--change-detected 4384 (when yas--change-detected
4352 (lwarn '(yasnippet backquote-change) :warning 4385 (lwarn '(yasnippet backquote-change) :warning
4353 "`%s' modified buffer in a backquote expression. 4386 "`%s' modified buffer in a backquote expression.
4354 To hide this warning, add (yasnippet backquote-change) to `warning-suppress-types'." 4387 To hide this warning, add (yasnippet backquote-change) to `warning-suppress-types'."
4355 (if yas--current-template 4388 (if yas--current-template
4356 (yas--template-name yas--current-template) 4389 (yas--template-name yas--current-template)
4357 "Snippet"))))) 4390 "Snippet")))
4391 saved-quotes))
4358 4392
4359(defun yas--restore-backquotes () 4393(defun yas--restore-backquotes (saved-quotes)
4360 "Replace markers in `yas--backquote-markers-and-strings' with their values." 4394 "Replace markers in SAVED-QUOTES with their values.
4361 (while yas--backquote-markers-and-strings 4395SAVED-QUOTES is the in format returned by `yas--save-backquotes'."
4362 (let* ((marker-and-string (pop yas--backquote-markers-and-strings)) 4396 (cl-loop for (marker . string) in saved-quotes do
4363 (marker (car marker-and-string)) 4397 (save-excursion
4364 (string (cdr marker-and-string))) 4398 (goto-char marker)
4365 (save-excursion 4399 (save-restriction
4366 (goto-char marker) 4400 (widen)
4367 (save-restriction 4401 (delete-char -1)
4368 (widen) 4402 (insert string)
4369 (delete-char -1) 4403 (delete-char 1))
4370 (insert string) 4404 (set-marker marker nil))))
4371 (delete-char 1))
4372 (set-marker marker nil)))))
4373 4405
4374(defun yas--scan-sexps (from count) 4406(defun yas--scan-sexps (from count)
4375 (ignore-errors 4407 (ignore-errors
@@ -4488,10 +4520,10 @@ When multiple expressions are found, only the last one counts."
4488 (when brand-new-mirror 4520 (when brand-new-mirror
4489 (push brand-new-mirror 4521 (push brand-new-mirror
4490 (yas--field-mirrors field)) 4522 (yas--field-mirrors field))
4491 (yas--calculate-mirrors-in-fields snippet brand-new-mirror) 4523 (yas--calculate-simple-fom-parentage snippet brand-new-mirror)
4492 (push (cons (match-beginning 0) real-match-end-0) yas--dollar-regions))))) 4524 (push (cons (match-beginning 0) real-match-end-0) yas--dollar-regions)))))
4493 4525
4494(defun yas--simple-mirror-parse-create (snippet) 4526(defun yas--simple-fom-create (snippet)
4495 "Parse the simple \"$n\" fields/mirrors/exitmarkers in SNIPPET." 4527 "Parse the simple \"$n\" fields/mirrors/exitmarkers in SNIPPET."
4496 (while (re-search-forward yas--simple-mirror-regexp nil t) 4528 (while (re-search-forward yas--simple-mirror-regexp nil t)
4497 (let ((number (string-to-number (match-string-no-properties 1)))) 4529 (let ((number (string-to-number (match-string-no-properties 1))))
@@ -4501,20 +4533,22 @@ When multiple expressions are found, only the last one counts."
4501 (push (cons (match-beginning 0) (yas--exit-marker (yas--snippet-exit snippet))) 4533 (push (cons (match-beginning 0) (yas--exit-marker (yas--snippet-exit snippet)))
4502 yas--dollar-regions)) 4534 yas--dollar-regions))
4503 (t 4535 (t
4504 (let ((field (yas--snippet-find-field snippet number))) 4536 (let ((field (yas--snippet-find-field snippet number))
4537 (fom))
4505 (if field 4538 (if field
4506 (let ((brand-new-mirror (yas--make-mirror 4539 (push
4507 (yas--make-marker (match-beginning 0)) 4540 (setq fom (yas--make-mirror
4508 (yas--make-marker (match-beginning 0)) 4541 (yas--make-marker (match-beginning 0))
4509 nil))) 4542 (yas--make-marker (match-beginning 0))
4510 (push brand-new-mirror 4543 nil))
4511 (yas--field-mirrors field)) 4544 (yas--field-mirrors field))
4512 (yas--calculate-mirrors-in-fields snippet brand-new-mirror)) 4545 (push
4513 (push (yas--make-field number 4546 (setq fom (yas--make-field number
4514 (yas--make-marker (match-beginning 0)) 4547 (yas--make-marker (match-beginning 0))
4515 (yas--make-marker (match-beginning 0)) 4548 (yas--make-marker (match-beginning 0))
4516 nil) 4549 nil))
4517 (yas--snippet-fields snippet)))) 4550 (yas--snippet-fields snippet)))
4551 (yas--calculate-simple-fom-parentage snippet fom))
4518 (push (cons (match-beginning 0) (match-end 0)) 4552 (push (cons (match-beginning 0) (match-end 0))
4519 yas--dollar-regions)))))) 4553 yas--dollar-regions))))))
4520 4554
@@ -4737,7 +4771,7 @@ object satisfying `yas--field-p' to restrict the expansion to.")))
4737 "Log level for `yas--message' 4 means trace most anything, 0 means nothing.") 4771 "Log level for `yas--message' 4 means trace most anything, 0 means nothing.")
4738 4772
4739(defun yas--message (level message &rest args) 4773(defun yas--message (level message &rest args)
4740 "When LEVEL is at or below `yas-verbosity-level', log MESSAGE and ARGS." 4774 "When LEVEL is at or below `yas-verbosity', log MESSAGE and ARGS."
4741 (when (>= yas-verbosity level) 4775 (when (>= yas-verbosity level)
4742 (message "%s" (apply #'yas--format message args)))) 4776 (message "%s" (apply #'yas--format message args))))
4743 4777
@@ -4805,6 +4839,31 @@ and return the directory. Return nil if not found."
4805 (directory-file-name file)))) 4839 (directory-file-name file))))
4806 (setq file nil)))) 4840 (setq file nil))))
4807 root)))) 4841 root))))
4842
4843;;; Unloading
4844
4845(defvar unload-function-defs-list) ; loadhist.el
4846
4847(defun yasnippet-unload-function ()
4848 "Disable minor modes when calling `unload-feature'."
4849 ;; Disable `yas-minor-mode' everywhere it's enabled.
4850 (yas-global-mode -1)
4851 (save-current-buffer
4852 (dolist (buffer (buffer-list))
4853 (set-buffer buffer)
4854 (when yas-minor-mode
4855 (yas-minor-mode -1))))
4856 ;; Remove symbol properties of all our functions, this avoids
4857 ;; Bug#25088 in Emacs 25.1, where the compiler macro on
4858 ;; `cl-defstruct' created functions hang around in the symbol plist
4859 ;; and cause errors when loading again (we don't *need* to clean
4860 ;; *all* symbol plists, but it's easier than being precise).
4861 (dolist (def unload-function-defs-list)
4862 (when (eq (car-safe def) 'defun)
4863 (setplist (cdr def) nil)))
4864 ;; Return nil so that `unload-feature' will take of undefining
4865 ;; functions, and changing any buffers using `snippet-mode'.
4866 nil)
4808 4867
4809 4868
4810;;; Backward compatibility to yasnippet <= 0.7 4869;;; Backward compatibility to yasnippet <= 0.7