diff options
| author | Simeon Simeonov | 2017-02-21 08:27:23 +0100 |
|---|---|---|
| committer | Simeon Simeonov | 2017-02-21 08:27:23 +0100 |
| commit | 6c9184e45865406de1df73a5b352df16fb55a6dd (patch) | |
| tree | f6c552dff9a5cc9f9bdbb7a0d58ee4ad3b4179d6 /.emacs.d/lisp/yasnippet.el | |
| parent | d09417873b51c525cdea37fb8d165ae28da4e97a (diff) | |
Update php-mode.el, yaml-mode.el and yasnippet.el
Diffstat (limited to '.emacs.d/lisp/yasnippet.el')
| -rw-r--r-- | .emacs.d/lisp/yasnippet.el | 532 |
1 files changed, 315 insertions, 217 deletions
diff --git a/.emacs.d/lisp/yasnippet.el b/.emacs.d/lisp/yasnippet.el index 7b01599..7b871b9 100644 --- a/.emacs.d/lisp/yasnippet.el +++ b/.emacs.d/lisp/yasnippet.el | |||
| @@ -271,22 +271,20 @@ Otherwise `yas-next-field-or-maybe-expand' just moves on to the | |||
| 271 | next field" | 271 | next field" |
| 272 | :type 'boolean) | 272 | :type 'boolean) |
| 273 | 273 | ||
| 274 | (defcustom yas-fallback-behavior 'call-other-command | 274 | (defcustom yas-fallback-behavior 'return-nil |
| 275 | "How to act when `yas-expand' does *not* expand a snippet. | 275 | "This option is obsolete. |
| 276 | 276 | Now that the conditional keybinding `yas-maybe-expand' is | |
| 277 | - `call-other-command' means try to temporarily disable YASnippet | 277 | available, there's no more need for it." |
| 278 | and call the next command bound to whatever key was used to | ||
| 279 | invoke `yas-expand'. | ||
| 280 | |||
| 281 | - nil or the symbol `return-nil' mean do nothing. (and | ||
| 282 | `yas-expand' returns nil) | ||
| 283 | |||
| 284 | - A Lisp form (apply COMMAND . ARGS) means interactively call | ||
| 285 | COMMAND. If ARGS is non-nil, call COMMAND non-interactively | ||
| 286 | with ARGS as arguments." | ||
| 287 | :type '(choice (const :tag "Call previous command" call-other-command) | 278 | :type '(choice (const :tag "Call previous command" call-other-command) |
| 288 | (const :tag "Do nothing" return-nil))) | 279 | (const :tag "Do nothing" return-nil))) |
| 289 | 280 | ||
| 281 | (make-obsolete-variable | ||
| 282 | 'yas-fallback-behavior | ||
| 283 | "For `call-other-command' behavior bind to the conditional | ||
| 284 | command value `yas-maybe-expand', for `return-nil' behavior bind | ||
| 285 | directly to `yas-expand'." | ||
| 286 | "0.12") | ||
| 287 | |||
| 290 | (defcustom yas-choose-keys-first nil | 288 | (defcustom yas-choose-keys-first nil |
| 291 | "If non-nil, prompt for snippet key first, then for template. | 289 | "If non-nil, prompt for snippet key first, then for template. |
| 292 | 290 | ||
| @@ -342,9 +340,16 @@ per-snippet basis. A value of `cua' is considered equivalent to | |||
| 342 | (const cua))) ; backwards compat | 340 | (const cua))) ; backwards compat |
| 343 | 341 | ||
| 344 | (defcustom yas-good-grace t | 342 | (defcustom yas-good-grace t |
| 345 | "If non-nil, don't raise errors in inline elisp evaluation. | 343 | "If non-nil, don't raise errors in elisp evaluation. |
| 344 | |||
| 345 | This affects both the inline elisp in snippets and the hook | ||
| 346 | variables such as `yas-after-exit-snippet-hook'. | ||
| 346 | 347 | ||
| 347 | An error string \"[yas] error\" is returned instead." | 348 | If this variable's value is `inline', an error string \"[yas] |
| 349 | error\" is returned instead of raising the error. If this | ||
| 350 | variable's value is `hooks', a message is output to according to | ||
| 351 | `yas-verbosity-level'. If this variable's value is t, both are | ||
| 352 | active." | ||
| 348 | :type 'boolean) | 353 | :type 'boolean) |
| 349 | 354 | ||
| 350 | (defcustom yas-visit-from-menu nil | 355 | (defcustom yas-visit-from-menu nil |
| @@ -451,13 +456,17 @@ Attention: These hooks are not run when exiting nested/stacked snippet expansion | |||
| 451 | '() | 456 | '() |
| 452 | "Hooks to run just before expanding a snippet.") | 457 | "Hooks to run just before expanding a snippet.") |
| 453 | 458 | ||
| 454 | (defvar yas-buffer-local-condition | 459 | (defconst yas-not-string-or-comment-condition |
| 455 | '(if (and (let ((ppss (syntax-ppss))) | 460 | '(if (and (let ((ppss (syntax-ppss))) |
| 456 | (or (nth 3 ppss) (nth 4 ppss))) | 461 | (or (nth 3 ppss) (nth 4 ppss))) |
| 457 | (memq this-command '(yas-expand yas-expand-from-trigger-key | 462 | (memq this-command '(yas-expand yas-expand-from-trigger-key |
| 458 | yas-expand-from-keymap))) | 463 | yas-expand-from-keymap))) |
| 459 | '(require-snippet-condition . force-in-comment) | 464 | '(require-snippet-condition . force-in-comment) |
| 460 | t) | 465 | t) |
| 466 | "Disables snippet expansion in strings and comments. | ||
| 467 | To use, set `yas-buffer-local-condition' to this value.") | ||
| 468 | |||
| 469 | (defcustom yas-buffer-local-condition t | ||
| 461 | "Snippet expanding condition. | 470 | "Snippet expanding condition. |
| 462 | 471 | ||
| 463 | This variable is a Lisp form which is evaluated every time a | 472 | This variable is a Lisp form which is evaluated every time a |
| @@ -504,12 +513,15 @@ conditions. | |||
| 504 | (setq yas-buffer-local-condition | 513 | (setq yas-buffer-local-condition |
| 505 | \\='(if (python-syntax-comment-or-string-p) | 514 | \\='(if (python-syntax-comment-or-string-p) |
| 506 | \\='(require-snippet-condition . force-in-comment) | 515 | \\='(require-snippet-condition . force-in-comment) |
| 507 | t)))) | 516 | t))))" |
| 508 | 517 | :type | |
| 509 | The default value is similar, it filters out potential snippet | 518 | `(choice |
| 510 | expansions inside comments and string literals, unless the | 519 | (const :tag "Disable snippet expansion inside strings and comments" |
| 511 | snippet itself contains a condition that returns the symbol | 520 | ,yas-not-string-or-comment-condition) |
| 512 | `force-in-comment'.") | 521 | (const :tag "Expand all snippets regardless of conditions" always) |
| 522 | (const :tag "Expand snippets unless their condition is nil" t) | ||
| 523 | (const :tag "Disable all snippet expansion" nil) | ||
| 524 | sexp)) | ||
| 513 | 525 | ||
| 514 | 526 | ||
| 515 | ;;; Internal variables | 527 | ;;; Internal variables |
| @@ -560,10 +572,20 @@ snippet itself contains a condition that returns the symbol | |||
| 560 | (defvar yas--minor-mode-menu nil | 572 | (defvar yas--minor-mode-menu nil |
| 561 | "Holds the YASnippet menu.") | 573 | "Holds the YASnippet menu.") |
| 562 | 574 | ||
| 575 | (defun yas--maybe-expand-key-filter (cmd) | ||
| 576 | (if (yas--templates-for-key-at-point) cmd)) | ||
| 577 | |||
| 578 | (defconst yas-maybe-expand | ||
| 579 | '(menu-item "" yas-expand :filter yas--maybe-expand-key-filter) | ||
| 580 | "A conditional key definition. | ||
| 581 | This can be used as a key definition in keymaps to bind a key to | ||
| 582 | `yas-expand' only when there is a snippet available to be | ||
| 583 | expanded.") | ||
| 584 | |||
| 563 | (defvar yas-minor-mode-map | 585 | (defvar yas-minor-mode-map |
| 564 | (let ((map (make-sparse-keymap))) | 586 | (let ((map (make-sparse-keymap))) |
| 565 | (define-key map [(tab)] 'yas-expand) | 587 | (define-key map [(tab)] yas-maybe-expand) |
| 566 | (define-key map (kbd "TAB") 'yas-expand) | 588 | (define-key map (kbd "TAB") yas-maybe-expand) |
| 567 | (define-key map "\C-c&\C-s" 'yas-insert-snippet) | 589 | (define-key map "\C-c&\C-s" 'yas-insert-snippet) |
| 568 | (define-key map "\C-c&\C-n" 'yas-new-snippet) | 590 | (define-key map "\C-c&\C-n" 'yas-new-snippet) |
| 569 | (define-key map "\C-c&\C-v" 'yas-visit-snippet-file) | 591 | (define-key map "\C-c&\C-v" 'yas-visit-snippet-file) |
| @@ -703,10 +725,10 @@ This variable is placed in `emulation-mode-map-alists'. | |||
| 703 | 725 | ||
| 704 | Its elements looks like (TABLE-NAME . KEYMAP). They're | 726 | Its elements looks like (TABLE-NAME . KEYMAP). They're |
| 705 | instantiated on `yas-reload-all' but KEYMAP is added to only when | 727 | instantiated on `yas-reload-all' but KEYMAP is added to only when |
| 706 | loading snippets. `yas--direct-TABLE-NAME' is then a variable set | 728 | loading snippets. `yas--direct-TABLE-NAME' is then a variable |
| 707 | buffer-locally when entering `yas-minor-mode'. KEYMAP binds all | 729 | set buffer-locally when entering `yas-minor-mode'. KEYMAP binds |
| 708 | defined direct keybindings to the command | 730 | all defined direct keybindings to `yas-maybe-expand-from-keymap' |
| 709 | `yas-expand-from-keymap' which then which snippet to expand.") | 731 | which decides on the snippet to expand.") |
| 710 | 732 | ||
| 711 | (defun yas-direct-keymaps-reload () | 733 | (defun yas-direct-keymaps-reload () |
| 712 | "Force reload the direct keybinding for active snippet tables." | 734 | "Force reload the direct keybinding for active snippet tables." |
| @@ -907,6 +929,21 @@ Honour `yas-dont-activate-functions', which see." | |||
| 907 | (set (make-local-variable 'comment-start-skip) "#+[\t ]*") | 929 | (set (make-local-variable 'comment-start-skip) "#+[\t ]*") |
| 908 | (add-hook 'after-save-hook #'yas-maybe-load-snippet-buffer nil t)) | 930 | (add-hook 'after-save-hook #'yas-maybe-load-snippet-buffer nil t)) |
| 909 | 931 | ||
| 932 | (defun yas-snippet-mode-buffer-p () | ||
| 933 | "Return non-nil if current buffer should be in `snippet-mode'. | ||
| 934 | Meaning it's visiting a file under one of the mode directories in | ||
| 935 | `yas-snippet-dirs'." | ||
| 936 | (when buffer-file-name | ||
| 937 | (member | ||
| 938 | (expand-file-name | ||
| 939 | ".." | ||
| 940 | (file-name-directory buffer-file-name)) | ||
| 941 | (yas-snippet-dirs)))) | ||
| 942 | |||
| 943 | ;; We're abusing `magic-fallback-mode-alist' here because | ||
| 944 | ;; `auto-mode-alist' doesn't support function matchers. | ||
| 945 | (add-to-list 'magic-fallback-mode-alist | ||
| 946 | `(yas-snippet-mode-buffer-p . snippet-mode)) | ||
| 910 | 947 | ||
| 911 | 948 | ||
| 912 | ;;; Internal structs for template management | 949 | ;;; Internal structs for template management |
| @@ -976,7 +1013,7 @@ Has the following fields: | |||
| 976 | A keymap for the snippets in this table that have direct | 1013 | A keymap for the snippets in this table that have direct |
| 977 | keybindings. This is kept in sync with the keyhash, i.e., all | 1014 | keybindings. This is kept in sync with the keyhash, i.e., all |
| 978 | the elements of the keyhash that are vectors appear here as | 1015 | the elements of the keyhash that are vectors appear here as |
| 979 | bindings to `yas-expand-from-keymap'. | 1016 | bindings to `yas-maybe-expand-from-keymap'. |
| 980 | 1017 | ||
| 981 | `yas--table-uuidhash' | 1018 | `yas--table-uuidhash' |
| 982 | 1019 | ||
| @@ -1075,6 +1112,10 @@ Has the following fields: | |||
| 1075 | ;; | 1112 | ;; |
| 1076 | (remhash uuid (yas--table-uuidhash table)))))) | 1113 | (remhash uuid (yas--table-uuidhash table)))))) |
| 1077 | 1114 | ||
| 1115 | (defconst yas-maybe-expand-from-keymap | ||
| 1116 | '(menu-item "" yas-expand-from-keymap | ||
| 1117 | :filter yas--maybe-expand-from-keymap-filter)) | ||
| 1118 | |||
| 1078 | (defun yas--add-template (table template) | 1119 | (defun yas--add-template (table template) |
| 1079 | "Store in TABLE the snippet template TEMPLATE. | 1120 | "Store in TABLE the snippet template TEMPLATE. |
| 1080 | 1121 | ||
| @@ -1093,7 +1134,7 @@ keybinding)." | |||
| 1093 | (make-hash-table :test 'equal) | 1134 | (make-hash-table :test 'equal) |
| 1094 | (yas--table-hash table)))) | 1135 | (yas--table-hash table)))) |
| 1095 | (when (vectorp k) | 1136 | (when (vectorp k) |
| 1096 | (define-key (yas--table-direct-keymap table) k 'yas-expand-from-keymap))) | 1137 | (define-key (yas--table-direct-keymap table) k yas-maybe-expand-from-keymap))) |
| 1097 | 1138 | ||
| 1098 | ;; Update TABLE's `yas--table-uuidhash' | 1139 | ;; Update TABLE's `yas--table-uuidhash' |
| 1099 | (puthash (yas--template-uuid template) | 1140 | (puthash (yas--template-uuid template) |
| @@ -1296,33 +1337,22 @@ Returns (TEMPLATES START END). This function respects | |||
| 1296 | 1337 | ||
| 1297 | ;;; Internal functions and macros: | 1338 | ;;; Internal functions and macros: |
| 1298 | 1339 | ||
| 1299 | (defun yas--handle-error (err) | 1340 | (defun yas--eval-for-string (form) |
| 1300 | "Handle error depending on value of `yas-good-grace'." | ||
| 1301 | (let ((msg (yas--format "elisp error: %s" (error-message-string err)))) | ||
| 1302 | (if yas-good-grace msg | ||
| 1303 | (error "%s" msg)))) | ||
| 1304 | |||
| 1305 | (defun yas--eval-lisp (form) | ||
| 1306 | "Evaluate FORM and convert the result to string." | 1341 | "Evaluate FORM and convert the result to string." |
| 1307 | (let ((retval (catch 'yas--exception | 1342 | (let ((debug-on-error (and (not (memq yas-good-grace '(t inline))) |
| 1308 | (condition-case err | 1343 | debug-on-error))) |
| 1309 | (save-excursion | 1344 | (condition-case oops |
| 1310 | (save-restriction | 1345 | (save-excursion |
| 1311 | (save-match-data | 1346 | (save-restriction |
| 1312 | (widen) | 1347 | (save-match-data |
| 1313 | (let ((result (eval form))) | 1348 | (widen) |
| 1314 | (when result | 1349 | (let ((result (eval form))) |
| 1315 | (format "%s" result)))))) | 1350 | (when result |
| 1316 | (error (yas--handle-error err)))))) | 1351 | (format "%s" result)))))) |
| 1317 | (when (and (consp retval) | 1352 | ((debug error) (cdr oops))))) |
| 1318 | (eq 'yas--exception (car retval))) | ||
| 1319 | (error (cdr retval))) | ||
| 1320 | retval)) | ||
| 1321 | 1353 | ||
| 1322 | (defun yas--eval-lisp-no-saves (form) | 1354 | (defun yas--eval-for-effect (form) |
| 1323 | (condition-case err | 1355 | (yas--safely-run-hook (apply-partially #'eval form))) |
| 1324 | (eval form) | ||
| 1325 | (error (message "%s" (yas--handle-error err))))) | ||
| 1326 | 1356 | ||
| 1327 | (defun yas--read-lisp (string &optional nil-on-error) | 1357 | (defun yas--read-lisp (string &optional nil-on-error) |
| 1328 | "Read STRING as a elisp expression and return it. | 1358 | "Read STRING as a elisp expression and return it. |
| @@ -1638,7 +1668,7 @@ this is a snippet or a snippet-command. | |||
| 1638 | 1668 | ||
| 1639 | CONDITION, EXPAND-ENV and KEYBINDING are Lisp forms, they have | 1669 | CONDITION, EXPAND-ENV and KEYBINDING are Lisp forms, they have |
| 1640 | been `yas--read-lisp'-ed and will eventually be | 1670 | been `yas--read-lisp'-ed and will eventually be |
| 1641 | `yas--eval-lisp'-ed. | 1671 | `yas--eval-for-string'-ed. |
| 1642 | 1672 | ||
| 1643 | The remaining elements are strings. | 1673 | The remaining elements are strings. |
| 1644 | 1674 | ||
| @@ -1731,8 +1761,7 @@ With prefix argument USE-JIT do jit-loading of snippets." | |||
| 1731 | ;; | 1761 | ;; |
| 1732 | (yas--define-parents mode-sym parents) | 1762 | (yas--define-parents mode-sym parents) |
| 1733 | (yas--menu-keymap-get-create mode-sym) | 1763 | (yas--menu-keymap-get-create mode-sym) |
| 1734 | (let ((fun `(lambda () ;; FIXME: Simulating lexical-binding. | 1764 | (let ((fun (apply-partially #'yas--load-directory-1 dir mode-sym))) |
| 1735 | (yas--load-directory-1 ',dir ',mode-sym)))) | ||
| 1736 | (if use-jit | 1765 | (if use-jit |
| 1737 | (yas--schedule-jit mode-sym fun) | 1766 | (yas--schedule-jit mode-sym fun) |
| 1738 | (funcall fun))) | 1767 | (funcall fun))) |
| @@ -2167,12 +2196,7 @@ object satisfying `yas--field-p' to restrict the expansion to." | |||
| 2167 | (nth 2 templates-and-pos))) | 2196 | (nth 2 templates-and-pos))) |
| 2168 | (yas--fallback)))) | 2197 | (yas--fallback)))) |
| 2169 | 2198 | ||
| 2170 | (defun yas-expand-from-keymap () | 2199 | (defun yas--maybe-expand-from-keymap-filter (cmd) |
| 2171 | "Directly expand some snippets, searching `yas--direct-keymaps'. | ||
| 2172 | |||
| 2173 | If expansion fails, execute the previous binding for this key" | ||
| 2174 | (interactive) | ||
| 2175 | (setq yas--condition-cache-timestamp (current-time)) | ||
| 2176 | (let* ((vec (cl-subseq (this-command-keys-vector) | 2200 | (let* ((vec (cl-subseq (this-command-keys-vector) |
| 2177 | (if current-prefix-arg | 2201 | (if current-prefix-arg |
| 2178 | (length (this-command-keys)) | 2202 | (length (this-command-keys)) |
| @@ -2180,10 +2204,15 @@ If expansion fails, execute the previous binding for this key" | |||
| 2180 | (templates (cl-mapcan (lambda (table) | 2204 | (templates (cl-mapcan (lambda (table) |
| 2181 | (yas--fetch table vec)) | 2205 | (yas--fetch table vec)) |
| 2182 | (yas--get-snippet-tables)))) | 2206 | (yas--get-snippet-tables)))) |
| 2183 | (if templates | 2207 | (if templates (or cmd templates)))) |
| 2184 | (yas--expand-or-prompt-for-template templates) | 2208 | |
| 2185 | (let ((yas-fallback-behavior 'call-other-command)) | 2209 | (defun yas-expand-from-keymap () |
| 2186 | (yas--fallback))))) | 2210 | "Directly expand some snippets, searching `yas--direct-keymaps'." |
| 2211 | (interactive) | ||
| 2212 | (setq yas--condition-cache-timestamp (current-time)) | ||
| 2213 | (let* ((templates (yas--maybe-expand-from-keymap-filter nil))) | ||
| 2214 | (when templates | ||
| 2215 | (yas--expand-or-prompt-for-template templates)))) | ||
| 2187 | 2216 | ||
| 2188 | (defun yas--expand-or-prompt-for-template (templates &optional start end) | 2217 | (defun yas--expand-or-prompt-for-template (templates &optional start end) |
| 2189 | "Expand one of TEMPLATES from START to END. | 2218 | "Expand one of TEMPLATES from START to END. |
| @@ -2827,16 +2856,16 @@ The last element of POSSIBILITIES may be a list of strings." | |||
| 2827 | key))))) | 2856 | key))))) |
| 2828 | 2857 | ||
| 2829 | (defun yas-throw (text) | 2858 | (defun yas-throw (text) |
| 2830 | "Throw a yas--exception with TEXT as the reason." | 2859 | "Signal `yas-exception' with TEXT as the reason." |
| 2831 | (throw 'yas--exception (cons 'yas--exception text))) | 2860 | (signal 'yas-exception (list text))) |
| 2861 | (put 'yas-exception 'error-conditions '(error yas-exception)) | ||
| 2862 | (put 'yas-exception 'error-message "[yas] Exception") | ||
| 2832 | 2863 | ||
| 2833 | (defun yas-verify-value (possibilities) | 2864 | (defun yas-verify-value (possibilities) |
| 2834 | "Verify that the current field value is in POSSIBILITIES. | 2865 | "Verify that the current field value is in POSSIBILITIES. |
| 2835 | 2866 | Otherwise signal `yas-exception'." | |
| 2836 | Otherwise throw exception." | 2867 | (when (and yas-moving-away-p (cl-notany (lambda (pos) (string= pos yas-text)) possibilities)) |
| 2837 | (when (and yas-moving-away-p | 2868 | (yas-throw (format "Field only allows %s" possibilities)))) |
| 2838 | (cl-notany (lambda (pos) (string= pos yas-text)) possibilities)) | ||
| 2839 | (yas-throw (yas--format "Field only allows %s" possibilities)))) | ||
| 2840 | 2869 | ||
| 2841 | (defun yas-field-value (number) | 2870 | (defun yas-field-value (number) |
| 2842 | "Get the string for field with NUMBER. | 2871 | "Get the string for field with NUMBER. |
| @@ -2961,6 +2990,20 @@ ENV is a list of elements with the form (VAR FORM)." | |||
| 2961 | (declare (debug (form body)) (indent 1)) | 2990 | (declare (debug (form body)) (indent 1)) |
| 2962 | `(eval (cl-list* 'let* ,env ',body))) | 2991 | `(eval (cl-list* 'let* ,env ',body))) |
| 2963 | 2992 | ||
| 2993 | (defun yas--snippet-map-markers (fun snippet) | ||
| 2994 | "Apply FUN to all marker (sub)fields in SNIPPET. | ||
| 2995 | Update each field with the result of calling FUN." | ||
| 2996 | (dolist (field (yas--snippet-fields snippet)) | ||
| 2997 | (setf (yas--field-start field) (funcall fun (yas--field-start field))) | ||
| 2998 | (setf (yas--field-end field) (funcall fun (yas--field-end field))) | ||
| 2999 | (dolist (mirror (yas--field-mirrors field)) | ||
| 3000 | (setf (yas--mirror-start mirror) (funcall fun (yas--mirror-start mirror))) | ||
| 3001 | (setf (yas--mirror-end mirror) (funcall fun (yas--mirror-end mirror))))) | ||
| 3002 | (let ((snippet-exit (yas--snippet-exit snippet))) | ||
| 3003 | (when snippet-exit | ||
| 3004 | (setf (yas--exit-marker snippet-exit) | ||
| 3005 | (funcall fun (yas--exit-marker snippet-exit)))))) | ||
| 3006 | |||
| 2964 | (defun yas--apply-transform (field-or-mirror field &optional empty-on-nil-p) | 3007 | (defun yas--apply-transform (field-or-mirror field &optional empty-on-nil-p) |
| 2965 | "Calculate transformed string for FIELD-OR-MIRROR from FIELD. | 3008 | "Calculate transformed string for FIELD-OR-MIRROR from FIELD. |
| 2966 | 3009 | ||
| @@ -2979,7 +3022,7 @@ string iff EMPTY-ON-NIL-P is true." | |||
| 2979 | (transformed (and transform | 3022 | (transformed (and transform |
| 2980 | (save-excursion | 3023 | (save-excursion |
| 2981 | (goto-char start-point) | 3024 | (goto-char start-point) |
| 2982 | (let ((ret (yas--eval-lisp transform))) | 3025 | (let ((ret (yas--eval-for-string transform))) |
| 2983 | (or ret (and empty-on-nil-p ""))))))) | 3026 | (or ret (and empty-on-nil-p ""))))))) |
| 2984 | transformed)) | 3027 | transformed)) |
| 2985 | 3028 | ||
| @@ -3231,12 +3274,80 @@ This renders the snippet as ordinary text." | |||
| 3231 | 3274 | ||
| 3232 | (yas--message 4 "Snippet %s exited." (yas--snippet-id snippet))) | 3275 | (yas--message 4 "Snippet %s exited." (yas--snippet-id snippet))) |
| 3233 | 3276 | ||
| 3234 | (defun yas--safely-run-hooks (hook-var) | 3277 | (defvar yas--snippets-to-move nil) |
| 3278 | (make-variable-buffer-local 'yas--snippets-to-move) | ||
| 3279 | |||
| 3280 | (defun yas--prepare-snippets-for-move (beg end buf pos) | ||
| 3281 | "Gather snippets in BEG..END for moving to POS in BUF." | ||
| 3282 | (let ((to-move nil) | ||
| 3283 | (snippets (yas-active-snippets beg end)) | ||
| 3284 | (dst-base-line (with-current-buffer buf | ||
| 3285 | (count-lines (point-min) pos)))) | ||
| 3286 | (when snippets | ||
| 3287 | (dolist (snippet snippets) | ||
| 3288 | (yas--snippet-map-markers | ||
| 3289 | (lambda (m) | ||
| 3290 | (goto-char m) | ||
| 3291 | (beginning-of-line) | ||
| 3292 | (prog1 (cons (count-lines (point-min) (point)) | ||
| 3293 | (yas--snapshot-marker-location m)) | ||
| 3294 | (set-marker m nil))) | ||
| 3295 | snippet) | ||
| 3296 | (let ((ctrl-ov (yas--snapshot-overlay-location | ||
| 3297 | (yas--snippet-control-overlay snippet)))) | ||
| 3298 | (push (list ctrl-ov dst-base-line snippet) to-move) | ||
| 3299 | (delete-overlay (car ctrl-ov)))) | ||
| 3300 | (with-current-buffer buf | ||
| 3301 | (setq yas--snippets-to-move (nconc to-move yas--snippets-to-move)))))) | ||
| 3302 | |||
| 3303 | (defun yas--on-buffer-kill () | ||
| 3304 | ;; Org mode uses temp buffers for fontification and "native tab", | ||
| 3305 | ;; move all the snippets to the original org-mode buffer when it's | ||
| 3306 | ;; killed. | ||
| 3307 | (let ((org-marker nil)) | ||
| 3308 | (when (and yas-minor-mode | ||
| 3309 | (or (bound-and-true-p org-edit-src-from-org-mode) | ||
| 3310 | (bound-and-true-p org-src--from-org-mode)) | ||
| 3311 | (markerp | ||
| 3312 | (setq org-marker | ||
| 3313 | (or (bound-and-true-p org-edit-src-beg-marker) | ||
| 3314 | (bound-and-true-p org-src--beg-marker))))) | ||
| 3315 | (yas--prepare-snippets-for-move | ||
| 3316 | (point-min) (point-max) | ||
| 3317 | (marker-buffer org-marker) org-marker)))) | ||
| 3318 | |||
| 3319 | (add-hook 'kill-buffer-hook #'yas--on-buffer-kill) | ||
| 3320 | |||
| 3321 | (defun yas--finish-moving-snippets () | ||
| 3322 | "Finish job started in `yas--prepare-snippets-for-move'." | ||
| 3323 | (cl-loop for (ctrl-ov base-line snippet) in yas--snippets-to-move | ||
| 3324 | for base-pos = (progn (goto-char (point-min)) | ||
| 3325 | (forward-line base-line) (point)) | ||
| 3326 | do (yas--snippet-map-markers | ||
| 3327 | (lambda (l-m-r-w) | ||
| 3328 | (goto-char base-pos) | ||
| 3329 | (forward-line (nth 0 l-m-r-w)) | ||
| 3330 | (yas--restore-marker-location (cdr l-m-r-w)) | ||
| 3331 | (nth 1 l-m-r-w)) | ||
| 3332 | snippet) | ||
| 3333 | (goto-char base-pos) | ||
| 3334 | (yas--restore-overlay-location ctrl-ov) | ||
| 3335 | (yas--maybe-move-to-active-field snippet)) | ||
| 3336 | (setq yas--snippets-to-move nil)) | ||
| 3337 | |||
| 3338 | (defun yas--safely-call-fun (fun) | ||
| 3235 | (condition-case error | 3339 | (condition-case error |
| 3236 | (run-hooks hook-var) | 3340 | (funcall fun) |
| 3237 | (error | 3341 | ((debug error) |
| 3238 | (yas--message 2 "%s error: %s" hook-var (error-message-string error))))) | 3342 | (yas--message 2 "Error running %s: %s" |
| 3343 | (if (symbolp fun) fun "a hook") | ||
| 3344 | (error-message-string error))))) | ||
| 3239 | 3345 | ||
| 3346 | (defun yas--safely-run-hook (hook) | ||
| 3347 | (let ((debug-on-error (and (not (memq yas-good-grace '(t hooks))) | ||
| 3348 | debug-on-error))) | ||
| 3349 | (if (functionp hook) (yas--safely-call-fun hook) | ||
| 3350 | (mapc #'yas--safely-call-fun hook)))) | ||
| 3240 | 3351 | ||
| 3241 | (defun yas--check-commit-snippet () | 3352 | (defun yas--check-commit-snippet () |
| 3242 | "Check if point exited the currently active field of the snippet. | 3353 | "Check if point exited the currently active field of the snippet. |
| @@ -3244,15 +3355,19 @@ This renders the snippet as ordinary text." | |||
| 3244 | If so cleans up the whole snippet up." | 3355 | If so cleans up the whole snippet up." |
| 3245 | (let* ((snippets (yas-active-snippets 'all)) | 3356 | (let* ((snippets (yas-active-snippets 'all)) |
| 3246 | (snippets-left snippets) | 3357 | (snippets-left snippets) |
| 3247 | (snippet-exit-transform)) | 3358 | (snippet-exit-transform nil) |
| 3359 | (snippet-exit-hook yas-after-exit-snippet-hook)) | ||
| 3248 | (dolist (snippet snippets) | 3360 | (dolist (snippet snippets) |
| 3249 | (let ((active-field (yas--snippet-active-field snippet))) | 3361 | (let ((active-field (yas--snippet-active-field snippet))) |
| 3250 | (yas--letenv (yas--snippet-expand-env snippet) | 3362 | (yas--letenv (yas--snippet-expand-env snippet) |
| 3363 | ;; Note: the `force-exit' field could be a transform in case of | ||
| 3364 | ;; ${0: ...}, see `yas--move-to-field'. | ||
| 3251 | (setq snippet-exit-transform (yas--snippet-force-exit snippet)) | 3365 | (setq snippet-exit-transform (yas--snippet-force-exit snippet)) |
| 3252 | (cond ((or snippet-exit-transform | 3366 | (cond ((or snippet-exit-transform |
| 3253 | (not (and active-field (yas--field-contains-point-p active-field)))) | 3367 | (not (and active-field (yas--field-contains-point-p active-field)))) |
| 3254 | (setq snippets-left (delete snippet snippets-left)) | 3368 | (setq snippets-left (delete snippet snippets-left)) |
| 3255 | (setf (yas--snippet-force-exit snippet) nil) | 3369 | (setf (yas--snippet-force-exit snippet) nil) |
| 3370 | (setq snippet-exit-hook yas-after-exit-snippet-hook) | ||
| 3256 | (yas--commit-snippet snippet)) | 3371 | (yas--commit-snippet snippet)) |
| 3257 | ((and active-field | 3372 | ((and active-field |
| 3258 | (or (not yas--active-field-overlay) | 3373 | (or (not yas--active-field-overlay) |
| @@ -3269,63 +3384,40 @@ If so cleans up the whole snippet up." | |||
| 3269 | nil))))) | 3384 | nil))))) |
| 3270 | (unless (or (null snippets) snippets-left) | 3385 | (unless (or (null snippets) snippets-left) |
| 3271 | (if snippet-exit-transform | 3386 | (if snippet-exit-transform |
| 3272 | (yas--eval-lisp-no-saves snippet-exit-transform)) | 3387 | (yas--eval-for-effect snippet-exit-transform)) |
| 3273 | (yas--safely-run-hooks 'yas-after-exit-snippet-hook)))) | 3388 | (yas--safely-run-hook snippet-exit-hook)))) |
| 3274 | 3389 | ||
| 3275 | ;; Apropos markers-to-points: | 3390 | ;; Apropos markers-to-points: |
| 3276 | ;; | 3391 | ;; |
| 3277 | ;; This was found useful for performance reasons, so that an | 3392 | ;; This was found useful for performance reasons, so that an excessive |
| 3278 | ;; excessive number of live markers aren't kept around in the | 3393 | ;; number of live markers aren't kept around in the |
| 3279 | ;; `buffer-undo-list'. However, in `markers-to-points', the | 3394 | ;; `buffer-undo-list'. We reuse the original marker object, although |
| 3280 | ;; set-to-nil markers can't simply be discarded and replaced with | 3395 | ;; that's probably not necessary. |
| 3281 | ;; fresh ones in `points-to-markers'. The original marker that was | ||
| 3282 | ;; just set to nil has to be reused. | ||
| 3283 | ;; | 3396 | ;; |
| 3284 | ;; This shouldn't bring horrible problems with undo/redo, but it | 3397 | ;; This shouldn't bring horrible problems with undo/redo, but you |
| 3285 | ;; you never know | 3398 | ;; never know. |
| 3286 | ;; | 3399 | ;; |
| 3287 | (defun yas--markers-to-points (snippet) | 3400 | (defun yas--markers-to-points (snippet) |
| 3288 | "Convert all markers in SNIPPET to a cons (POINT . MARKER) | 3401 | "Save all markers of SNIPPET as positions." |
| 3289 | where POINT is the original position of the marker and MARKER is | 3402 | (yas--snippet-map-markers (lambda (m) |
| 3290 | the original marker object with the position set to nil." | 3403 | (prog1 (cons (marker-position m) m) |
| 3291 | (dolist (field (yas--snippet-fields snippet)) | 3404 | (set-marker m nil))) |
| 3292 | (let ((start (marker-position (yas--field-start field))) | 3405 | snippet)) |
| 3293 | (end (marker-position (yas--field-end field)))) | ||
| 3294 | (set-marker (yas--field-start field) nil) | ||
| 3295 | (set-marker (yas--field-end field) nil) | ||
| 3296 | (setf (yas--field-start field) (cons start (yas--field-start field))) | ||
| 3297 | (setf (yas--field-end field) (cons end (yas--field-end field)))) | ||
| 3298 | (dolist (mirror (yas--field-mirrors field)) | ||
| 3299 | (let ((start (marker-position (yas--mirror-start mirror))) | ||
| 3300 | (end (marker-position (yas--mirror-end mirror)))) | ||
| 3301 | (set-marker (yas--mirror-start mirror) nil) | ||
| 3302 | (set-marker (yas--mirror-end mirror) nil) | ||
| 3303 | (setf (yas--mirror-start mirror) (cons start (yas--mirror-start mirror))) | ||
| 3304 | (setf (yas--mirror-end mirror) (cons end (yas--mirror-end mirror)))))) | ||
| 3305 | (let ((snippet-exit (yas--snippet-exit snippet))) | ||
| 3306 | (when snippet-exit | ||
| 3307 | (let ((exit (marker-position (yas--exit-marker snippet-exit)))) | ||
| 3308 | (set-marker (yas--exit-marker snippet-exit) nil) | ||
| 3309 | (setf (yas--exit-marker snippet-exit) (cons exit (yas--exit-marker snippet-exit))))))) | ||
| 3310 | 3406 | ||
| 3311 | (defun yas--points-to-markers (snippet) | 3407 | (defun yas--points-to-markers (snippet) |
| 3312 | "Convert all cons (POINT . MARKER) in SNIPPET to markers. | 3408 | "Restore SNIPPET's marker positions, saved by `yas--markers-to-points'." |
| 3409 | (yas--snippet-map-markers (lambda (p-m) | ||
| 3410 | (set-marker (cdr p-m) (car p-m)) | ||
| 3411 | (cdr p-m)) | ||
| 3412 | snippet)) | ||
| 3313 | 3413 | ||
| 3314 | This is done by setting MARKER to POINT with `set-marker'." | 3414 | (defun yas--maybe-move-to-active-field (snippet) |
| 3315 | (dolist (field (yas--snippet-fields snippet)) | 3415 | "Try to move to SNIPPET's active (or first) field and return it if found." |
| 3316 | (setf (yas--field-start field) (set-marker (cdr (yas--field-start field)) | 3416 | (let ((target-field (or (yas--snippet-active-field snippet) |
| 3317 | (car (yas--field-start field)))) | 3417 | (car (yas--snippet-fields snippet))))) |
| 3318 | (setf (yas--field-end field) (set-marker (cdr (yas--field-end field)) | 3418 | (when target-field |
| 3319 | (car (yas--field-end field)))) | 3419 | (yas--move-to-field snippet target-field) |
| 3320 | (dolist (mirror (yas--field-mirrors field)) | 3420 | target-field))) |
| 3321 | (setf (yas--mirror-start mirror) (set-marker (cdr (yas--mirror-start mirror)) | ||
| 3322 | (car (yas--mirror-start mirror)))) | ||
| 3323 | (setf (yas--mirror-end mirror) (set-marker (cdr (yas--mirror-end mirror)) | ||
| 3324 | (car (yas--mirror-end mirror)))))) | ||
| 3325 | (let ((snippet-exit (yas--snippet-exit snippet))) | ||
| 3326 | (when snippet-exit | ||
| 3327 | (setf (yas--exit-marker snippet-exit) (set-marker (cdr (yas--exit-marker snippet-exit)) | ||
| 3328 | (car (yas--exit-marker snippet-exit))))))) | ||
| 3329 | 3421 | ||
| 3330 | (defun yas--field-contains-point-p (field &optional point) | 3422 | (defun yas--field-contains-point-p (field &optional point) |
| 3331 | (let ((point (or point | 3423 | (let ((point (or point |
| @@ -3569,7 +3661,7 @@ considered when expanding the snippet." | |||
| 3569 | (cond ((listp content) | 3661 | (cond ((listp content) |
| 3570 | ;; x) This is a snippet-command | 3662 | ;; x) This is a snippet-command |
| 3571 | ;; | 3663 | ;; |
| 3572 | (yas--eval-lisp-no-saves content)) | 3664 | (yas--eval-for-effect content)) |
| 3573 | (t | 3665 | (t |
| 3574 | ;; x) This is a snippet-snippet :-) | 3666 | ;; x) This is a snippet-snippet :-) |
| 3575 | ;; | 3667 | ;; |
| @@ -3658,21 +3750,14 @@ to their correct locations *at the time the snippet is revived*. | |||
| 3658 | After revival, push the `yas--take-care-of-redo' in the | 3750 | After revival, push the `yas--take-care-of-redo' in the |
| 3659 | `buffer-undo-list'" | 3751 | `buffer-undo-list'" |
| 3660 | ;; Reconvert all the points to markers | 3752 | ;; Reconvert all the points to markers |
| 3661 | ;; | ||
| 3662 | (yas--points-to-markers snippet) | 3753 | (yas--points-to-markers snippet) |
| 3663 | ;; When at least one editable field existed in the zombie snippet, | 3754 | ;; When at least one editable field existed in the zombie snippet, |
| 3664 | ;; try to revive the whole thing... | 3755 | ;; try to revive the whole thing... |
| 3665 | ;; | 3756 | (when (yas--maybe-move-to-active-field snippet) |
| 3666 | (let ((target-field (or (yas--snippet-active-field snippet) | 3757 | (setf (yas--snippet-control-overlay snippet) (yas--make-control-overlay snippet beg end)) |
| 3667 | (car (yas--snippet-fields snippet))))) | 3758 | (overlay-put (yas--snippet-control-overlay snippet) 'yas--snippet snippet) |
| 3668 | (when target-field | 3759 | (push `(apply yas--take-care-of-redo ,beg ,end ,snippet) |
| 3669 | (setf (yas--snippet-control-overlay snippet) (yas--make-control-overlay snippet beg end)) | 3760 | buffer-undo-list))) |
| 3670 | (overlay-put (yas--snippet-control-overlay snippet) 'yas--snippet snippet) | ||
| 3671 | |||
| 3672 | (yas--move-to-field snippet target-field) | ||
| 3673 | |||
| 3674 | (push `(apply yas--take-care-of-redo ,beg ,end ,snippet) | ||
| 3675 | buffer-undo-list)))) | ||
| 3676 | 3761 | ||
| 3677 | (defun yas--snippet-create (expand-env begin end) | 3762 | (defun yas--snippet-create (expand-env begin end) |
| 3678 | "Create a snippet from a template inserted at BEGIN to END. | 3763 | "Create a snippet from a template inserted at BEGIN to END. |
| @@ -3934,7 +4019,8 @@ Meant to be called in a narrowed buffer, does various passes" | |||
| 3934 | 4019 | ||
| 3935 | (defun yas--snapshot-marker-location (marker) | 4020 | (defun yas--snapshot-marker-location (marker) |
| 3936 | "Returns info for restoring MARKER's location after indent. | 4021 | "Returns info for restoring MARKER's location after indent. |
| 3937 | The returned value is a list of the form (REGEXP MARKER WS-COUNT)." | 4022 | The returned value is a list of the form (MARKER REGEXP WS-COUNT). |
| 4023 | If MARKER is not on current line, then return nil." | ||
| 3938 | (when (and (<= (line-beginning-position) marker) | 4024 | (when (and (<= (line-beginning-position) marker) |
| 3939 | (<= marker (line-end-position))) | 4025 | (<= marker (line-end-position))) |
| 3940 | (let ((before | 4026 | (let ((before |
| @@ -3943,33 +4029,60 @@ The returned value is a list of the form (REGEXP MARKER WS-COUNT)." | |||
| 3943 | (after | 4029 | (after |
| 3944 | (split-string (buffer-substring-no-properties | 4030 | (split-string (buffer-substring-no-properties |
| 3945 | marker (line-end-position)) "[[:space:]]+" t))) | 4031 | marker (line-end-position)) "[[:space:]]+" t))) |
| 3946 | (list (concat "[[:space:]]*" | 4032 | (list marker |
| 4033 | (concat "[[:space:]]*" | ||
| 3947 | (mapconcat (lambda (s) | 4034 | (mapconcat (lambda (s) |
| 3948 | (if (eq s marker) "\\(\\)" | 4035 | (if (eq s marker) "\\(\\)" |
| 3949 | (regexp-quote s))) | 4036 | (regexp-quote s))) |
| 3950 | (nconc before (list marker) after) | 4037 | (nconc before (list marker) after) |
| 3951 | "[[:space:]]*")) | 4038 | "[[:space:]]*")) |
| 3952 | marker | ||
| 3953 | (progn (goto-char marker) | 4039 | (progn (goto-char marker) |
| 3954 | (skip-syntax-forward " " (line-end-position)) | 4040 | (skip-syntax-forward " " (line-end-position)) |
| 3955 | (- (point) marker)))))) | 4041 | (- (point) marker)))))) |
| 3956 | 4042 | ||
| 4043 | (defun yas--snapshot-overlay-location (overlay) | ||
| 4044 | "Like `yas--snapshot-marker-location', but for overlays. | ||
| 4045 | The returned format is (OVERLAY (LINE RE WS) (LINE RE WS))." | ||
| 4046 | (let ((loc-beg (progn (goto-char (overlay-start overlay)) | ||
| 4047 | (yas--snapshot-marker-location (point)))) | ||
| 4048 | (loc-end (progn (goto-char (overlay-end overlay)) | ||
| 4049 | (yas--snapshot-marker-location (point))))) | ||
| 4050 | (setcar loc-beg (count-lines (point-min) (progn (goto-char (car loc-beg)) | ||
| 4051 | (line-beginning-position)))) | ||
| 4052 | (setcar loc-end (count-lines (point-min) (progn (goto-char (car loc-end)) | ||
| 4053 | (line-beginning-position)))) | ||
| 4054 | (list overlay loc-beg loc-end))) | ||
| 4055 | |||
| 4056 | (defun yas--goto-saved-location (regexp ws-count) | ||
| 4057 | "Move point to location saved by `yas--snapshot-marker-location'." | ||
| 4058 | (beginning-of-line) | ||
| 4059 | (save-restriction | ||
| 4060 | ;; Narrowing is the only way to limit `looking-at'. | ||
| 4061 | (narrow-to-region (point) (line-end-position)) | ||
| 4062 | (if (not (looking-at regexp)) | ||
| 4063 | (lwarn '(yasnippet re-marker) :warning | ||
| 4064 | "Couldn't find: %S" regexp) | ||
| 4065 | (goto-char (match-beginning 1)) | ||
| 4066 | (skip-syntax-forward " ") | ||
| 4067 | (skip-syntax-backward " " (- (point) ws-count))))) | ||
| 4068 | |||
| 3957 | (defun yas--restore-marker-location (re-marker) | 4069 | (defun yas--restore-marker-location (re-marker) |
| 3958 | "Restores marker based on info from `yas--snapshot-marker-location'." | 4070 | "Restores marker based on info from `yas--snapshot-marker-location'. |
| 3959 | (let ((regexp (nth 0 re-marker)) | 4071 | Assumes point is currently on the 'same' line as before." |
| 3960 | (marker (nth 1 re-marker)) | 4072 | (apply #'yas--goto-saved-location (cdr re-marker)) |
| 3961 | (ws-count (nth 2 re-marker))) | 4073 | (set-marker (car re-marker) (point))) |
| 3962 | (beginning-of-line) | 4074 | |
| 3963 | (save-restriction | 4075 | (defun yas--restore-overlay-location (ov-locations) |
| 3964 | ;; Narrowing is the only way to limit `looking-at'. | 4076 | "Restores overlay based on info from `yas--snapshot-overlay-location'." |
| 3965 | (narrow-to-region (point) (line-end-position)) | 4077 | (move-overlay (car ov-locations) |
| 3966 | (if (not (looking-at regexp)) | 4078 | (save-excursion |
| 3967 | (lwarn '(yasnippet re-marker) :warning | 4079 | (forward-line (car (nth 1 ov-locations))) |
| 3968 | "Couldn't find: %S" regexp) | 4080 | (apply #'yas--goto-saved-location (cdr (nth 1 ov-locations))) |
| 3969 | (goto-char (match-beginning 1)) | 4081 | (point)) |
| 3970 | (skip-syntax-forward " ") | 4082 | (save-excursion |
| 3971 | (skip-syntax-backward " " (- (point) ws-count)) | 4083 | (forward-line (car (nth 2 ov-locations))) |
| 3972 | (set-marker marker (point)))))) | 4084 | (apply #'yas--goto-saved-location (cdr (nth 2 ov-locations))) |
| 4085 | (point)))) | ||
| 3973 | 4086 | ||
| 3974 | (defun yas--indent-region (from to snippet) | 4087 | (defun yas--indent-region (from to snippet) |
| 3975 | "Indent the lines between FROM and TO with `indent-according-to-mode'. | 4088 | "Indent the lines between FROM and TO with `indent-according-to-mode'. |
| @@ -4021,16 +4134,7 @@ The SNIPPET's markers are preserved." | |||
| 4021 | (defun yas--collect-snippet-markers (snippet) | 4134 | (defun yas--collect-snippet-markers (snippet) |
| 4022 | "Make a list of all the markers used by SNIPPET." | 4135 | "Make a list of all the markers used by SNIPPET." |
| 4023 | (let (markers) | 4136 | (let (markers) |
| 4024 | (dolist (field (yas--snippet-fields snippet)) | 4137 | (yas--snippet-map-markers (lambda (m) (push m markers) m) snippet) |
| 4025 | (push (yas--field-start field) markers) | ||
| 4026 | (push (yas--field-end field) markers) | ||
| 4027 | (dolist (mirror (yas--field-mirrors field)) | ||
| 4028 | (push (yas--mirror-start mirror) markers) | ||
| 4029 | (push (yas--mirror-end mirror) markers))) | ||
| 4030 | (let ((snippet-exit (yas--snippet-exit snippet))) | ||
| 4031 | (when (and snippet-exit | ||
| 4032 | (marker-buffer (yas--exit-marker snippet-exit))) | ||
| 4033 | (push (yas--exit-marker snippet-exit) markers))) | ||
| 4034 | markers)) | 4138 | markers)) |
| 4035 | 4139 | ||
| 4036 | (defun yas--escape-string (escaped) | 4140 | (defun yas--escape-string (escaped) |
| @@ -4078,9 +4182,9 @@ with their evaluated value into `yas--backquote-markers-and-strings'." | |||
| 4078 | (delete-region (match-beginning 0) (match-end 0))) | 4182 | (delete-region (match-beginning 0) (match-end 0))) |
| 4079 | (let ((before-change-functions | 4183 | (let ((before-change-functions |
| 4080 | (cons detect-change before-change-functions))) | 4184 | (cons detect-change before-change-functions))) |
| 4081 | (setq transformed (yas--eval-lisp (yas--read-lisp | 4185 | (setq transformed (yas--eval-for-string (yas--read-lisp |
| 4082 | (yas--restore-escapes | 4186 | (yas--restore-escapes |
| 4083 | current-string '(?`)))))) | 4187 | current-string '(?`)))))) |
| 4084 | (goto-char (match-beginning 0)) | 4188 | (goto-char (match-beginning 0)) |
| 4085 | (when transformed | 4189 | (when transformed |
| 4086 | (let ((marker (make-marker)) | 4190 | (let ((marker (make-marker)) |
| @@ -4289,44 +4393,42 @@ When multiple expressions are found, only the last one counts." | |||
| 4289 | (save-restriction | 4393 | (save-restriction |
| 4290 | (widen) | 4394 | (widen) |
| 4291 | (save-excursion | 4395 | (save-excursion |
| 4292 | (dolist (field-and-mirror | 4396 | (cl-loop |
| 4293 | (sort | 4397 | for (field . mirror) |
| 4294 | ;; make a list of ((F1 . M1) (F1 . M2) (F2 . M3) (F2 . M4) ...) | 4398 | in (cl-sort |
| 4295 | ;; where F is the field that M is mirroring | 4399 | ;; Make a list of (FIELD . MIRROR). |
| 4296 | ;; | 4400 | (cl-mapcan (lambda (field) |
| 4297 | (cl-mapcan #'(lambda (field) | 4401 | (mapcar (lambda (mirror) |
| 4298 | (mapcar #'(lambda (mirror) | 4402 | (cons field mirror)) |
| 4299 | (cons field mirror)) | 4403 | (yas--field-mirrors field))) |
| 4300 | (cl-sort | 4404 | (yas--snippet-fields snippet)) |
| 4301 | (cl-copy-list | 4405 | ;; Then sort this list so that entries with mirrors with |
| 4302 | (yas--field-mirrors field)) | 4406 | ;; parent fields appear before. This was important for |
| 4303 | #'< | 4407 | ;; fixing #290, and also handles the case where a mirror in |
| 4304 | :key #'yas--mirror-start))) | 4408 | ;; a field causes another mirror to need reupdating. |
| 4305 | (yas--snippet-fields snippet)) | 4409 | #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm)))) |
| 4306 | ;; then sort this list so that entries with mirrors with parent | 4410 | ;; Before updating a mirror with a parent-field, maybe advance |
| 4307 | ;; fields appear before. This was important for fixing #290, and | 4411 | ;; its start (#290). |
| 4308 | ;; luckily also handles the case where a mirror in a field causes | 4412 | do (let ((parent-field (yas--mirror-parent-field mirror))) |
| 4309 | ;; another mirror to need reupdating | 4413 | (when parent-field |
| 4310 | ;; | 4414 | (yas--advance-start-maybe mirror (yas--fom-start parent-field)))) |
| 4311 | #'(lambda (field-and-mirror1 field-and-mirror2) | 4415 | ;; Update this mirror. |
| 4312 | (> (yas--calculate-mirror-depth (cdr field-and-mirror1)) | 4416 | do (yas--mirror-update-display mirror field snippet) |
| 4313 | (yas--calculate-mirror-depth (cdr field-and-mirror2)))))) | 4417 | ;; Delay indenting until we're done all mirrors. We must do |
| 4314 | (let* ((field (car field-and-mirror)) | 4418 | ;; this to avoid losing whitespace between fields that are |
| 4315 | (mirror (cdr field-and-mirror)) | 4419 | ;; still empty (i.e., they will be non-empty after updating). |
| 4316 | (parent-field (yas--mirror-parent-field mirror))) | 4420 | when (eq yas-indent-line 'auto) |
| 4317 | ;; before updating a mirror with a parent-field, maybe advance | 4421 | collect (cons (yas--mirror-start mirror) (yas--mirror-end mirror)) |
| 4318 | ;; its start (#290) | 4422 | into indent-regions |
| 4319 | ;; | 4423 | ;; `yas--place-overlays' is needed since the active field and |
| 4320 | (when parent-field | 4424 | ;; protected overlays might have been changed because of insertions |
| 4321 | (yas--advance-start-maybe mirror (yas--fom-start parent-field))) | 4425 | ;; in `yas--mirror-update-display'. |
| 4322 | ;; update this mirror | 4426 | do (let ((active-field (yas--snippet-active-field snippet))) |
| 4323 | ;; | 4427 | (when active-field (yas--place-overlays snippet active-field))) |
| 4324 | (yas--mirror-update-display mirror field snippet) | 4428 | finally do |
| 4325 | ;; `yas--place-overlays' is needed since the active field and | 4429 | (let ((yas--inhibit-overlay-hooks t)) |
| 4326 | ;; protected overlays might have been changed because of insertions | 4430 | (cl-loop for (beg . end) in (cl-sort indent-regions #'< :key #'car) |
| 4327 | ;; in `yas--mirror-update-display'. | 4431 | do (yas--indent-region beg end snippet))))))) |
| 4328 | (let ((active-field (yas--snippet-active-field snippet))) | ||
| 4329 | (when active-field (yas--place-overlays snippet active-field)))))))) | ||
| 4330 | 4432 | ||
| 4331 | (defun yas--mirror-update-display (mirror field snippet) | 4433 | (defun yas--mirror-update-display (mirror field snippet) |
| 4332 | "Update MIRROR according to FIELD (and mirror transform)." | 4434 | "Update MIRROR according to FIELD (and mirror transform)." |
| @@ -4347,12 +4449,7 @@ When multiple expressions are found, only the last one counts." | |||
| 4347 | (set-marker (yas--mirror-end mirror) (point)) | 4449 | (set-marker (yas--mirror-end mirror) (point)) |
| 4348 | (yas--advance-start-maybe (yas--mirror-next mirror) (point)) | 4450 | (yas--advance-start-maybe (yas--mirror-next mirror) (point)) |
| 4349 | ;; super-special advance | 4451 | ;; super-special advance |
| 4350 | (yas--advance-end-of-parents-maybe mirror-parent-field (point))) | 4452 | (yas--advance-end-of-parents-maybe mirror-parent-field (point)))))) |
| 4351 | (when (eq yas-indent-line 'auto) | ||
| 4352 | (let ((yas--inhibit-overlay-hooks t)) | ||
| 4353 | (yas--indent-region (yas--mirror-start mirror) | ||
| 4354 | (yas--mirror-end mirror) | ||
| 4355 | snippet)))))) | ||
| 4356 | 4453 | ||
| 4357 | (defun yas--field-update-display (field) | 4454 | (defun yas--field-update-display (field) |
| 4358 | "Much like `yas--mirror-update-display', but for fields." | 4455 | "Much like `yas--mirror-update-display', but for fields." |
| @@ -4377,6 +4474,7 @@ When multiple expressions are found, only the last one counts." | |||
| 4377 | ;; | 4474 | ;; |
| 4378 | (defun yas--post-command-handler () | 4475 | (defun yas--post-command-handler () |
| 4379 | "Handles various yasnippet conditions after each command." | 4476 | "Handles various yasnippet conditions after each command." |
| 4477 | (yas--finish-moving-snippets) | ||
| 4380 | (cond ((eq 'undo this-command) | 4478 | (cond ((eq 'undo this-command) |
| 4381 | ;; | 4479 | ;; |
| 4382 | ;; After undo revival the correct field is sometimes not | 4480 | ;; After undo revival the correct field is sometimes not |
