branch: externals/tempel commit 842f095640de7752140be353b4c146e35560fbd5 Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
Implement pre and post expansion (Fix #22) Examples: (elisp "#+begin_src emacs-lisp" n> r> n "#+end_src" :post (progn (tempel-done) (org-edit-src-code))) (pre-post (message "snippet") :pre (message "pre") :post (message "post")) --- README.org | 7 +++++-- tempel.el | 64 ++++++++++++++++++++++++++++++++++---------------------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/README.org b/README.org index 2911cc5404..856defea64 100644 --- a/README.org +++ b/README.org @@ -95,7 +95,9 @@ The templates are defined in a Lisp file which is stored by default in the ~user-emacs-directory~ (=~/.config/emacs/templates=). The templates are grouped by major mode with an optional ~: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. +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=. #+begin_src emacs-lisp ;; -*- mode: lisp -*- @@ -179,7 +181,8 @@ the template. Behind the name, the Tempo syntax elements follow. (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") + (elisp "#+begin_src emacs-lisp" n> r> n "#+end_src" + :post (progn (tempel-done) (org-edit-src-code))) #+end_src * Template syntax diff --git a/tempel.el b/tempel.el index b2fe93fb7c..d1de0bd352 100644 --- a/tempel.el +++ b/tempel.el @@ -318,35 +318,41 @@ PROMPT is the optional prompt/default value." (defun tempel--insert (template region) "Insert TEMPLATE given the current REGION." - ;; TODO do we want to have the ability to reactivate snippets? - (unless (eq buffer-undo-list t) - (push (list 'apply #'tempel--disable) buffer-undo-list)) - (setf (alist-get 'tempel--active minor-mode-overriding-map-alist) tempel-map) - (save-excursion - ;; Split existing overlays, do not expand within existing field. - ;; TODO This will be causing issues. Think more about nested expansion. - (dolist (st tempel--active) - (dolist (ov (car st)) - (when (and (<= (overlay-start ov) (point)) (>= (overlay-end ov) (point))) - (setf (overlay-end ov) (point))))) - ;; Activate template - (let ((st (cons nil nil)) - (inhibit-modification-hooks t)) - (push (make-overlay (point) (point)) (car st)) - (overlay-put (caar st) 'face 'cursor) ;; TODO debug - (dolist (elt template) (tempel--element st region elt)) - (push (make-overlay (point) (point) nil t t) (car st)) - (overlay-put (caar st) 'face 'cursor) ;; TODO debug - (push st tempel--active))) - (if (cddaar tempel--active) - (unless (cl-loop for ov in (caar tempel--active) - thereis (and (overlay-get ov 'tempel--state) - (eq (point) (overlay-start ov)))) - ;; Jump to first field - (tempel-next 1)) - ;; Disable right away - (goto-char (overlay-start (caaar tempel--active))) - (tempel--disable))) + (let ((plist template)) + (while (and plist (not (keywordp (car plist)))) + (pop plist)) + (eval (plist-get plist :pre) 'lexical) + ;; TODO do we want to have the ability to reactivate snippets? + (unless (eq buffer-undo-list t) + (push (list 'apply #'tempel--disable) buffer-undo-list)) + (setf (alist-get 'tempel--active minor-mode-overriding-map-alist) tempel-map) + (save-excursion + ;; Split existing overlays, do not expand within existing field. + ;; TODO This will be causing issues. Think more about nested expansion. + (dolist (st tempel--active) + (dolist (ov (car st)) + (when (and (<= (overlay-start ov) (point)) (>= (overlay-end ov) (point))) + (setf (overlay-end ov) (point))))) + ;; Activate template + (let ((st (cons nil nil)) + (inhibit-modification-hooks t)) + (push (make-overlay (point) (point)) (car st)) + (overlay-put (caar st) 'face 'cursor) ;; TODO debug + (while (and template (not (keywordp (car template)))) + (tempel--element st region (pop template))) + (push (make-overlay (point) (point) nil t t) (car st)) + (overlay-put (caar st) 'face 'cursor) ;; TODO debug + (push st tempel--active))) + (if (cddaar tempel--active) + (unless (cl-loop for ov in (caar tempel--active) + thereis (and (overlay-get ov 'tempel--state) + (eq (point) (overlay-start ov)))) + ;; Jump to first field + (tempel-next 1)) + ;; Disable right away + (goto-char (overlay-start (caaar tempel--active))) + (tempel--disable)) + (eval (plist-get plist :post) 'lexical))) (defun tempel--save () "Save template file buffer."