new: make-snippet makes an anonymous snippet lambda

bug: apparently broke edebug though
This commit is contained in:
Joao Tavora
2013-10-17 12:16:54 +01:00
parent 6039bc667f
commit b4bf8bbd33

View File

@@ -217,58 +217,13 @@ I would need these somewhere in the let* form
,(or transform-form ,(or transform-form
'field-text))) 'field-text)))
(defun define--snippet-body (body)
(defmacro define-snippet (name _args &rest body) "Does the actual work for `define-snippet'"
"Define NAME as a snippet-inserting function.
NAME's function definition is set to a function with no arguments
that inserts the fields components at point.
Each form in BODY can be:
* A cons (field FIELD-NAME FIELD-VALUE FIELD-TRANSFORM)
definining a snippet field. A snippet field can be navigated to
using `snippet-next-field' and
`snippet-prev-field'. FIELD-TRANSFORM is currently
unimplemented.
* A cons (mirror FIELD-NAME MIRROR-TRANSFORM) defining a mirror
of the field named FIELD-NAME. Each time the text under the
field changes, the form MIRROR-TRANSFORM is invoked with the
variable `field-text' set to the text under the field. The
string produced become the text under the mirror.
* A string literal which is inserted as a literal part of the
snippet and remains unchanged while the snippet is navigated.
* A symbol designating a function which is called when the
snippet is inserted. The string produced is treated as a
literal string.
* A lambda form taking no arguments, called when the snippet is
inserted. Again, the string produced is treated as a literal
snippet string.
ARGS is an even-numbered property list of (KEY VAL) pairs. KEY
can be:
* the symbol `:obarray', in which case the symbol NAME in
interned in the obarray VAL instead of the global obarray. This
options is currently unimplemented."
(declare (debug (&define name sexp &rest &or
("lambda" sexp def-form) ; curiously, function-form
; doesn't work here
functionp
sexp
("mirror" sexp def-form)
("field" sexp form))))
(let* ((sym-tuples (snippet--form-sym-tuples body)) (let* ((sym-tuples (snippet--form-sym-tuples body))
(marker-init-forms (snippet--make-marker-init-forms sym-tuples)) (marker-init-forms (snippet--make-marker-init-forms sym-tuples))
(init-object-forms (snippet--init-field-and-mirror-forms sym-tuples)) (init-object-forms (snippet--init-field-and-mirror-forms sym-tuples))
(first-field-sym (snippet--first-field-sym sym-tuples))) (first-field-sym (snippet--first-field-sym sym-tuples)))
`(defun ,name () `(let* (,@(mapcar #'first init-object-forms)
(let* (,@(mapcar #'first init-object-forms)
,@marker-init-forms) ,@marker-init-forms)
,@(mapcar #'second init-object-forms) ,@(mapcar #'second init-object-forms)
@@ -310,7 +265,59 @@ can be:
sym-tuples)))) sym-tuples))))
,(if first-field-sym ,(if first-field-sym
`(snippet--move-to-field ,first-field-sym)) `(snippet--move-to-field ,first-field-sym))
(add-hook 'post-command-hook 'snippet--post-command-hook t t))))) (add-hook 'post-command-hook 'snippet--post-command-hook t t))))
(cl-defmacro define-snippet (name () &rest body)
"Define NAME as a snippet-inserting function.
NAME's function definition is set to a function with no arguments
that inserts the fields components at point.
Each form in BODY can be:
* A cons (field FIELD-NAME FIELD-VALUE FIELD-TRANSFORM)
definining a snippet field. A snippet field can be navigated to
using `snippet-next-field' and
`snippet-prev-field'. FIELD-TRANSFORM is currently
unimplemented.
* A cons (mirror FIELD-NAME MIRROR-TRANSFORM) defining a mirror
of the field named FIELD-NAME. Each time the text under the
field changes, the form MIRROR-TRANSFORM is invoked with the
variable `field-text' set to the text under the field. The
string produced become the text under the mirror.
* A string literal which is inserted as a literal part of the
snippet and remains unchanged while the snippet is navigated.
* A symbol designating a function which is called when the
snippet is inserted. The string produced is treated as a
literal string.
* A lambda form taking no arguments, called when the snippet is
inserted. Again, the string produced is treated as a literal
snippet string.
ARGS is an even-numbered property list of (KEY VAL) pairs. KEY
can be:
* the symbol `:obarray', in which case the symbol NAME in
interned in the obarray VAL instead of the global obarray. This
options is currently unimplemented."
(declare (debug (&define name sexp &rest &or
;; curiously, function-form doesn't work here
;;
("lambda" sexp def-form)
sexp
("mirror" sexp def-form)
("field" sexp))))
`(defun ,name ()
,(define--snippet-body body)))
(cl-defmacro make-snippet (&rest body)
"Same as `define-snippet', but return an anonymous function."
`(lambda () ,(define--snippet-body body)))
;;; Snippet mechanics ;;; Snippet mechanics
@@ -323,7 +330,8 @@ can be:
next-field next-field
prev-field) prev-field)
(defun snippet--init-field (object name start end parent-field mirrors next-field prev-field) (defun snippet--init-field (object name start end parent-field mirrors
next-field prev-field)
(setf (snippet--field-name object) name (setf (snippet--field-name object) name
(snippet--field-start object) start (snippet--field-start object) start
(snippet--field-end object) end (snippet--field-end object) end