mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 13:13:03 +00:00
* per-snippet exit hook implemented as primary transformation of ${0:$$...()} field
* yas/snippet-revival is off by default, but should work * modified `yas/replace-backquotes' according to suggestion in Issue 139 * need to redo eval'ing of expand-env to correctly fix that issue
This commit is contained in:
parent
e50ae363b4
commit
2ccd85a726
78
yasnippet.el
78
yasnippet.el
@ -1266,8 +1266,8 @@ return an expression that when evaluated will issue an error."
|
|||||||
keybinding)))
|
keybinding)))
|
||||||
(read-kbd-macro keybinding-string 'need-vector))
|
(read-kbd-macro keybinding-string 'need-vector))
|
||||||
(error
|
(error
|
||||||
(message "[yas] warning: keybinding \"%s\" invalid for snippet \"%s\" since %s."
|
(message "[yas] warning: keybinding \"%s\" invalid since %s."
|
||||||
keybinding name (error-message-string err))
|
keybinding (error-message-string err))
|
||||||
nil))))
|
nil))))
|
||||||
|
|
||||||
(defvar yas/extra-modes nil
|
(defvar yas/extra-modes nil
|
||||||
@ -2575,8 +2575,8 @@ With optional prefix argument KILL quit the window and buffer."
|
|||||||
:expand-env (sixth parsed)))))
|
:expand-env (sixth parsed)))))
|
||||||
(cond (yas/current-template
|
(cond (yas/current-template
|
||||||
(let ((buffer-name (format "*testing snippet: %s*" (yas/template-name yas/current-template))))
|
(let ((buffer-name (format "*testing snippet: %s*" (yas/template-name yas/current-template))))
|
||||||
(set-buffer (switch-to-buffer buffer-name))
|
(kill-buffer (get-buffer-create buffer-name))
|
||||||
(erase-buffer)
|
(switch-to-buffer (get-buffer-create buffer-name))
|
||||||
(setq buffer-undo-list nil)
|
(setq buffer-undo-list nil)
|
||||||
(condition-case nil (funcall test-mode) (error nil))
|
(condition-case nil (funcall test-mode) (error nil))
|
||||||
(yas/expand-snippet (yas/template-content yas/current-template)
|
(yas/expand-snippet (yas/template-content yas/current-template)
|
||||||
@ -2618,7 +2618,7 @@ With optional prefix argument KILL quit the window and buffer."
|
|||||||
(while (and table-lists
|
(while (and table-lists
|
||||||
continue)
|
continue)
|
||||||
(dolist (table (car table-lists))
|
(dolist (table (car table-lists))
|
||||||
(yas/describe-pretty-table table))
|
(yas/describe-pretty-table table original-buffer))
|
||||||
(setq table-lists (cdr table-lists))
|
(setq table-lists (cdr table-lists))
|
||||||
(when table-lists
|
(when table-lists
|
||||||
(yas/create-snippet-xrefs)
|
(yas/create-snippet-xrefs)
|
||||||
@ -2646,7 +2646,7 @@ With optional prefix argument KILL quit the window and buffer."
|
|||||||
(setq buffer-read-only t))
|
(setq buffer-read-only t))
|
||||||
(display-buffer buffer)))
|
(display-buffer buffer)))
|
||||||
|
|
||||||
(defun yas/describe-pretty-table (table)
|
(defun yas/describe-pretty-table (table &optional original-buffer)
|
||||||
(insert (format "\nSnippet table `%s'"
|
(insert (format "\nSnippet table `%s'"
|
||||||
(yas/table-name table)))
|
(yas/table-name table)))
|
||||||
(if (yas/table-parents table)
|
(if (yas/table-parents table)
|
||||||
@ -2676,7 +2676,8 @@ With optional prefix argument KILL quit the window and buffer."
|
|||||||
(group (prog1 group
|
(group (prog1 group
|
||||||
(setq group (make-string (length group) ? ))))
|
(setq group (make-string (length group) ? ))))
|
||||||
(condition-string (let ((condition (yas/template-condition p)))
|
(condition-string (let ((condition (yas/template-condition p)))
|
||||||
(if condition
|
(if (and condition
|
||||||
|
original-buffer)
|
||||||
(with-current-buffer original-buffer
|
(with-current-buffer original-buffer
|
||||||
(if (yas/eval-condition condition)
|
(if (yas/eval-condition condition)
|
||||||
"(y)"
|
"(y)"
|
||||||
@ -2916,7 +2917,10 @@ have, compare through the field's start point"
|
|||||||
(and (zerop (- (yas/field-start field) (yas/field-end field)))
|
(and (zerop (- (yas/field-start field) (yas/field-end field)))
|
||||||
(or (yas/field-parent-field field)
|
(or (yas/field-parent-field field)
|
||||||
(and (eq field (car (last (yas/snippet-fields snippet))))
|
(and (eq field (car (last (yas/snippet-fields snippet))))
|
||||||
(= (yas/field-start field) (overlay-end (yas/snippet-control-overlay snippet)))))))
|
(= (yas/field-start field) (overlay-end (yas/snippet-control-overlay snippet)))))
|
||||||
|
;; the field numbered 0, just before the exit marker, should
|
||||||
|
;; never be skipped
|
||||||
|
(not (zerop (yas/field-number field)))))
|
||||||
|
|
||||||
(defun yas/snippets-at-point (&optional all-snippets)
|
(defun yas/snippets-at-point (&optional all-snippets)
|
||||||
"Return a sorted list of snippets at point, most recently
|
"Return a sorted list of snippets at point, most recently
|
||||||
@ -2984,14 +2988,18 @@ delegate to `yas/next-field'."
|
|||||||
|
|
||||||
Also create some protection overlays"
|
Also create some protection overlays"
|
||||||
(goto-char (yas/field-start field))
|
(goto-char (yas/field-start field))
|
||||||
(setf (yas/snippet-active-field snippet) field)
|
|
||||||
(yas/place-overlays snippet field)
|
(yas/place-overlays snippet field)
|
||||||
(overlay-put yas/active-field-overlay 'yas/field field)
|
(overlay-put yas/active-field-overlay 'yas/field field)
|
||||||
(let ((number (yas/field-number field)))
|
(let ((number (yas/field-number field)))
|
||||||
|
;; check for the special ${0: ...} field
|
||||||
(if (and number (zerop number))
|
(if (and number (zerop number))
|
||||||
(progn
|
(progn
|
||||||
(set-mark (yas/field-end field))
|
(set-mark (yas/field-end field))
|
||||||
(setf (yas/snippet-force-exit snippet) t))
|
(setf (yas/snippet-force-exit snippet)
|
||||||
|
(or (yas/field-transform field)
|
||||||
|
t)))
|
||||||
|
;; make this field active
|
||||||
|
(setf (yas/snippet-active-field snippet) field)
|
||||||
;; primary field transform: first call to snippet transform
|
;; primary field transform: first call to snippet transform
|
||||||
(unless (yas/field-modified-p field)
|
(unless (yas/field-modified-p field)
|
||||||
(if (yas/field-update-display field snippet)
|
(if (yas/field-update-display field snippet)
|
||||||
@ -3030,7 +3038,7 @@ Also create some protection overlays"
|
|||||||
|
|
||||||
;;; Some low level snippet-routines
|
;;; Some low level snippet-routines
|
||||||
|
|
||||||
(defun yas/commit-snippet (snippet &optional no-hooks)
|
(defun yas/commit-snippet (snippet)
|
||||||
"Commit SNIPPET, but leave point as it is. This renders the
|
"Commit SNIPPET, but leave point as it is. This renders the
|
||||||
snippet as ordinary text.
|
snippet as ordinary text.
|
||||||
|
|
||||||
@ -3077,30 +3085,24 @@ NO-HOOKS means don't run the `yas/after-exit-snippet-hook' hooks."
|
|||||||
buffer-undo-list)
|
buffer-undo-list)
|
||||||
;; Dismember the snippet... this is useful if we get called
|
;; Dismember the snippet... this is useful if we get called
|
||||||
;; again from `yas/take-care-of-redo'....
|
;; again from `yas/take-care-of-redo'....
|
||||||
(setf (yas/snippet-fields snippet) nil))
|
(setf (yas/snippet-fields snippet) nil)))
|
||||||
|
|
||||||
;; XXX: `yas/after-exit-snippet-hook' should be run with
|
(message "[yas] snippet %s exited." (yas/snippet-id snippet)))
|
||||||
;; `yas/snippet-beg' and `yas/snippet-end' bound. That might not
|
|
||||||
;; be the case if the main overlay had somehow already
|
|
||||||
;; disappeared, which sometimes happens when the snippet's messed
|
|
||||||
;; up...
|
|
||||||
;;
|
|
||||||
(unless no-hooks (run-hooks 'yas/after-exit-snippet-hook)))
|
|
||||||
|
|
||||||
(message "[yas] snippet exited."))
|
|
||||||
|
|
||||||
(defun yas/check-commit-snippet ()
|
(defun yas/check-commit-snippet ()
|
||||||
"Checks if point exited the currently active field of the
|
"Checks if point exited the currently active field of the
|
||||||
snippet, if so cleans up the whole snippet up."
|
snippet, if so cleans up the whole snippet up."
|
||||||
(let* ((snippets (yas/snippets-at-point 'all-snippets))
|
(let* ((snippets (yas/snippets-at-point 'all-snippets))
|
||||||
(snippets-left snippets))
|
(snippets-left snippets)
|
||||||
|
(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)))
|
||||||
(cond ((or (prog1 (yas/snippet-force-exit snippet)
|
(setq snippet-exit-transform (yas/snippet-force-exit snippet))
|
||||||
(setf (yas/snippet-force-exit snippet) nil))
|
(cond ((or snippet-exit-transform
|
||||||
(not (and active-field (yas/field-contains-point-p active-field))))
|
(not (and active-field (yas/field-contains-point-p active-field))))
|
||||||
(setq snippets-left (delete snippet snippets-left))
|
(setq snippets-left (delete snippet snippets-left))
|
||||||
(yas/commit-snippet snippet snippets-left))
|
(setf (yas/snippet-force-exit snippet) nil)
|
||||||
|
(yas/commit-snippet snippet))
|
||||||
((and active-field
|
((and active-field
|
||||||
(or (not yas/active-field-overlay)
|
(or (not yas/active-field-overlay)
|
||||||
(not (overlay-buffer yas/active-field-overlay))))
|
(not (overlay-buffer yas/active-field-overlay))))
|
||||||
@ -3116,7 +3118,10 @@ snippet, if so cleans up the whole snippet up."
|
|||||||
nil))))
|
nil))))
|
||||||
(unless snippets-left
|
(unless snippets-left
|
||||||
(remove-hook 'post-command-hook 'yas/post-command-handler 'local)
|
(remove-hook 'post-command-hook 'yas/post-command-handler 'local)
|
||||||
(remove-hook 'pre-command-hook 'yas/pre-command-handler 'local))))
|
(remove-hook 'pre-command-hook 'yas/pre-command-handler 'local)
|
||||||
|
(if snippet-exit-transform
|
||||||
|
(yas/eval-lisp-no-saves snippet-exit-transform)
|
||||||
|
(run-hooks 'yas/after-exit-snippet-hook)))))
|
||||||
|
|
||||||
;; Apropos markers-to-points:
|
;; Apropos markers-to-points:
|
||||||
;;
|
;;
|
||||||
@ -3400,8 +3405,8 @@ considered when expanding the snippet."
|
|||||||
(let ((to-delete (and start end (buffer-substring-no-properties start end)))
|
(let ((to-delete (and start end (buffer-substring-no-properties start end)))
|
||||||
(start (or start (point)))
|
(start (or start (point)))
|
||||||
(end (or end (point)))
|
(end (or end (point)))
|
||||||
(column (current-column))
|
|
||||||
snippet)
|
snippet)
|
||||||
|
(setq yas/indent-original-column (current-column))
|
||||||
;; Delete the region to delete, this *does* get undo-recorded.
|
;; Delete the region to delete, this *does* get undo-recorded.
|
||||||
;;
|
;;
|
||||||
(when (and to-delete
|
(when (and to-delete
|
||||||
@ -3490,7 +3495,7 @@ Meant to exit in the `buffer-undo-list'."
|
|||||||
;; slightly optimize: this action is only needed for snippets with
|
;; slightly optimize: this action is only needed for snippets with
|
||||||
;; at least one field
|
;; at least one field
|
||||||
(when (yas/snippet-fields snippet)
|
(when (yas/snippet-fields snippet)
|
||||||
(yas/commit-snippet snippet 'no-hooks)))
|
(yas/commit-snippet snippet)))
|
||||||
|
|
||||||
(defun yas/snippet-revive (beg end snippet)
|
(defun yas/snippet-revive (beg end snippet)
|
||||||
"Revives the SNIPPET and creates a control overlay from BEG to
|
"Revives the SNIPPET and creates a control overlay from BEG to
|
||||||
@ -3775,6 +3780,7 @@ SNIPPET-MARKERS."
|
|||||||
(set-marker marker (point)))
|
(set-marker marker (point)))
|
||||||
trouble-markers)))
|
trouble-markers)))
|
||||||
|
|
||||||
|
(defvar yas/indent-original-column nil)
|
||||||
(defun yas/indent (snippet)
|
(defun yas/indent (snippet)
|
||||||
(let ((snippet-markers (yas/collect-snippet-markers snippet)))
|
(let ((snippet-markers (yas/collect-snippet-markers snippet)))
|
||||||
;; Look for those $>
|
;; Look for those $>
|
||||||
@ -3788,7 +3794,7 @@ SNIPPET-MARKERS."
|
|||||||
(cond ((eq yas/indent-line 'fixed)
|
(cond ((eq yas/indent-line 'fixed)
|
||||||
(while (and (zerop (forward-line))
|
(while (and (zerop (forward-line))
|
||||||
(zerop (current-column)))
|
(zerop (current-column)))
|
||||||
(indent-to-column column)))
|
(indent-to-column yas/indent-original-column)))
|
||||||
((eq yas/indent-line 'auto)
|
((eq yas/indent-line 'auto)
|
||||||
(let ((end (set-marker (make-marker) (point-max)))
|
(let ((end (set-marker (make-marker) (point-max)))
|
||||||
(indent-first-line-p yas/also-auto-indent-first-line))
|
(indent-first-line-p yas/also-auto-indent-first-line))
|
||||||
@ -3860,12 +3866,13 @@ With optional string TEXT do it in string instead of the buffer."
|
|||||||
|
|
||||||
(defun yas/replace-backquotes ()
|
(defun yas/replace-backquotes ()
|
||||||
"Replace all the \"`(lisp-expression)`\"-style expression
|
"Replace all the \"`(lisp-expression)`\"-style expression
|
||||||
with their evaluated value"
|
with their evaluated value"
|
||||||
(while (re-search-forward yas/backquote-lisp-expression-regexp nil t)
|
(while (re-search-forward yas/backquote-lisp-expression-regexp nil t)
|
||||||
(let ((transformed (yas/eval-lisp (yas/read-lisp (yas/restore-escapes (match-string 1))))))
|
(let ((current-string (match-string 1)) transformed)
|
||||||
(goto-char (match-end 0))
|
(delete-region (match-beginning 0) (match-end 0))
|
||||||
(when transformed (insert transformed))
|
(setq transformed (yas/eval-lisp (yas/read-lisp (yas/restore-escapes current-string))))
|
||||||
(delete-region (match-beginning 0) (match-end 0)))))
|
(goto-char (match-beginning 0))
|
||||||
|
(when transformed (insert transformed)))))
|
||||||
|
|
||||||
(defun yas/scan-sexps (from count)
|
(defun yas/scan-sexps (from count)
|
||||||
(condition-case err
|
(condition-case err
|
||||||
@ -4078,7 +4085,8 @@ When multiple expressions are found, only the last one counts."
|
|||||||
"Much like `yas/mirror-update-display', but for fields"
|
"Much like `yas/mirror-update-display', but for fields"
|
||||||
(when (yas/field-transform field)
|
(when (yas/field-transform field)
|
||||||
(let ((inhibit-modification-hooks t)
|
(let ((inhibit-modification-hooks t)
|
||||||
(transformed (yas/apply-transform field field))
|
(transformed (and (not (eq (yas/field-number field) 0))
|
||||||
|
(yas/apply-transform field field)))
|
||||||
(point (point)))
|
(point (point)))
|
||||||
(when (and transformed
|
(when (and transformed
|
||||||
(not (string= transformed (buffer-substring-no-properties (yas/field-start field)
|
(not (string= transformed (buffer-substring-no-properties (yas/field-start field)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user