Function: majutsu-template-defun

majutsu-template-defun is a macro defined in majutsu-template.el.

Signature

(majutsu-template-defun NAME ARGS SIGNATURE &rest BODY)

Documentation

Define a majutsu template helper NAME with ARGS, SIGNATURE and BODY.

Generates majutsu-template-NAME and registers it for template DSL usage.

Source Code

;; Defined in /nix/store/jagqw3nms546pad0gxi5f3wsckk6pji7-emacs-packages-deps/share/emacs/site-lisp/majutsu-template.el
;;;###autoload
(defmacro majutsu-template-defun (name args signature &rest body)
  "Define a majutsu template helper NAME with ARGS, SIGNATURE and BODY.
Generates `majutsu-template-NAME' and registers it for template DSL usage."
  (declare (indent defun))
  (unless (and (symbolp name) (not (keywordp name)))
    (user-error "majutsu-template-defun: NAME must be an unprefixed symbol"))
  (let* ((name-str (symbol-name name))
         (signature-info (majutsu-template--parse-signature name signature))
         (owner (majutsu-template--ensure-owner-type
                 (plist-get signature-info :owner)
                 name))
         (template-name (or (plist-get signature-info :template-name) name-str))
         (keyword-flag (plist-get signature-info :keyword))
         (fn-symbol (intern (format "majutsu-template-%s" name-str)))
         (parsed-args (majutsu-template--parse-args name args))
         (bind-self-arg (majutsu-template--validate-bind-self
                         name
                         (plist-get signature-info :bind-self)
                         parsed-args))
         (self-arg (and owner (car parsed-args)))
         (self-binding-arg (or bind-self-arg self-arg))
         (returns-via (majutsu-template--validate-returns-via
                       name
                       (plist-get signature-info :returns-via)
                       parsed-args))
         (lambda-list (majutsu-template--build-lambda-list parsed-args))
         (normalizers (majutsu-template--build-arg-normalizers parsed-args))
         (arg-checks (majutsu-template--build-arg-type-checks name parsed-args))
         (return-type (plist-get signature-info :returns))
         (docstring (majutsu-template--compose-docstring
                     template-name (plist-get signature-info :doc) parsed-args))
         (body-context (list :name name
                             :template-name template-name
                             :owner owner
                             :keyword keyword-flag
                             :args parsed-args
                             :returns return-type
                             :body-forms body))
         (body-forms (cond
                      (body body)
                      (owner
                       (user-error "majutsu-template-defun %s: owner-bound helpers must provide a body; use majutsu-template-defmethod/defkeyword for declarations"
                                   name))
                      (t
                       (majutsu-template--default-defun-body body-context))))
         (meta `(majutsu-template--make-fn
                 :name ,template-name
                 :symbol ',fn-symbol
                 :args ',parsed-args
                 :returns ',return-type
                 :returns-via ',returns-via
                 :doc ,docstring
                 :owner ',owner
                 :keyword ',keyword-flag
                 :bind-self ',(and bind-self-arg
                                   (majutsu-template--arg-name bind-self-arg)))))
    (when (and owner bind-self-arg)
      (user-error "majutsu-template-defun %s: owner-bound helpers already bind self automatically; do not also specify :bind-self"
                  name))
    `(progn
       (majutsu-template--register-function ,meta)
       (defun ,fn-symbol ,lambda-list
         ,docstring
         ,@normalizers
         ,@arg-checks
         ,(if self-binding-arg
              `(majutsu-template--call-with-self-binding
                ,(majutsu-template--arg-name self-binding-arg)
                ',(majutsu-template--arg-type self-binding-arg)
                (lambda ()
                  (let ((majutsu-template--result (progn ,@body-forms)))
                    (majutsu-template--rewrite majutsu-template--result))))
            `(let ((majutsu-template--result (progn ,@body-forms)))
               (majutsu-template--rewrite majutsu-template--result)))))))