Skip to content

Commit

Permalink
Provide an option to use Emacs advice system
Browse files Browse the repository at this point in the history
  • Loading branch information
haji-ali committed Jan 25, 2023
1 parent 156c61b commit a70205f
Showing 1 changed file with 42 additions and 7 deletions.
49 changes: 42 additions & 7 deletions el-patch.el
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ loaded. You can toggle the `use-package' integration later using
"Non-nil means to validate patches when byte-compiling."
:type 'boolean)

(defcustom el-patch-use-advice nil
"Types for which el-patch should use Emacs' advice system for patching.
Typically should be \\='(`defun' `cl-defun')."
:type 'list)

;;;; Internal variables

(defvar el-patch-variant nil
Expand Down Expand Up @@ -565,9 +570,31 @@ PATCH-DEFINITION is an unquoted list starting with `defun',
;; wrong).
,register-patch
;; Now we actually overwrite the current definition.
(el-patch--stealthy-eval
,definition
"This function was patched by `el-patch'."))))))
,(if (and (member type el-patch-use-advice)
(eq
;; Get original name
(cadr (el-patch--resolve-definition
(cl-subseq patch-definition 0 2)
nil))
name))
;; Use advice system
(let ((advice-name (intern (format "%S@el-patch--advice"
name))))
`(progn
(el-patch--stealthy-eval
,(append
(list (car definition) ;; Same type
advice-name) ;; Different name
;; Rest is the same
(cddr definition))
,(format
"This advice was defined by `el-patch' for `%S'."
name))
(advice-add (quote ,name)
:override (quote ,advice-name))))
`(el-patch--stealthy-eval
,definition
"This function was patched by `el-patch'.")))))))

;;;;; Removing patches

Expand All @@ -579,10 +606,18 @@ patched. NAME, TYPE, and VARIANT are as returned by
`el-patch-get'."
(interactive (el-patch--select-patch))
(if-let ((patch-definition (el-patch-get name type variant)))
(eval `(el-patch--stealthy-eval
,(el-patch--resolve-definition
patch-definition nil)
"This function was patched and then unpatched by `el-patch'."))
(if (and (member (car patch-definition) el-patch-use-advice)
(eq (cadr (el-patch--resolve-definition
(cl-subseq patch-definition 0 2)
t))
name))
(advice-remove name
(intern (format "%S@el-patch--advice" name)))
(eval
`(el-patch--stealthy-eval
,(el-patch--resolve-definition
patch-definition nil)
"This function was patched and then unpatched by `el-patch'.")))
(error "There is no patch for %S %S" type name)))

;;;; Defining patch types
Expand Down

0 comments on commit a70205f

Please sign in to comment.