7

In my .emacs I have an expression of the form

(defadvice find-file ...)

...which modifies the behavior of the standard find-file command.

There are times, however, when I want to bypass this customized behavior altogether, and run the original, unmodified, find-file.

The only way I have found to do this is to comment-out the (defadvice find-file ...) expression in my .emacs file and start a fresh Emacs session. This is an extremely disruptive, not to mention heavy-handed, solution.

Is there a way to tell Emacs to run the original find-file?

Alternatively, is there at least a way to rescind the defadvice altogether for the remainder of the Emacs session?


EDIT: An earlier attempt to try something like what PythonNut suggests in a comment failed because I could not figure out how to write a simple wrapper for find-file. More specifically, I replaced the (defadvice find-file ...) expression in my .emacs file with

(defun my-find-file (&rest args)
  (apply 'find-file args))

(global-set-key (kbd "C-x C-f") 'my-find-file)

(defadvice my-find-file ...)

...where the code shown as ... in the new (defadvice my-find-file ...) is identical to the ... in the original (defadvice find-file ...).

If I start a new Emacs session with this new .emacs file, and type C-x C-f, I get the error message Wrong type argument: commandp, my-find-file. It looks like my-find-file is not an adequate wrapper for find-file. (I posted a question specifically about this.)

kjo
  • 3,145
  • 14
  • 42
  • 3
    Might I propose that creating a new `my-find-file` and using that instead of the regular `find-file` and switching back when you need the old behavior may be a better solution? – PythonNut Jan 02 '16 at 16:46
  • @PythonNut: please see my EDIT – kjo Jan 02 '16 at 17:27
  • 1
    what I really meant was to remove the `defadvice` entirely and put whatever modifications you made in the advice into your wrapper function. – PythonNut Jan 02 '16 at 18:20

3 Answers3

7

The defadvice macro is almost obsolete, having been replaced by an improved system that uses advice-add, advice-remove, etc, which allows you to turn advice on and off, among other things. See the manual for details.

If you are stuck on an older version of Emacs without the improved system, you can deactivate advice on a function with (ad-deactivate FUNCTION).

Tyler
  • 21,719
  • 1
  • 52
  • 92
  • Won't that disable all advice for that function? – PythonNut Jan 02 '16 at 16:45
  • 5
    @PythonNut yes, `ad-deactivate` will allow you to run the "original, unmodified function", as requested by OP. If you want to add or remove individual pieces of advice, the `advice-add` and `advice-remove` functions allow for that too. – Tyler Jan 02 '16 at 17:09
5

If you have an Emacs version prior to release 24.4 then you have the doc for `defadvice' available from within Emacs. In that case, Ask Emacs!

C-h i to open Info, the doc browser, in Emacs. Then choose the Elisp manual. Then i advice TAB to look up advice in the index.

The TAB shows you the index entries that start with advice, one of which is advice, enabling and disabling. so continue typing: , enab and hit RET (Enter key) to visit the part of the manual (node ) that tells you the answer.

One answer is... command ad-disable-advice:

M-x ad-disable-advice RET find-file

But reading more you see that this disables a particular piece of advice of a particular class for the given function. You can also deactivate all advice for the function. Reading more, you come across command ad-deactivate, which does that:

M-x ad-deactivate RET find-file

phils
  • 48,657
  • 3
  • 76
  • 115
Drew
  • 75,699
  • 9
  • 109
  • 225
  • Well, I had done that, but since none of the things I found in the docs worked (including all the suggestions you posted), I figured that I did not understand the Emacs documentation, and therefore posted my question... When I say that these suggestions did not work, what I mean is that after doing them, `find-file` still does not work the way it does "out-of-the-box". – kjo Jan 02 '16 at 16:53
  • 1
    In that case, describe what you tried, step by step, and say what you saw and what you expected to see instead. You probably want to disable only one kind of advice defined for `find-file`, and you need to find the right one (look at the `defadvice` form to see what that is). – Drew Jan 02 '16 at 16:56
  • 1
    Note that after disabling a piece of advice with `(ad-disable-advice FUNCTION CLASS NAME)` -- or indeed enabling one with `(ad-enable-advice FUNCTION CLASS NAME)` -- you must then `(ad-activate FUNCTION)` for the change to take effect. – phils Jan 02 '16 at 21:49
  • There is also `ad-remove-advice`. Both are available interactively. – Sam Brightman Feb 14 '23 at 08:49
4

I agree with PythonNut that the best solution is probably not to use advice at all, but to define a new command my-find-file instead.

This said, if you find that advising find-file is a better option (e.g. because you also want to affect pre-exisitng calls to find-file), you might like to do it as follows:

(define-minor-mode my-find-file-mode
  "Tweak `find-file' the way I like it."
  :global t :init-value t)

(defun my-find-file-advice (orig &rest args)
  (if (not my-find-file-mode)
      (apply orig args)
    ..do the advice thing here..))
(advice-add 'find-file :around #'my-find-file-advice)

After which you can enable/disable your advice via M-x my-find-file-mode.

Stefan
  • 26,154
  • 3
  • 46
  • 84