diff --git a/snippet-tests.el b/snippet-tests.el index 9edd5ac..cb0e72d 100644 --- a/snippet-tests.el +++ b/snippet-tests.el @@ -328,7 +328,7 @@ ;;; `snippet-defmacro' attempt ;;; -(snippet-defmacro snippet--sprintf () +(define-snippet snippet--sprintf () (&mirror 0 (_field-string field-empty-p) (unless field-empty-p "s")) (insert "printf (") diff --git a/snippet.el b/snippet.el index beb10c9..caaf4ba 100644 --- a/snippet.el +++ b/snippet.el @@ -1,6 +1,6 @@ ;;; snippet.el --- yasnippet's engine distilled -*- lexical-binding: t; -*- -;; Copyright (C) 2013 João Távora +;; Copyright (C) 2013-2015 Free Software Foundation ;; Author: João Távora ;; Keywords: convenience @@ -26,29 +26,29 @@ ;; frontends with the bare minimum funcionality to define, insert, navigate and ;; undo snippets. ;; -;; Snippets are defined via the `define-snippet' and `make-snippet' -;; entrypoints.The snippet definition syntax is as powerful as yasnippet's -;; (inspired by textmate's). Since the syntax is now sexp-based, snippets -;; definitions are easily manipulated and generated by macros. -;; -;; Another improvement is that `define-snippet' calls can be now be `edebug'ed -;; and stepped through on snippet insertion and navigation. +;; Snippets are defined via the `define-snippet' or `make-snippet' +;; entrypoints. The snippet definition syntax is quite different (TODO: how so?) +;; Both are as powerful as yasnippet's (inspired by textmate's). ;; ;; Once inserted into a buffer, snippets are navigated using ;; `snippet-next-field' and `snippet-prev-field', bound to TAB and S-TAB by ;; default. ;; -;; There is a PROPERTIES argument, unimplemented at time of writing, in the -;; `define-snippet' macro which will *probably* understand a set of properties -;; controlling snippet's indentation, custom keymapping and other per-snippet -;; characteristics affecting snippet.el's core functionality. -;; ;; Funcionality such as snippet management, mode management, tab-trigerring or ;; any other fanciness are *not* offered. `define-snippet's PROPERTIES ;; mechanism *might* become extensible to provide frontends such as yasnippet ;; the capability to conveniently implement said fanciness. ;; ;; TODO: auto-indentation of the inserted snippet +;; +;; TODO: there should be somewhere a PROPERTIES argument, unimplemented at time +;; of writing, in the `define-snippet' macro which should probably understand a +;; set of properties controlling snippet's indentation, custom keymapping and +;; other per-snippet characteristics affecting snippet.el's core functionality. +;; +;; TODO: `define-snippet' should be `edebug'ed and stepped through on snippet +;; insertion *and* navigation. This works for forms in snippet fields, but fails +;; for mirrors for some reason. ;; ;; TODO: undo, specifically snippet revival ;; @@ -87,7 +87,7 @@ (require 'eieio) -;;; the define-snippet macro and its helpers +;;; the `make-snippet' function and its helpers ;;; (defvar snippet--sym-obarray (make-vector 100 nil)) @@ -163,8 +163,7 @@ (snippet--make-field-sym name)))))) (defun snippet--define-body (body) - "Does the actual work for `define-snippet'. -Argument BODY is a list of forms as described in `define-snippet'." + "Does the actual work for `make-snippet'." (let ((unfolded (snippet--unfold-forms (mapcar #'snippet--canonicalize-form body))) all-objects exit-object) @@ -226,12 +225,14 @@ Argument BODY is a list of forms as described in `define-snippet'." (setq sym nil))) (snippet--activate-snippet (list ,@all-objects)))))) +(def-edebug-spec snippet-form + (&or + ("&mirror" sexp def-form) + ("&field" sexp &or ("&nested" &rest snippet-form) def-form) + def-form)) -(cl-defmacro define-snippet (name (&rest _properties) &rest snippet-forms) - "Define NAME as a snippet-inserting function. - -NAME's function definition is set to a function with no arguments -that inserts the snippet's components at point. +(defun make-snippet (forms) + "Make a snippet-inserting function from FORMS. Each form in SNIPPET-FORMS, inserted at point in order, can be: @@ -288,19 +289,6 @@ considered to have returned a single whitespace. PROPERTIES is an even-numbered property list of (KEY VAL) pairs. Its meaning is not decided yet" - (declare (debug (&define name sexp &rest snippet-form))) - `(defun ,name () - ,(snippet--define-body snippet-forms))) - -(def-edebug-spec snippet-form - (&or - ("&mirror" sexp def-form) - ("&field" sexp &or ("&nested" &rest snippet-form) def-form) - def-form)) - -(defun make-snippet (forms) - "Same as `define-snippet', but return an anonymous function. -Argument FORMS is a list of forms as described in `define-snippet'." `(lambda () ,(snippet--define-body forms))) @@ -676,12 +664,15 @@ Skips over nested fields if their parent has been modified." -;;; `snippet-defmacro' attempt +;;; The `define-snippet' macro ;;; -(cl-defmacro snippet-defmacro (name args &body body) +(defmacro define-snippet (name args &optional docstring &rest body) (declare (debug (&define name sexp def-body)) (indent defun)) - `(defun ,name ,args + (unless (stringp docstring) + (push docstring body) + (setq docstring nil)) + `(defun ,name ,args ,docstring (let (;; (start (point-marker)) (snippet--fields (make-hash-table)) (snippet--mirrors (make-hash-table)) @@ -741,8 +732,6 @@ Skips over nested fields if their parent has been modified." (put '&mirror 'lisp-indent-function 'defun) (put '&exit 'lisp-indent-function 'defun) - - ;; Local Variables: ;; coding: utf-8 ;; whitespace-style: (face lines-tail)