How to go back to previously defined function in Emacs Lisp? - emacs

I have a function:
(defun function-name (&optional args) ... <unknown content>)
I redefine it with
(defun function-name (&optional args) ... my own content)
Can I somehow after some time remove my own version of function-name and stay with the first one?

No, you cannot.
Save/Restore
You can save the definition yourself before redefining the function:
Common Lisp:
(defparameter *old-def* (fdefinition 'function-name))
(defun function-name ...)
...
(setf (fdefinition 'function-name) *old-def*)
Emacs Lisp:
(defconst *old-def* (symbol-function 'function-name))
(defun function-name ...)
...
(fset 'function-name *old-def*)
Reload
Or, if you know where the function was defined, you can reload the definition:
Common Lisp:
(load "file-name")
Emacs Lisp: same as above or M-x load-library RET.
Reeval
Or, if you know the original definition, you can reevaluate it, by pasting it at the Common Lisp prompt or by visiting the file with the definition in Emacs and evaluating the defun using C-M-x, as suggested by #Drew in a comment.

Note that it's risky to redefine other libraries' or Emacs' own functions, since you don't know what else depends on them working exactly as expected. If at all possible, use a different name. If not, provide copious documentation warning prominently about the redefinitions. Also, did you check first whether the existing function can be tweaked to your satisfaction using predefined hooks that run before or after it or by customizing any particular user options?

Not the way you do it, but you can get what you want by using an advice instead of a new definition. E.g.
(defadvice function-name (around my-overrride activate)
... my own content)
after the above you can recover the old behavior by deactivating the advice. Using the new advice system in Emacs-24.4 this would look like:
(defun my-function-name (&optional args) ... my own content)
(add-advice 'function-name :override #'my-function-name)
which can be reverted with
(remove-advice 'function-name #'my-function-name)

Related

How to restore default function in Emacs?

I changed beep function (defun beep () ..., is it possible to revert it without restarting Emacs?
Just visit the original definition, and evaluate it.
If need be you can start a second instance of Emacs in order to find the code: C-h f beep RET and follow the link to the source code.
(I'd normally say find-function, but in this instance beep is an alias, and following the link takes you to the defalias line, whereas find-function goes to the source definition.)
Not unless you first saved (symbol-function 'ding). If you did, then you can restore it (using fset). If not, you cannot, because ding (aka beep) is defined in C, not Lisp.
If it were defined in Lisp then you could do what #phils suggested.
It may be a fluke, but I can do it currently with:
(defun restore-redefined-function (name)
(interactive (find-function-read))
(save-window-excursion
(find-function name)
(eval-defun nil)))
In *scratch*:
(defun beep () "foo")
;; beep
(symbol-function 'beep)
;; (lambda nil "foo")
M-x restore-redefined-function and enter beep.
in *scratch*:
(symbol-function 'beep)
;; ding

how to modify a function's definition graciously

Assume there is a sample function defined in a library (this question's precondition is all definitions in this library cannot be modified, something like "read only"):
(defun sample ()
(foo)
(bar)
(baz))
I want to use this library, but the function sample cannot match my request, what I want is:
(defun sample ()
(foo)
(when condition
(bar))
(baz))
Someone told me to use defadvice, but I noticed that defadvice can only insert code before or after the invocations of sample, like:
(before-advice ...)
(sample)
(after-advice ...)
it cannot modify the definition of sample itself. So, how can I achieve this graciously? Should I have to rewrite a sample myself, called my-sample or sample2?
sds's answer works, except that you presumably only want to be advising bar when sample is executing, so you'd need to advise sample as well in order to activate and deactivate the advice for bar. My with-temporary-advice macro facilitates this:
(defmacro with-temporary-advice (function class name &rest body)
"Enable the specified advice, evaluate BODY, then disable the advice."
`(unwind-protect
(progn
(ad-enable-advice ,function ,class ,name)
(ad-activate ,function)
,#body)
(ad-disable-advice ,function ,class ,name)
(ad-activate ,function)))
(defadvice bar (around my-conditional-bar disable)
;; This advice disabled by default, and enabled dynamically.
(when condition
ad-do-it))
(defadvice sample (around my-sample-advice activate)
"Make execution of `bar' conditional when running `sample'."
(with-temporary-advice 'bar 'around 'my-conditional-bar
ad-do-it))
Note that if bar is also called in other ways while sample is executing, the advice will apply for those calls as well, so you should account for that if it's a possibility.
Alternatively, you may prefer to use flet to redefine bar when required. This is subject to the same caveat as the first solution, of course.
(defadvice sample (around my-sample-advice activate)
"Make execution of `bar' conditional when running `sample'."
(if condition
ad-do-it
(flet ((bar () nil))
ad-do-it)))
That's much simpler to read, but for reasons I don't understand flet is, as of Emacs 24.3, no longer in favour. Its docstring suggests using cl-flet instead, but as cl-flet uses lexical binding, that won't actually work. As best I could tell, it sounded like flet isn't actually going away, however the current recommendation seems to be to use advice instead.
Also note that if, inside bar, the unwanted behaviour depended on some variable, then it would be preferable to use a let binding on that variable instead of the flet binding on the function.
Edit:
These approaches do make it harder to see what is happening, of course. Depending upon the exact situation, it may well be preferable to simply redefine the sample function to do what you want (or to write a my-sample function to call in its place, as you suggested).
Others have already provided good answers, but since some complain about flet's disgrace, I'll show what I'd use:
(defvar my-inhibit-bar nil)
(defadvice bar (around my-condition activate)
(unless my-inhibit-bar ad-do-it))
(defadvice sample (around my-condition activate)
(let ((my-inhibit-bar (not condition)))
ad-do-it))
Look ma! No flet and no ugly activate/deactive! And when you C-h f bar it will clearly tell you that there's more than meets the eye. Also I'd actually use the new advice-add instead:
(defvar my-inhibit-bar nil)
(defun my-bar-advice (doit &rest args)
(unless my-inhibit-bar (apply doit args)))
(advice-add :around 'bar #'my-bar-advice)
(defun my-sample-advice (doit &rest args)
(let ((my-inhibit-bar (not condition)))
(apply doit args)))
(advice-add :around 'sample #'my-sample-advice)
You should advise function bar instead, using an around advice:
(defadvice bar (around my-condition)
(when condition
ad-do-it))

Prevent unwanted commands from Emacs being loaded into completion and help buffers

I am begining to develop my own Emacs environment, I have a custom init.el (as below) that loads libraries from my user directory and ignores the installed directories. I have not placed any of the Amusement or Mail lisp libraries in the User directory but they are still appearing in auto-complete lists. This is because they are being defined as auto-load functions. How do I prevent these auto-load functions from being created? I don't want to individually remove each unwanted function as this is cumbersome and wasteful.
Help info on an unwanted function;
5x5 is an interactive autoloaded Lisp function.
It is bound to <menu-bar> <tools> <games> <5x5>.
my init.el;
(setq inhibit-defaul-init 1)
(setq load-path (list
(expand-file-name "~/.emacs.d/")
(expand-file-name "~/.emacs.d/lisp/")
(expand-file-name "~/.emacs.d/lisp/emacs-lisp/")
(expand-file-name "~/.emacs.d/lisp/eshell/")
(expand-file-name "~/.emacs.d/lisp/net/")
(expand-file-name "~/.emacs.d/lisp/nxml")
(expand-file-name "~/.emacs.d/lisp/org")
(expand-file-name "~/.emacs.d/lisp/term")
(expand-file-name "~/.emacs.d/lisp/textmodes")
(expand-file-name "~/.emacs.d/lisp/usrl")
(expand-file-name "~/.emacs.d/lisp/")
)
)
You can unbind autoloaded functions in the same way that you can unbind normal functions, so you could effectively remove 5x5 and other unwanted autoloaded functions from the running system like this:
(mapc
(lambda (func) (fmakunbound func))
'(5x5 5x5-crack-randomly 5x5-crack-mutating-current 5x5-crack-mutating-best 5x5-crack-xor-mutate 5x5-crack))
For autoloaded variables, you would use makunbound instead of fmakunbound.
To obtain a list of likely suspects, you could use
M-x find-library RET loaddefs RET
M-x occur RET ^(autoload RET
The loadhist library might also be of interest.
Edit:
Actually, inspecting the autoload file seems like a fairly safe method of establishing whether or not you want to eliminate something. I believe this is only usable with functions, however; as far as I can see, other kinds of autoloaded objects are just defined immediately by loaddefs. You could make assumptions based on symbol-name, but I wouldn't recommend it (but then I wouldn't do any of this, so YMMV).
(defvar my-unwanted-libraries
'("5x5" "snake" "hanoi" "tetris")
"Unbind all autoloaded functions for these libraries.")
(defun my-unbind-unwanted-autoload-functions ()
"Unbind all unwanted autoloaded functions."
(interactive)
(do-symbols (symbol)
(let* ((function (and (fboundp symbol)
(symbol-function symbol)))
(file (and function
(consp function)
(eq (car function) 'autoload)
(cadr function))))
(when (and file (member file my-unwanted-libraries))
(fmakunbound symbol)))))
Since most of Emacs is written in Emacs Lisp, and as much as possible is auto-loaded, you cannot easily remove the functions set up for auto loading. For example, c++-mode is an autoloaded function, so getting rid of all autoloaded functions would prevent you from using c++-mode (unless you'd added your own copy).
Probably the best way to do what you are asking is to build your own Emacs executable, and restrict what gets put into the Emacs executable itself. This is documented here. You could simply remove the directories/libraries you don't want, and rebuild. The newly generated autoload file wouldn't contain references to the functions in those libraries, and you'd be all set.
Note: you may inadvertently remove libraries that are used by Emacs that you don't realize. For example, M-x report-emacs-bug uses Email...
Is there a particular reason you want to remove these autoloaded functions? If you feel they're cluttering up completions, there are many many completion libraries you can use to customize what you see.

How does the following statement is interpreted by emacs

https://stackoverflow.com/a/663636/391104
(defun my-c++-mode-hook ()
(setq c-basic-offset 4)
(c-set-offset 'substatement-open 0))
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
Based on my investigation, I just need to add the above code into my .emacs and then it works magically.
Q1> What does defun my-c++-mode-hook () mean? a function definition in lisp?
Q2> What is the usage of following line? where should I trigger it or it is run automatically by emacs
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
Thank you
Q1: Yes, this is a function definition (hence defun). The second symbol is the name, which has the suffix '-hook' to indicate to humans that it is intended to be used as a hook. It could be given (almost) any arbitrary name without changing its behaviour. The empty () indicates the function takes no arguments. Everything else is the body of the function.
Q2: Basically, this adds a pointer to the previous function to the list of functions that are called when ever c++-mode is started. Whenever you start a mode, the Emacs looks for the mode hook, running all the functions in it. Both the function definition and the add-hook line need to go in your .emacs, and they will be run automatically when you start emacs.
To wrap your head around elisp, the introduction is highly recommended. It ships with emacs, and can be accessed from the info system: C-h i, then look for Elisp Introduction.

Can I use ido-completing-read instead of completing-read everywhere?

I'm a big fan of ido-mode, so much so that I would like to use it for things like describe-function or find-tag and so on, without having to write something like in "Can I get ido-mode-style completion for searching tags in Emacs?" for each one.
Both
(defalias completing-read ido-completing-read)
and
(setf 'completing-read 'ido-completing-read)
don't work, at least partly because ido-completing-read calls completing-read in its body, so any simple redefinition would result in infinite recursion.
In theory, it should be possible, since the first line of the docstring for ido-completing-read is "Ido replacement for the built-in completing-read." I've looked around a bit and can't seem to find anyone else who has attempted or succeeded at it.
I realize that Icicles probably provides something like this, and I may end up going with that anyway, but it is a bit more of a plunge than I care to take right now.
Thanks for any help.
Edit: This is now an Emacs package available from MELPA. It has been expanded into a full-fledged minor mode. Development happens on GitHub.
Original post:
Here is my refinement of Jacobo's answer. Credit to him for the original magic. I've added an override variable, which you can use to prevent the use of ido-completing-read in specific functions. I have also added a check that uses the original completing-read if there are no completions (This happens occasionally, for example in org-remember-apply-template from org-mode, which breaks with Jacobo's original advice).
(defvar ido-enable-replace-completing-read t
"If t, use ido-completing-read instead of completing-read if possible.
Set it to nil using let in around-advice for functions where the
original completing-read is required. For example, if a function
foo absolutely must use the original completing-read, define some
advice like this:
(defadvice foo (around original-completing-read-only activate)
(let (ido-enable-replace-completing-read) ad-do-it))")
;; Replace completing-read wherever possible, unless directed otherwise
(defadvice completing-read
(around use-ido-when-possible activate)
(if (or (not ido-enable-replace-completing-read) ; Manual override disable ido
(boundp 'ido-cur-list)) ; Avoid infinite loop from ido calling this
ad-do-it
(let ((allcomp (all-completions "" collection predicate)))
(if allcomp
(setq ad-return-value
(ido-completing-read prompt
allcomp
nil require-match initial-input hist def))
ad-do-it))))
Oh, and for using ido in M-x, use amx.
Hocus pocus, abracadabra, presto!
(defadvice completing-read
(around foo activate)
(if (boundp 'ido-cur-list)
ad-do-it
(setq ad-return-value
(ido-completing-read
prompt
(all-completions "" collection predicate)
nil require-match initial-input hist def))))
That works with everything but subr's, from which execute-extended-command is the one that matters (what is binded to M-x). But we can get what we want from M-x
(global-set-key
"\M-x"
(lambda ()
(interactive)
(call-interactively
(intern
(ido-completing-read
"M-x "
(all-completions "" obarray 'commandp))))))
I don't think ido-mode is ready for this quite yet. In particular, ido-completing-read currently only works with strings, while completing-read supports alists as well. This is very important once you want to have a different user-level description of the items you want to complete on.
Therefore I am not surprised that it doesn't work out of the box, yet. Short of modifying the code yourself your best bet is probably to just file a bug report/feature request.
Ido comes with a function that should do this, so just call it in your .emacs file:
(ido-everywhere t)
Using Emacs 24.3, ido-ubiquitous didn't work for me. So tried this and it is working fine so far:
(defun my-completing-read (prompt collection &optional predicate
require-match initial-input
hist def inherit-input-method)
(if (listp collection)
(ido-completing-read prompt collection predicate require-match
initial-input hist def inherit-input-method)
(completing-read-default prompt collection predicate require-match
initial-input hist def inherit-input-method)))
(setq completing-read-function 'my-completing-read)
Just a thought: have you tried editing ido-completing-read to call original-completing-read instead of completing-read, defining original-completing-read to be the current completing-read and then doing your defalias or setf thing?