mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 21:13:04 +00:00
Use expand-env for all snippet evaluations
* yasnippet.el (yas--snippet): New field, expand-env. (yas--letenv): New macro, evaluate body with a given environment. (yas--find-next-field, yas--safely-run-hooks): (yas--on-field-overlay-modification): (yas-expand-snippet, yas--snippet-create): Use it.
This commit is contained in:
parent
5534cab0b7
commit
4ee3835adf
117
yasnippet.el
117
yasnippet.el
@ -2902,10 +2902,11 @@ Use this in primary and mirror transformations to tget."
|
|||||||
(put 'yas--active-field-overlay 'permanent-local t)
|
(put 'yas--active-field-overlay 'permanent-local t)
|
||||||
(put 'yas--field-protection-overlays 'permanent-local t)
|
(put 'yas--field-protection-overlays 'permanent-local t)
|
||||||
|
|
||||||
(cl-defstruct (yas--snippet (:constructor yas--make-snippet ()))
|
(cl-defstruct (yas--snippet (:constructor yas--make-snippet (expand-env)))
|
||||||
"A snippet.
|
"A snippet.
|
||||||
|
|
||||||
..."
|
..."
|
||||||
|
expand-env
|
||||||
(fields '())
|
(fields '())
|
||||||
(exit nil)
|
(exit nil)
|
||||||
(id (yas--snippet-next-id) :read-only t)
|
(id (yas--snippet-next-id) :read-only t)
|
||||||
@ -2954,6 +2955,12 @@ DEPTH is a count of how many nested mirrors can affect this mirror"
|
|||||||
marker
|
marker
|
||||||
next)
|
next)
|
||||||
|
|
||||||
|
(defmacro yas--letenv (env &rest body)
|
||||||
|
"Evaluate BODY with bindings from ENV.
|
||||||
|
ENV is a list of elements with the form (VAR FORM)."
|
||||||
|
(declare (debug (form body)) (indent 1))
|
||||||
|
`(eval (cl-list* 'let* ,env ',body)))
|
||||||
|
|
||||||
(defun yas--apply-transform (field-or-mirror field &optional empty-on-nil-p)
|
(defun yas--apply-transform (field-or-mirror field &optional empty-on-nil-p)
|
||||||
"Calculate transformed string for FIELD-OR-MIRROR from FIELD.
|
"Calculate transformed string for FIELD-OR-MIRROR from FIELD.
|
||||||
|
|
||||||
@ -3102,15 +3109,16 @@ If there's none, exit the snippet."
|
|||||||
(let* ((snippet (car (yas-active-snippets)))
|
(let* ((snippet (car (yas-active-snippets)))
|
||||||
(active-field (overlay-get yas--active-field-overlay 'yas--field))
|
(active-field (overlay-get yas--active-field-overlay 'yas--field))
|
||||||
(target-field (yas--find-next-field arg snippet active-field)))
|
(target-field (yas--find-next-field arg snippet active-field)))
|
||||||
;; Apply transform to active field.
|
(yas--letenv (yas--snippet-expand-env snippet)
|
||||||
(when active-field
|
;; Apply transform to active field.
|
||||||
(let ((yas-moving-away-p t))
|
(when active-field
|
||||||
(when (yas--field-update-display active-field)
|
(let ((yas-moving-away-p t))
|
||||||
(yas--update-mirrors snippet))))
|
(when (yas--field-update-display active-field)
|
||||||
;; Now actually move...
|
(yas--update-mirrors snippet))))
|
||||||
(if target-field
|
;; Now actually move...
|
||||||
(yas--move-to-field snippet target-field)
|
(if target-field
|
||||||
(yas-exit-snippet snippet))))
|
(yas--move-to-field snippet target-field)
|
||||||
|
(yas-exit-snippet snippet)))))
|
||||||
|
|
||||||
(defun yas--place-overlays (snippet field)
|
(defun yas--place-overlays (snippet field)
|
||||||
"Correctly place overlays for SNIPPET's FIELD."
|
"Correctly place overlays for SNIPPET's FIELD."
|
||||||
@ -3239,25 +3247,26 @@ If so cleans up the whole snippet up."
|
|||||||
(snippet-exit-transform))
|
(snippet-exit-transform))
|
||||||
(dolist (snippet snippets)
|
(dolist (snippet snippets)
|
||||||
(let ((active-field (yas--snippet-active-field snippet)))
|
(let ((active-field (yas--snippet-active-field snippet)))
|
||||||
(setq snippet-exit-transform (yas--snippet-force-exit snippet))
|
(yas--letenv (yas--snippet-expand-env snippet)
|
||||||
(cond ((or snippet-exit-transform
|
(setq snippet-exit-transform (yas--snippet-force-exit snippet))
|
||||||
(not (and active-field (yas--field-contains-point-p active-field))))
|
(cond ((or snippet-exit-transform
|
||||||
(setq snippets-left (delete snippet snippets-left))
|
(not (and active-field (yas--field-contains-point-p active-field))))
|
||||||
(setf (yas--snippet-force-exit snippet) nil)
|
(setq snippets-left (delete snippet snippets-left))
|
||||||
(yas--commit-snippet snippet))
|
(setf (yas--snippet-force-exit snippet) nil)
|
||||||
((and active-field
|
(yas--commit-snippet snippet))
|
||||||
(or (not yas--active-field-overlay)
|
((and active-field
|
||||||
(not (overlay-buffer yas--active-field-overlay))))
|
(or (not yas--active-field-overlay)
|
||||||
;;
|
(not (overlay-buffer yas--active-field-overlay))))
|
||||||
;; stacked expansion: this case is mainly for recent
|
;;
|
||||||
;; snippet exits that place us back int the field of
|
;; stacked expansion: this case is mainly for recent
|
||||||
;; another snippet
|
;; snippet exits that place us back int the field of
|
||||||
;;
|
;; another snippet
|
||||||
(save-excursion
|
;;
|
||||||
(yas--move-to-field snippet active-field)
|
(save-excursion
|
||||||
(yas--update-mirrors snippet)))
|
(yas--move-to-field snippet active-field)
|
||||||
(t
|
(yas--update-mirrors snippet)))
|
||||||
nil))))
|
(t
|
||||||
|
nil)))))
|
||||||
(unless (or (null snippets) snippets-left)
|
(unless (or (null snippets) snippets-left)
|
||||||
(if snippet-exit-transform
|
(if snippet-exit-transform
|
||||||
(yas--eval-lisp-no-saves snippet-exit-transform))
|
(yas--eval-lisp-no-saves snippet-exit-transform))
|
||||||
@ -3428,14 +3437,15 @@ field start. This hook does nothing if an undo is in progress."
|
|||||||
(field (overlay-get overlay 'yas--field))
|
(field (overlay-get overlay 'yas--field))
|
||||||
(snippet (overlay-get yas--active-field-overlay 'yas--snippet)))
|
(snippet (overlay-get yas--active-field-overlay 'yas--snippet)))
|
||||||
(save-match-data
|
(save-match-data
|
||||||
(when (yas--skip-and-clear-field-p field beg end length)
|
(yas--letenv (yas--snippet-expand-env snippet)
|
||||||
;; We delete text starting from the END of insertion.
|
(when (yas--skip-and-clear-field-p field beg end length)
|
||||||
(yas--skip-and-clear field end))
|
;; We delete text starting from the END of insertion.
|
||||||
(setf (yas--field-modified-p field) t)
|
(yas--skip-and-clear field end))
|
||||||
(yas--advance-end-maybe field (overlay-end overlay))
|
(setf (yas--field-modified-p field) t)
|
||||||
(save-excursion
|
(yas--advance-end-maybe field (overlay-end overlay))
|
||||||
(yas--field-update-display field))
|
(save-excursion
|
||||||
(yas--update-mirrors snippet)))))
|
(yas--field-update-display field))
|
||||||
|
(yas--update-mirrors snippet))))))
|
||||||
|
|
||||||
;;; Apropos protection overlays:
|
;;; Apropos protection overlays:
|
||||||
;;
|
;;
|
||||||
@ -3582,13 +3592,9 @@ considered when expanding the snippet."
|
|||||||
;; insert things that are not valid in the
|
;; insert things that are not valid in the
|
||||||
;; major-mode language syntax anyway.
|
;; major-mode language syntax anyway.
|
||||||
(syntax-propertize-function nil))
|
(syntax-propertize-function nil))
|
||||||
|
(insert content)
|
||||||
(setq snippet
|
(setq snippet
|
||||||
(if expand-env
|
(yas--snippet-create expand-env start (point))))
|
||||||
(eval `(let* ,expand-env
|
|
||||||
(insert content)
|
|
||||||
(yas--snippet-create start (point))))
|
|
||||||
(insert content)
|
|
||||||
(yas--snippet-create start (point)))))
|
|
||||||
;; Invalidate any syntax-propertizing done while `syntax-propertize-function' was nil
|
;; Invalidate any syntax-propertizing done while `syntax-propertize-function' was nil
|
||||||
(syntax-ppss-flush-cache start))
|
(syntax-ppss-flush-cache start))
|
||||||
|
|
||||||
@ -3668,27 +3674,28 @@ After revival, push the `yas--take-care-of-redo' in the
|
|||||||
(push `(apply yas--take-care-of-redo ,beg ,end ,snippet)
|
(push `(apply yas--take-care-of-redo ,beg ,end ,snippet)
|
||||||
buffer-undo-list))))
|
buffer-undo-list))))
|
||||||
|
|
||||||
(defun yas--snippet-create (begin end)
|
(defun yas--snippet-create (expand-env begin end)
|
||||||
"Create a snippet from a template inserted at BEGIN to END.
|
"Create a snippet from a template inserted at BEGIN to END.
|
||||||
|
|
||||||
Returns the newly created snippet."
|
Returns the newly created snippet."
|
||||||
(save-restriction
|
(save-restriction
|
||||||
(narrow-to-region begin end)
|
(narrow-to-region begin end)
|
||||||
(let ((snippet (yas--make-snippet)))
|
(let ((snippet (yas--make-snippet expand-env)))
|
||||||
(goto-char begin)
|
(yas--letenv expand-env
|
||||||
(yas--snippet-parse-create snippet)
|
(goto-char begin)
|
||||||
|
(yas--snippet-parse-create snippet)
|
||||||
|
|
||||||
;; Sort and link each field
|
;; Sort and link each field
|
||||||
(yas--snippet-sort-fields snippet)
|
(yas--snippet-sort-fields snippet)
|
||||||
|
|
||||||
;; Create keymap overlay for snippet
|
;; Create keymap overlay for snippet
|
||||||
(setf (yas--snippet-control-overlay snippet)
|
(setf (yas--snippet-control-overlay snippet)
|
||||||
(yas--make-control-overlay snippet (point-min) (point-max)))
|
(yas--make-control-overlay snippet (point-min) (point-max)))
|
||||||
|
|
||||||
;; Move to end
|
;; Move to end
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
|
|
||||||
snippet)))
|
snippet))))
|
||||||
|
|
||||||
|
|
||||||
;;; Apropos adjacencies and "fom's":
|
;;; Apropos adjacencies and "fom's":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user