From 9b1d01b600f9da0139dddb19485177ccee99f1ee Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Mon, 24 Apr 2023 19:51:03 +0100 Subject: [PATCH] fix(internal): do not add advice on package load Instead advice yank and yank-pop the first time that yank-indent-mode is enabled. Also add new yank-indent-setup and yank-indent-teardown functions which enable manual control over adding and removing the advice on yank and yank-pop. --- yank-indent.el | 54 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/yank-indent.el b/yank-indent.el index e143667..9197afe 100644 --- a/yank-indent.el +++ b/yank-indent.el @@ -109,6 +109,37 @@ from having `yank-indent-mode' enabled." (or (member major-mode yank-indent-exact-modes) (apply #'derived-mode-p yank-indent-derived-modes)))) +(defvar yank-indent--initial-setup nil) + +(defun yank-indent--is-setup-p () + "Return non-nil if required advice is setup." + (and (advice-member-p #'yank-indent--after-yank-advice #'yank) + (advice-member-p #'yank-indent--after-yank-advice #'yank-pop))) + +;;;###autoload +(defun yank-indent-setup () + "Setup advice on `yank' and `yank-pop' as required by `yank-indent-mode'. + +First time `yank-indent-mode' is enabled it will automatically +call `yank-indent-setup' if needed. + +Setup can be undone with `yank-indent-teardown', but enabling +`yank-indent-mode' again after that will not run setup again." + (interactive) + (advice-add #'yank :after #'yank-indent--after-yank-advice) + (advice-add #'yank-pop :after #'yank-indent--after-yank-advice) + (setq yank-indent--initial-setup t)) + +;;;###autoload +(defun yank-indent-teardown () + "Undo `yank-indent-setup' by removing advice from `yank' and `yank-pop'. + +If this is used, `yank-indent-setup' must be explicitly called +before `yank-indent-mode' will work again." + (interactive) + (advice-remove #'yank #'yank-indent--after-yank-advice) + (advice-remove #'yank-pop #'yank-indent--after-yank-advice)) + ;;;###autoload (define-minor-mode yank-indent-mode "Minor mode for automatically indenting yanked text. @@ -117,17 +148,23 @@ When enabled, this mode indents the yanked region according to the current mode's indentation rules, provided that the region size is less than or equal to `yank-indent-threshold' and no prefix argument is given during yanking." - :lighter " YI") - -(defun yank-indent--enable () - "Enable `yank-indent-mode' if the current buffer meets the criteria." - (when (yank-indent--should-enable-p) - (yank-indent-mode 1))) + :lighter " YI" + :group 'yank-indent + (if yank-indent-mode + ;; Auto-run advice setup if needed first time mode is enabled. Display + ;; warning if advice setup has been undone. + (when (not (yank-indent--is-setup-p)) + (if yank-indent--initial-setup + (message (concat "Warning: yank-indent-mode not available, " + "run `M-x yank-indent-setup' to setup.")) + (yank-indent-setup))))) ;;;###autoload (define-globalized-minor-mode global-yank-indent-mode yank-indent-mode - yank-indent--enable) + (lambda () + (when (yank-indent--should-enable-p) + (yank-indent-mode 1)))) (defun yank-indent--after-yank-advice (&optional _) "Conditionally indent the region (yanked text) after yanking. @@ -150,8 +187,5 @@ functions." (if (<= (- end beg) yank-indent-threshold) (indent-region beg end))))) -(advice-add #'yank :after #'yank-indent--after-yank-advice) -(advice-add #'yank-pop :after #'yank-indent--after-yank-advice) - (provide 'yank-indent) ;;; yank-indent.el ends here