Overriding a function in Emacs Lisp - emacs

I would like to temporarily override the kill-new function. I have a way I want to reimplement kill-new that works in only in certain contexts, but I don't want to reimplement a special version of kill-region on top of that. (kill-new is called from kill-region)
Since Emacs Lisp uses dynamic scoping, this should be possible, right? (On the other hand, it seems that this would be an unsafe thing to support, and it might make me a bit nervous knowing that it is possible...)
I have experimented with using let and fset, but so far have found no way to get it to work as expected. So, hopefully someone can fill in the blank in the following pseudocode:
(defun my-kill-new (string &optional replace yank-handler)
(message "in my-kill-new!"))
(defun foo ()
(some-form-that-binds-a-function (kill-new my-kill-new)
(kill-region (point) (mark))))
What should some-form-that-binds-a-function be? Or am I barking up the wrong tree?

Your some-form-that-binds-a-function is called flet, so you were close.

Here is a solution:
(defadvice kill-new (around my-kill-new (string &optional replace yank-handler))
(message "my-kill-new!"))
(defun foo ()
(progn (ad-enable-advice 'kill-new 'around 'my-kill-new)
(ad-activate 'kill-new)
(kill-region (point) (mark))
(ad-disable-advice 'kill-new 'around 'my-kill-new)
(ad-activate 'kill-new)))

Look at the advice package, which is very good at doing all of this.

Related

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

Elisp rename macro

How can I rename elisp macro? To be more accurate, I want make defun to be synonym to cl-defun.
I do not care about time or memory overhead.
Summary
I don't think you can do that - at least not easily.
Since cl-defun expands to defun, you will get an infinite macroexpand loop when using defun if you do the obvious (defalias 'defun 'cl-defun).
The is a way...
So what you need to do is
save the original defun: (fset 'defun-original (symbol-function 'defun)).
copy the definition of cl-defun in cl-macs.el, replacing defun with defun-original.
replace defun with cl-defun using defalias: (defalias 'defun 'cl-defun).
Now, at least, if things go sour, you can restore the original behavior with (fset 'defun (symbol-function 'defun-original)).
...but you don't want it
However, I think you don't really want to do that.
If you want to use a Common Lisp, use it. Trying to pretend that you can turn Elisp into CL will cause you nothing but grief. I tried to travel that road 15 years ago - there is no fun there. It should be easier now, at least there is lexical binding, but I still don't think it is worth the effort.
If you want to extend Emacs, then using cl-defun makes even less sense: your extensions will be useless for others and you won't even be able to ask for help because few people will bother with such a radical change in such a basic functionality for such a tiny gain.
In general, you can make a synonym very simply with (defalias 'foo 'cl-defun).
But the expansion of a call to cl-defun uses defun, so if you do (defalias 'defun 'cl-defun) you'll get into infinite loops.
You can probably get what you want by replacing defun with a macro which either does what defun does or what cl-defun does, depending on whether the cal uses cl-defun features or not. E.g. using advice-add (which is in Emacs's trunk; you can use defadvice in older Emacsen to get simlar results) it could look something like the untested code below:
(defun my-defun-dispatch (doit name args &rest body)
(let ((needs-cl nil))
(dolist (arg args)
(unless (and (symbolp arg)
(or (not (eq ?& (aref (symbol-name arg) 0)))
(memq arg '(&optional &rest))))
(setq needs-cl t)))
(if needs-cl
`(cl-defun ,name ,args ,#body)
(funcall doit name args body))))
(advice-add :around 'defun 'my-defun-dispatch)
Any particular reason?
Maybe it's safe to do, and I'm sure it's possible, but I'm very dubious that you should be attempting it in the first place if you can't figure out how to go about it. I don't mean that as any kind of insult; I just suspect that a fundamental change like this could easily cause problems, so you ought to have a solid handle on elisp first before trying it.
I realise that's a bit of a non-answer, but I thought it was worth saying.
FYI cl-defun is defined in terms of defun.

Write-only buffer?

I would like to imitate the way how most consoles work in a buffer, is there any way to do that? I.e. only allow appending text to the buffer, but not deleting?
Probably I could disable or advise some built-in functions which delete characters, but I'm afraid this isn't a very scalable solution... I could miss some.
As mentioned, you can set the read-only text-property. Or more simply you can set the buffer-read-only variable and then write a few commands that override it. For example (guaranteed 100% untested code ahead):
(defun append-only-s-i-c ()
(let ((inhibit-read-only (eobp)))
(call-interactively 'self-insert-command)))
(defvar append-only-mode-map
(let ((map (make-sparse-keymap)))
(define-key map [remap self-insert-command] 'append-only-s-i-c)
map))
(define-derived-mode append-only-mode nil "Append-Only"
"Here's the doc."
(set (make-local-variable 'buffer-read-only) t))
As demonstrated by this example, the read-only-ness of text can be overriden by a command, so even the read-only text-property won't guarantee 100% that the text will never be modified, but fairly few commands override the read-only information, so it should not be a serious problem in practice.
Another approach would be to use before-change-functions and signal an error from there if the modification takes place before EOB. Might be a better approach:
(defun append-only-b-c-f (beg end)
(if (< beg (point-max)) (error "Can't modify text: append-only!")))
(define-derived-mode append-only-mode nil "Append-Only"
"Here's the doc."
(add-hook 'before-change-functions #'append-only-b-c-f nil 'local))
I believe you want to set the read-only property on text as it is inserted, see special properties

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?

in Emacs, what's the best way for keyboard-escape-quit not destroy other windows?

EDIT: I understand there is keyboard-quit (which is normally bound to C-g); but I'm more interested to know about how one deals with editing functions that come with Emacs (like in this case). I run into this kind of situations from time to time when I want to change just a little bit of some build-in functions.
In emacs, when you hit M-ESC ESC (or ESC three times), you can get out of a lots of situations like transient-mark, etc. But I habitually hit the escape key (I actually remap this to a single hit of the escape key) more than I intended, and that ends up killing my windows configuration, which is quite annoying. The function keyboard-escape-quit is defined in simple.el:
(defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
(interactive)
(cond ((eq last-command 'mode-exited) nil)
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(current-prefix-arg
nil)
((and transient-mark-mode mark-active)
(deactivate-mark))
((> (recursion-depth) 0)
(exit-recursive-edit))
(buffer-quit-function
(funcall buffer-quit-function))
((not (one-window-p t))
(delete-other-windows))
((string-match "^ \\*" (buffer-name (current-buffer)))
(bury-buffer))))
And I can see that I don't want the lines:
((not (one-window-p t))
(delete-other-windows))
But what is the best way to modify this function? I can see only two ways: 1) modify simple.el 2) copy this function to my .emacs file and do the modifications there. Both ways are not really good; ideally I would like to see something on the line of defadvice, but I can't see how I can do it in this case.
You could use around advice and redefine the offending function to do what you want (i.e. one-window-p should always return t):
(defadvice keyboard-escape-quit (around my-keyboard-escape-quit activate)
(let (orig-one-window-p)
(fset 'orig-one-window-p (symbol-function 'one-window-p))
(fset 'one-window-p (lambda (&optional nomini all-frames) t))
(unwind-protect
ad-do-it
(fset 'one-window-p (symbol-function 'orig-one-window-p)))))
This kind of acts like a (let ...) but has to be more complicated because you need to override a function for a limited scope instead of a variable.
I usually find that 'keyboard-quit (C-g) works to get out of all of those situations.
However, if you really want to have a variant of this function, I think that copying to your .emacs file (and renaming, I usually usa a prefix of bp) and making the edits there is probably the best option.
EDIT, in response to edit: In general, whenever I want an edited version of an emacs function, I either write it myself, or copy it to my .emacs, rename it bp-whotever and then do appropriate edits.
The downside of this is that my .emacs is HUGE, and probably extra-crufty with ancient functions that are nolonger used... the upside is that whenever I need to write something new, I've got tons of sample code to look at...
Here's another, simpler piece of advice that takes advantage of the fact that keyboard-escape-quit calls buffer-quit-function before closing windows:
(defadvice keyboard-escape-quit
(around keyboard-escape-quit-dont-close-windows activate)
(let ((buffer-quit-function (lambda () ())))
ad-do-it))
Works with Emacs 25.1. (I originally used #scottfrazer's advice, but it's unhappy in 25.1. Haven't bothered debugging yet.)
A single press of the Escape key, by default, acts as a Meta prefix key; that is, a keybinding which involves the Meta key.
Triple-pressing the Escape key will run keyboard-escape-quit, which is like keyboard-quit but with more of a "do what I mean" behaviour.
This code may help with your use case. You can use this in your Emacs init file:
;;; esc always quits
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
(global-set-key [escape] 'keyboard-quit)
I'm more interested to know about how one deals with editing functions that come with Emacs (like in this case). I run into this kind of situations from time to time when I want to change just a little bit of some build-in functions.
This is exactly the purpose for which I created the library el-patch. You would put this in your init-file:
(el-patch-defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
(interactive)
(cond ((eq last-command 'mode-exited) nil)
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(current-prefix-arg
nil)
((and transient-mark-mode mark-active)
(deactivate-mark))
((> (recursion-depth) 0)
(exit-recursive-edit))
(buffer-quit-function
(funcall buffer-quit-function))
(el-patch-remove
((not (one-window-p t))
(delete-other-windows)))
((string-match "^ \\*" (buffer-name (current-buffer)))
(bury-buffer))))
Here's a new way using cl-lib instead of cl which is now deprecated:
;; Make it so keyboard-escape-quit doesn't delete-other-windows
(defadvice keyboard-escape-quit
(around keyboard-escape-quit-dont-delete-other-windows activate)
(cl-letf (((symbol-function 'delete-other-windows)
(lambda () nil)))
ad-do-it))
You'll need to make sure prior to it you have called:
(require 'cl-lib)