 ;;;; Applying patches
 
 (defun el-patch--advice-name (function-name)
-  "Given a FUNCTION-NAME, returns the name of the `:override'
-advice el-patch uses to apply patches to it."
+  "Translate a FUNCTION-NAME into an advice name.
+Return a symbol naming the `:override' advice el-patch will use
+to patch a function called FUNCTION-NAME."
   (intern (format "el-patch--advice--%S" function-name)))
 
 (defun el-patch--function-to-advice (definition)
-  "Given a DEFINITION, a list starting with `defun', `defmacro',
-etc., returns a new definition, a list starting with `defun',
-that can be used to define an `:override' advice."
+  "Turn a function DEFINITION into an advice definition.
+DEFINITION is a list starting with `defun', `defmacro', etc.
+Return a new definition, a list starting with `defun', that can
+be used to define an `:override' advice."
   `(defun ,(el-patch--advice-name (cadr definition))
        ,@(cddr definition)))
 
 (defun el-patch--definition (patch-definition)
-  "Activates a PATCH-DEFINITION, a list starting with `defun',
-`defmacro', etc. Updates `el-patch--patches', creates the advice,
-and activates it."
+  "Activate a PATCH-DEFINITION.
+PATCH-DEFINITION is a list starting with `defun', `defmacro',
+etc. Update `el-patch--patches', create the advice, and activate
+it."
   (let* ((function-name (cadr patch-definition))
          (advice-name (el-patch--advice-name function-name)))
     (puthash function-name patch-definition el-patch--patches)

          (list form)))))

(defun el-patch--resolve-definition (patch-definition new)
  "Resolves a patch DEFINITION, a list starting with `defun',
`defmacro', etc., returning a list of the same format. Resolves
in favor of the original version if NEW is nil; otherwise
resolves in favor of the new version."
  (cl-mapcan (lambda (form)
               (el-patch--resolve form new))
             patch-definition))


;;;###autoload
(defmacro el-patch-add (&rest args)
  "Patch directive for inserting forms.
In the original definition, the ARGS and their containing form
are removed. In the new definition, the ARGS are spliced into the
containing s-expression."
  (declare (indent 0))
  `(error "Can't use `el-patch-add' outside of an `el-patch'"))

;;;###autoload
(defmacro el-patch-remove (&rest args)
  "Patch directive for removing forms.
In the original definition, the ARGS are spliced into the
containing s-expression. In the new definition, the ARGS and
their containing form are removed."
  (declare (indent 0))
  `(error "Can't use `el-patch-remove' outside of an `el-patch'"))

;;;###autoload
(defmacro el-patch-swap (old new)
  "Patch directive for swapping forms.
In the original definition, OLD is spliced into the containing
s-expression. In the new definition, NEW is spliced instead."
  (declare (indent 0))
  `(error "Can't use `el-patch-swap' outside of an `el-patch'"))

;;;###autoload
(defmacro el-patch-wrap (&optional triml trimr args)
  "Patch directive for wrapping forms.
TRIML and TRIMR are optional arguments. If only one is provided,
it is assumed to be TRIML. ARGS is required, and it must be a
list.

In the original definition, the ARGS are spliced into the
containing s-expression. If TRIML is provided, the first TRIML of
the ARGS are removed first. If TRIMR is provided, the last TRIMR
are also removed. In the new definition, the ARGS and their
containing list are spliced into the containing s-expression."
  (declare (indent defun))
  `(error "Can't use `el-patch-wrap' outside of an `el-patch'"))

;;;###autoload
(defmacro el-patch-splice (&optional triml trimr args)
  "Patch directive for splicing forms.
TRIML and TRIMR are optional arguments. If only one is provided,
it is assumed to be TRIML. ARGS is required, and it must be a
list.

In the original definition, the ARGS and their containing list
are spliced into the containing s-expression. In the new
definition, the ARGS are spliced into the containing
s-expression. If TRIML is provided, the first TRIML of the ARGS
are removed first. If TRIMR is provided, the last TRIMR are also
removed."
  (declare (indent defun))
  `(error "Can't use `el-patch-splice' outside of an `el-patch'"))

;;;###autoload
(defmacro el-patch-let (varlist arg)
  "Patch directive for creating local el-patch bindings.
Creates local bindings according to VARLIST, then resolves to ARG
in both the original and new definitions. You may bind symbols
that are also patch directives, but the bindings will not have
effect if the symbols are used at the beginning of a list (they
will act as patch directives)."
  (declare (indent 1))
  `(error "Can't use `el-patch-let' outside of an `el-patch'"))

;;;###autoload
(defmacro el-patch-literal (arg)
  "Patch directive for treating patch directives literally.
Resolves to ARG, which is not processed further by el-patch."
  (declare (indent 0))
  `(error "Can't use `el-patch-literal' outside of an `el-patch'"))

