summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimeon Simeonov2017-02-21 08:27:23 +0100
committerSimeon Simeonov2017-02-21 08:27:23 +0100
commit6c9184e45865406de1df73a5b352df16fb55a6dd (patch)
treef6c552dff9a5cc9f9bdbb7a0d58ee4ad3b4179d6
parentd09417873b51c525cdea37fb8d165ae28da4e97a (diff)
Update php-mode.el, yaml-mode.el and yasnippet.el
-rw-r--r--.emacs.d/lisp/php-mode.el19
-rw-r--r--.emacs.d/lisp/yaml-mode.el2
-rw-r--r--.emacs.d/lisp/yasnippet.el532
-rw-r--r--.emacs.d/snippets/python-mode/__new__8
4 files changed, 335 insertions, 226 deletions
diff --git a/.emacs.d/lisp/php-mode.el b/.emacs.d/lisp/php-mode.el
index 4284d43..cd35d7d 100644
--- a/.emacs.d/lisp/php-mode.el
+++ b/.emacs.d/lisp/php-mode.el
@@ -6,13 +6,13 @@
6 6
7;; Author: Eric James Michael Ritz 7;; Author: Eric James Michael Ritz
8;; URL: https://github.com/ejmr/php-mode 8;; URL: https://github.com/ejmr/php-mode
9;; Version: 1.18.0 9;; Version: 1.18.2
10;; Package-Requires: ((emacs "24") (cl-lib "0.5")) 10;; Package-Requires: ((emacs "24") (cl-lib "0.5"))
11 11
12(defconst php-mode-version-number "1.18.0" 12(defconst php-mode-version-number "1.18.2"
13 "PHP Mode version number.") 13 "PHP Mode version number.")
14 14
15(defconst php-mode-modified "2017-01-27" 15(defconst php-mode-modified "2017-02-20"
16 "PHP Mode build date.") 16 "PHP Mode build date.")
17 17
18;;; License 18;;; License
@@ -523,6 +523,9 @@ PHP does not have an \"enum\"-like keyword."
523 php '("function" 523 php '("function"
524 "use")) 524 "use"))
525 525
526(c-lang-defconst c-other-block-decl-kwds
527 php '("namespace"))
528
526(c-lang-defconst c-other-kwds 529(c-lang-defconst c-other-kwds
527 "Keywords not accounted for by any other `*-kwds' language constant." 530 "Keywords not accounted for by any other `*-kwds' language constant."
528 php '( 531 php '(
@@ -608,11 +611,12 @@ but only if the setting is enabled"
608 (arglist-cont-nonempty . (first php-lineup-cascaded-calls c-lineup-arglist)) 611 (arglist-cont-nonempty . (first php-lineup-cascaded-calls c-lineup-arglist))
609 (arglist-intro . php-lineup-arglist-intro) 612 (arglist-intro . php-lineup-arglist-intro)
610 (case-label . +) 613 (case-label . +)
611 (class-open . -) 614 (class-open . 0)
612 (comment-intro . 0) 615 (comment-intro . 0)
613 (inlambda . 0) 616 (inlambda . 0)
614 (lambda-intro-cont . +)
615 (inline-open . 0) 617 (inline-open . 0)
618 (namespace-open . 0)
619 (lambda-intro-cont . +)
616 (label . +) 620 (label . +)
617 (statement-cont . (first php-lineup-cascaded-calls php-lineup-string-cont +)) 621 (statement-cont . (first php-lineup-cascaded-calls php-lineup-string-cont +))
618 (substatement-open . 0) 622 (substatement-open . 0)
@@ -1349,11 +1353,10 @@ a completion list."
1349 (,(rx "$" (in "A-Za-z_") (* (in "0-9A-Za-z_"))) 1353 (,(rx "$" (in "A-Za-z_") (* (in "0-9A-Za-z_")))
1350 0 font-lock-variable-name-face prepend nil) 1354 0 font-lock-variable-name-face prepend nil)
1351 (,(concat "\\s-@" (regexp-opt php-phpdoc-type-tags) "\\s-+" 1355 (,(concat "\\s-@" (regexp-opt php-phpdoc-type-tags) "\\s-+"
1352 "\\(" (rx (+ (? "\\") (+ (in "0-9A-Za-z")) (? "[]") (? "|"))) "\\)+" 1356 "\\(" (rx (+ (? "\\") (+ (in "0-9A-Z_a-z")) (? "[]") (? "|"))) "\\)+")
1353 "\\(?:\\s-\\|$\\)")
1354 1 font-lock-string-face prepend nil) 1357 1 font-lock-string-face prepend nil)
1355 (,(concat "\\(?:|\\|\\s-\\)\\(" 1358 (,(concat "\\(?:|\\|\\s-\\)\\("
1356 (regexp-opt php-phpdoc-type-keywords) 1359 (regexp-opt php-phpdoc-type-keywords 'words)
1357 "\\)") 1360 "\\)")
1358 1 font-lock-type-face prepend nil) 1361 1 font-lock-type-face prepend nil)
1359 ("https?://[^\n\t ]+" 1362 ("https?://[^\n\t ]+"
diff --git a/.emacs.d/lisp/yaml-mode.el b/.emacs.d/lisp/yaml-mode.el
index 44650be..615de6f 100644
--- a/.emacs.d/lisp/yaml-mode.el
+++ b/.emacs.d/lisp/yaml-mode.el
@@ -426,7 +426,7 @@ cross boundaries of block literals."
426 426
427 427
428(defun yaml-mode-version () 428(defun yaml-mode-version ()
429 "Diplay version of `yaml-mode'." 429 "Display version of `yaml-mode'."
430 (interactive) 430 (interactive)
431 (message "yaml-mode %s" yaml-mode-version) 431 (message "yaml-mode %s" yaml-mode-version)
432 yaml-mode-version) 432 yaml-mode-version)
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
271next field" 271next 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 276Now that the conditional keybinding `yas-maybe-expand' is
277- `call-other-command' means try to temporarily disable YASnippet 277available, 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
284command value `yas-maybe-expand', for `return-nil' behavior bind
285directly 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
345This affects both the inline elisp in snippets and the hook
346variables such as `yas-after-exit-snippet-hook'.
346 347
347An error string \"[yas] error\" is returned instead." 348If this variable's value is `inline', an error string \"[yas]
349error\" is returned instead of raising the error. If this
350variable's value is `hooks', a message is output to according to
351`yas-verbosity-level'. If this variable's value is t, both are
352active."
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.
467To 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
463This variable is a Lisp form which is evaluated every time a 472This 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
509The default value is similar, it filters out potential snippet 518 `(choice
510expansions inside comments and string literals, unless the 519 (const :tag "Disable snippet expansion inside strings and comments"
511snippet 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.
581This 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
583expanded.")
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
704Its elements looks like (TABLE-NAME . KEYMAP). They're 726Its elements looks like (TABLE-NAME . KEYMAP). They're
705instantiated on `yas-reload-all' but KEYMAP is added to only when 727instantiated on `yas-reload-all' but KEYMAP is added to only when
706loading snippets. `yas--direct-TABLE-NAME' is then a variable set 728loading snippets. `yas--direct-TABLE-NAME' is then a variable
707buffer-locally when entering `yas-minor-mode'. KEYMAP binds all 729set buffer-locally when entering `yas-minor-mode'. KEYMAP binds
708defined direct keybindings to the command 730all defined direct keybindings to `yas-maybe-expand-from-keymap'
709`yas-expand-from-keymap' which then which snippet to expand.") 731which 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'.
934Meaning 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
1639CONDITION, EXPAND-ENV and KEYBINDING are Lisp forms, they have 1669CONDITION, EXPAND-ENV and KEYBINDING are Lisp forms, they have
1640been `yas--read-lisp'-ed and will eventually be 1670been `yas--read-lisp'-ed and will eventually be
1641`yas--eval-lisp'-ed. 1671`yas--eval-for-string'-ed.
1642 1672
1643The remaining elements are strings. 1673The 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
2173If 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 2866Otherwise signal `yas-exception'."
2836Otherwise 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.
2995Update 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."
3244If so cleans up the whole snippet up." 3355If 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."
3289where POINT is the original position of the marker and MARKER is 3402 (yas--snippet-map-markers (lambda (m)
3290the 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
3314This 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*.
3658After revival, push the `yas--take-care-of-redo' in the 3750After 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.
3937The returned value is a list of the form (REGEXP MARKER WS-COUNT)." 4022The returned value is a list of the form (MARKER REGEXP WS-COUNT).
4023If 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.
4045The 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)) 4071Assumes 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
diff --git a/.emacs.d/snippets/python-mode/__new__ b/.emacs.d/snippets/python-mode/__new__
new file mode 100644
index 0000000..8ccb151
--- /dev/null
+++ b/.emacs.d/snippets/python-mode/__new__
@@ -0,0 +1,8 @@
1# -*- mode: snippet -*-
2# name: __new__
3# key: new
4# group: dunder methods
5# --
6def __new__(mcs, name, bases, dct):
7 $0
8 return type.__new__(mcs, name, bases, dct)