Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide an option to use Emacs advice system #63

Merged
merged 7 commits into from
Feb 26, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Provide an option to use Emacs advice system
  • Loading branch information
haji-ali committed Feb 26, 2023
commit d8e1ad993721a187160f5fbc49a08309b701caa4
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a list then the docstring should probably mention what happens when you set it to that value (as opposed to just non-nil).


;;;; 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'.")))))))
haji-ali marked this conversation as resolved.
Show resolved Hide resolved

;;;;; 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