snippet-defmacro is the dynamic approach, make-snippet the static one

* snippet-tests.el (snippet--sprintf): Use `define-snippet'

* snippet.el: Pass copyright to FSF. Some doc change.
(snippet--define-body): Docstring update.
(define-snippet): Renamed from `snippet-defmacro'
This commit is contained in:
João Távora 2015-04-03 12:57:26 +01:00
parent 9f88e596bf
commit ece2e7d1f2
2 changed files with 29 additions and 40 deletions

View File

@ -328,7 +328,7 @@
;;; `snippet-defmacro' attempt ;;; `snippet-defmacro' attempt
;;; ;;;
(snippet-defmacro snippet--sprintf () (define-snippet snippet--sprintf ()
(&mirror 0 (_field-string field-empty-p) (&mirror 0 (_field-string field-empty-p)
(unless field-empty-p "s")) (unless field-empty-p "s"))
(insert "printf (") (insert "printf (")

View File

@ -1,6 +1,6 @@
;;; snippet.el --- yasnippet's engine distilled -*- lexical-binding: t; -*- ;;; 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 <joaotavora@gmail.com> ;; Author: João Távora <joaotavora@gmail.com>
;; Keywords: convenience ;; Keywords: convenience
@ -26,29 +26,29 @@
;; frontends with the bare minimum funcionality to define, insert, navigate and ;; frontends with the bare minimum funcionality to define, insert, navigate and
;; undo snippets. ;; undo snippets.
;; ;;
;; Snippets are defined via the `define-snippet' and `make-snippet' ;; Snippets are defined via the `define-snippet' or `make-snippet'
;; entrypoints.The snippet definition syntax is as powerful as yasnippet's ;; entrypoints. The snippet definition syntax is quite different (TODO: how so?)
;; (inspired by textmate's). Since the syntax is now sexp-based, snippets ;; Both are as powerful as yasnippet's (inspired by textmate's).
;; 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.
;; ;;
;; Once inserted into a buffer, snippets are navigated using ;; Once inserted into a buffer, snippets are navigated using
;; `snippet-next-field' and `snippet-prev-field', bound to TAB and S-TAB by ;; `snippet-next-field' and `snippet-prev-field', bound to TAB and S-TAB by
;; default. ;; 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 ;; Funcionality such as snippet management, mode management, tab-trigerring or
;; any other fanciness are *not* offered. `define-snippet's PROPERTIES ;; any other fanciness are *not* offered. `define-snippet's PROPERTIES
;; mechanism *might* become extensible to provide frontends such as yasnippet ;; mechanism *might* become extensible to provide frontends such as yasnippet
;; the capability to conveniently implement said fanciness. ;; the capability to conveniently implement said fanciness.
;; ;;
;; TODO: auto-indentation of the inserted snippet ;; 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 ;; TODO: undo, specifically snippet revival
;; ;;
@ -87,7 +87,7 @@
(require 'eieio) (require 'eieio)
;;; the define-snippet macro and its helpers ;;; the `make-snippet' function and its helpers
;;; ;;;
(defvar snippet--sym-obarray (make-vector 100 nil)) (defvar snippet--sym-obarray (make-vector 100 nil))
@ -163,8 +163,7 @@
(snippet--make-field-sym name)))))) (snippet--make-field-sym name))))))
(defun snippet--define-body (body) (defun snippet--define-body (body)
"Does the actual work for `define-snippet'. "Does the actual work for `make-snippet'."
Argument BODY is a list of forms as described in `define-snippet'."
(let ((unfolded (snippet--unfold-forms (let ((unfolded (snippet--unfold-forms
(mapcar #'snippet--canonicalize-form body))) (mapcar #'snippet--canonicalize-form body)))
all-objects exit-object) all-objects exit-object)
@ -226,12 +225,14 @@ Argument BODY is a list of forms as described in `define-snippet'."
(setq sym nil))) (setq sym nil)))
(snippet--activate-snippet (list ,@all-objects)))))) (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) (defun make-snippet (forms)
"Define NAME as a snippet-inserting function. "Make a snippet-inserting function from FORMS.
NAME's function definition is set to a function with no arguments
that inserts the snippet's components at point.
Each form in SNIPPET-FORMS, inserted at point in order, can be: 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) PROPERTIES is an even-numbered property list of (KEY VAL)
pairs. Its meaning is not decided yet" 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))) `(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)) (declare (debug (&define name sexp def-body))
(indent defun)) (indent defun))
`(defun ,name ,args (unless (stringp docstring)
(push docstring body)
(setq docstring nil))
`(defun ,name ,args ,docstring
(let (;; (start (point-marker)) (let (;; (start (point-marker))
(snippet--fields (make-hash-table)) (snippet--fields (make-hash-table))
(snippet--mirrors (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 '&mirror 'lisp-indent-function 'defun)
(put '&exit 'lisp-indent-function 'defun) (put '&exit 'lisp-indent-function 'defun)
;; Local Variables: ;; Local Variables:
;; coding: utf-8 ;; coding: utf-8
;; whitespace-style: (face lines-tail) ;; whitespace-style: (face lines-tail)