Don't use overlays to find active snippets

* yasnippet.el (yas--active-snippets): New buffer-local variable.
(yas-active-snippets): Use it, when asked for all active snippets.
(yas--commit-snippet): Remove finished snippet from list of active
snippets.
(yas--snippet-create): Add new snippet to list of active snippets.
(yas--check-commit-snippet): Consult list of active snippetes.
This commit is contained in:
Noam Postavsky 2018-04-10 22:30:15 -04:00
parent 4af33546d8
commit e67592ce1b

View File

@ -3070,6 +3070,10 @@ other fields."
(defvar yas--active-field-overlay nil
"Overlays the currently active field.")
(defvar yas--active-snippets nil
"List of currently active snippets")
(make-variable-buffer-local 'yas--active-snippets)
(defvar yas--field-protection-overlays nil
"Two overlays protect the current active field.")
@ -3273,19 +3277,19 @@ equivalent to a range covering the whole buffer."
(setq beg (point-min) end (point-max)))
((not end)
(setq end (1+ beg))))
;; Note: don't use `mapcar' here, since it would allocate in
;; proportion to the amount of overlays, even though the list of
;; active snippets should be very small. That is important because
;; this function is called in the post-command hook (via
;; `yas--check-commit-snippet').
(let ((snippets nil))
(dolist (ov (overlays-in beg end))
(let ((snippet (overlay-get ov 'yas--snippet)))
;; Snippets have multiple overlays, so check for dups.
(when (and snippet (not (memq snippet snippets)))
(push snippet snippets))))
(cl-sort snippets #'>= :key #'yas--snippet-id)))
(if (and (eq beg (point-min))
(eq end (point-max)))
yas--active-snippets
;; Note: don't use `mapcar' here, since it would allocate in
;; proportion to the amount of overlays, even though the list of
;; active snippets should be very small.
(let ((snippets nil))
(dolist (ov (overlays-in beg end))
(let ((snippet (overlay-get ov 'yas--snippet)))
;; Snippets have multiple overlays, so check for dups.
(when (and snippet (not (memq snippet snippets)))
(push snippet snippets))))
(cl-sort snippets #'>= :key #'yas--snippet-id))))
(define-obsolete-function-alias 'yas--snippets-at-point
'yas-active-snippets "0.12")
@ -3445,6 +3449,9 @@ This renders the snippet as ordinary text."
;;
(yas--markers-to-points snippet)
;; It's no longer an active snippet.
(cl-callf2 delq snippet yas--active-snippets)
;; Take care of snippet revival on undo.
(if (and yas-snippet-revival (listp buffer-undo-list))
(push `(apply yas--snippet-revive ,yas-snippet-beg ,yas-snippet-end ,snippet)
@ -3538,13 +3545,12 @@ HOOK should be a symbol, a hook variable, as in `run-hooks'."
"Check if point exited the currently active field of the snippet.
If so cleans up the whole snippet up."
(let* ((snippets (yas-active-snippets 'all))
(snippets-left snippets)
(snippet-exit-transform)
(let* ((snippet-exit-transform nil)
(exited-snippets-p nil)
;; Record the custom snippet `yas-after-exit-snippet-hook'
;; set in the expand-env field.
(snippet-exit-hook yas-after-exit-snippet-hook))
(dolist (snippet snippets)
(dolist (snippet yas--active-snippets)
(let ((active-field (yas--snippet-active-field snippet)))
(yas--letenv (yas--snippet-expand-env snippet)
;; Note: the `force-exit' field could be a transform in case of
@ -3552,10 +3558,10 @@ If so cleans up the whole snippet up."
(setq snippet-exit-transform (yas--snippet-force-exit snippet))
(cond ((or snippet-exit-transform
(not (and active-field (yas--field-contains-point-p active-field))))
(setq snippets-left (delete snippet snippets-left))
(setf (yas--snippet-force-exit snippet) nil)
(setq snippet-exit-hook yas-after-exit-snippet-hook)
(yas--commit-snippet snippet))
(yas--commit-snippet snippet)
(setq exited-snippets-p t))
((and active-field
(or (not yas--active-field-overlay)
(not (overlay-buffer yas--active-field-overlay))))
@ -3569,7 +3575,7 @@ If so cleans up the whole snippet up."
(yas--update-mirrors snippet)))
(t
nil)))))
(unless (or (null snippets) snippets-left)
(unless (or yas--active-snippets (not exited-snippets-p))
(when snippet-exit-transform
(yas--eval-for-effect snippet-exit-transform))
(let ((yas-after-exit-snippet-hook snippet-exit-hook))
@ -4062,6 +4068,7 @@ Returns the newly created snippet."
;; Move to end
(goto-char (point-max))
(push snippet yas--active-snippets)
snippet))))