Много кода использует старый механизм defadvice, который устарел благодаря новому advice-add, реализация и семантика которого значительно проще.
Старый совет, например:
(defadvice previous-line (before next-line-at-end
(&optional arg try-vscroll))
"Вставить пустую строку при перемещении вверх от первой строки."
(if (and next-line-add-newlines (= arg 1)
(save-excursion (beginning-of-line) (bobp)))
(progn
(beginning-of-line)
(newline))))
может быть переведен в новый механизм советов в обычную функцию:
(defun previous-line--next-line-at-end (&optional arg try-vscroll)
"Вставить пустую строку при перемещении вверх от первой строки."
(if (and next-line-add-newlines (= arg 1)
(save-excursion (beginning-of-line) (bobp)))
(progn
(beginning-of-line)
(newline))))
Очевидно, что это на самом деле не изменяет previous-line. Для этого старый совет требовал:
(ad-activate 'previous-line)
в то время как новый механизм советов требует:
(advice-add 'previous-line :before #'previous-line--next-line-at-end)
Обратите внимание, что ad-activate имел глобальный эффект: он активировал все советы, включенные для указанной функции. Если вы хотели активировать или деактивировать конкретный совет, вам нужно было включить или выключить его с помощью ad-enable-advice и ad-disable-advice. Новый механизм устраняет это различие.
Относительно советов, таких как:
(defadvice foo (around foo-around)
"Игнорировать регистр в `foo'."
(let ((case-fold-search t))
ad-do-it))
(ad-activate 'foo)
может быть переведено в:
(defun foo--foo-around (orig-fun &rest args)
"Игнорировать регистр в `foo'."
(let ((case-fold-search t))
(apply orig-fun args)))
(advice-add 'foo :around #'foo--foo-around)
Что касается класса совета, обратите внимание, что новый :before не совсем эквивалентен старому before, потому что в старом совете вы могли изменять аргументы функции (например, с помощью ad-set-arg), и это влияло на значения аргументов, видимые исходной функцией, тогда как в новом :before изменение аргумента с помощью setq в совете не влияет на аргументы, видимые исходной функцией.
При переносе советов before, которые зависели от этого поведения, вам потребуется преобразовать их в новый совет :around или :filter-args.
Аналогично, старый совет after мог изменять возвращаемое значение, изменяя ad-return-value, тогда как новый совет :after не может, поэтому при переносе таких старых советов after вам потребуется преобразовать их в новый совет :around или :filter-return.