branch: externals/tempel commit e51f87cff720130f952a3bc32f44cf07060d8359 Author: Fritz Grabo <fritz.gr...@gmail.com> Commit: GitHub <nore...@github.com>
Evaluate `:post` callback at template finalization (vs. post expansion) (#53) --- README.org | 13 +++++++------ tempel.el | 25 ++++++++++++++++++------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/README.org b/README.org index b91704b082..82b31eb002 100644 --- a/README.org +++ b/README.org @@ -105,9 +105,12 @@ The templates are defined in a Lisp file configured by ~tempel-path~. By default the file =~/.config/emacs/templates= is used. The templates are grouped by major mode with an optional ~:when~ condition. Each template is a list in the concise form of the Emacs Tempo syntax. The first element of each list is the name of the -template. Behind the name, the Tempo syntax elements follow. Pre- and -post-expansion operations can be specified per template by the optional keys -=:pre= and =:post=. +template. Behind the name, the Tempo syntax elements follow. + +In addition, each template may specify a =:pre= and/or =:post= key with a FORM that is +evaluated before the template is expanded or after it is finalized, respectively. The +=:post= form is evaluated in the lexical scope of the template, which means that it can +access the template's named fields. #+begin_src emacs-lisp fundamental-mode ;; Available everywhere @@ -207,14 +210,12 @@ post-expansion operations can be specified per template by the optional keys (comment "#+begin_comment" n> r> n> "#+end_comment") (verse "#+begin_verse" n> r> n> "#+end_verse") (src "#+begin_src " p n> r> n> "#+end_src") - (elisp "#+begin_src emacs-lisp" n> r> n "#+end_src" - :post (progn (tempel-done) (org-edit-src-code))) + (elisp "#+begin_src emacs-lisp" n> r> n "#+end_src" :post (org-edit-src-code)) ;; Local Variables: ;; mode: lisp-data ;; outline-regexp: "[a-z]" ;; End: - #+end_src * Template syntax diff --git a/tempel.el b/tempel.el index 4efe8e9ee0..251615c790 100644 --- a/tempel.el +++ b/tempel.el @@ -379,18 +379,18 @@ If a field was added, return it." (push range (car st)) (overlay-put range 'modification-hooks (list #'tempel--range-modified)) (overlay-put range 'tempel--range st) + (overlay-put range 'tempel--post (plist-get plist :post)) ;;(overlay-put range 'face 'region) ;; TODO debug (push st tempel--active))) (cond ((cl-loop for ov in (caar tempel--active) never (overlay-get ov 'tempel--field)) (goto-char (overlay-end (caaar tempel--active))) - (tempel--disable)) ;; Disable right away + (tempel--done)) ;; Finalize right away ((cl-loop for ov in (caar tempel--active) never (and (overlay-get ov 'tempel--field) (eq (point) (overlay-start ov)))) - (tempel-next 1))) ;; Jump to first field - (eval (plist-get plist :post) 'lexical))) + (tempel-next 1))))) ;; Jump to first field (defun tempel--save () "Prompt to save modified files in `tempel-path'." @@ -538,7 +538,7 @@ This is meant to be a source in `tempel-template-sources'." ;; containing template right away. (when-let* ((ov (tempel--field-at-point)) ((overlay-get ov 'tempel--quit))) - (tempel--disable (overlay-get ov 'tempel--field)))) + (tempel--done (overlay-get ov 'tempel--field)))) (defun tempel-previous (arg) "Move ARG fields backward and quit at the beginning." @@ -558,10 +558,11 @@ This is meant to be a source in `tempel-template-sources'." (defun tempel-abort () "Abort template insertion." (interactive) - ;; TODO abort only the topmost template? (when-let ((beg (tempel--beginning)) (end (tempel--end))) - (tempel-done) + ;; TODO abort only the topmost template? + (while tempel--active + (tempel--disable)) (delete-region beg end))) (defun tempel--disable (&optional st) @@ -580,7 +581,17 @@ This is meant to be a source in `tempel-template-sources'." "Template completion is done." (interactive) ;; TODO disable only the topmost template? - (while tempel--active (tempel--disable))) + (while tempel--active (tempel--done))) + +(defun tempel--done (&optional st) + "Finalize template ST, or last template." + (let* ((st (or st (car tempel--active))) + (range (caar st)) + (env (cdr st)) + (buffer (current-buffer))) + (eval (overlay-get range 'tempel--post) env) + (with-current-buffer buffer + (tempel--disable st)))) (defun tempel--interactive (capf) "Complete with CAPF."