Save value of old function in elisp to call - emacs

I have a function:
(defun alternate-narrow-to-region (start end)
(message "Hi!")
(narrow-to-region start end))
I want all uses of narrow-to-region, except for the one in this function body, to call alternate-narrow-to-region (so narrow-to-defun, narrow-to-page, direct calls to narrow-to-region, end up calling alternate-narrow-to-region).
How do I do this?

To save the original definition (which is in your question title but not in the text), use defalias:
(defalias 'ORIGINAL-narrow-to-region (symbol-function 'narrow-to-region)
"My doc string about this.")
Note that in this case you do not want to use this:
(defalias 'FOREVER-narrow-to-region 'narrow-to-region
"My doc string about this.")
What you want to do is copy the function definition at a given point in time. The latter use of defalias instead has the effect of pointing FOREVER-narrow-to-region to whatever the current definition of narrow-to-region is. If you redefine narrow-to-region then it will point to the new definition, which is presumably not what you want in this case.
As for the question implied by your text, the answer is that you cannot. You cannot get Emacs to always use your function instead of narrow-to-region. This is explained at your other question: code that calls narrow-to-region and is compiled will continue to (in effect) call the original narrow-to-region. (It is not really called at all. Its code is effectively inlined.)
If you wanted to get Emacs to use a replacement command only when called interactively, you could of course remap the original command's key bindings to the replacment. But that does not seem to be the case here.

Related

indent-[code-]rigidly called from emacs LISP function

I'm trying to write an emacs LISP function to un-indent the region
(rigidly). I can pass prefix arguments to indent-code-rigidly or
indent-rigidly or indent-region and they all work fine, but I don't
want to always have to pass a negative prefix argument to shift things
left.
My current code is as below but it seems to do nothing:
(defun undent ()
"un-indent rigidly."
(interactive)
(list
(setq fline (line-number-at-pos (region-beginning)))
(setq lline (line-number-at-pos (region-end)))
(setq curIndent (current-indentation))
;;(indent-rigidly fline lline (- curIndent 1))
(indent-region fline lline 2)
;;(message "%d %d" curIndent (- curIndent 1))
)
)
I gather that (current-indentation) won't get me the indentation of the first line
of the region, but of the first line following the region (so a second quesiton is
how to get that!). But even when I just use a constant for the column (as shown,
I don't see this function do any change.
Though if I uncomment the (message) call, it displays reasonable numbers.
GNU Emacs 24.3.1, on Ubuntu. And in case it matters, I use
(setq-default indent-tabs-mode nil) and (cua-mode).
I must be missing something obvious... ?
All of what Tim X said is true, but if you just need something that works, or an example to show you what direction to take your own code, I think you're looking for something like this:
(defun unindent-rigidly (start end arg &optional interactive)
"As `indent-rigidly', but reversed."
(interactive "r\np\np")
(indent-rigidly start end (- arg) interactive))
All this does is call indent-rigidly with an appropriately transformed prefix argument. If you call this with a prefix argument n, it will act as if you had called indent-rigidly with the argument -n. If you omit the prefix argument, it will behave as if you called indent-rigidly with the argument -1 (instead of going into indent-rigidly's interactive mode).
There are a number of problems with your function, including some vary
fundamental elisp requirements. Highly recommend reading the Emacs Lisp
Reference Manual (bundled with emacs). If you are new to programming and lisp,
you may also find An Introduction to Emacs Lisp useful (also bundled with
Emacs).
A few things to read about which will probably help
Read the section on the command loop from the elisp reference. In particular,
look at the node which describes how to define a new command and the use of
'interactive', which you will need if you want to bind your function to a key
or call it with M-x.
Read the section on variables from the lisp reference
and understand variable scope (local v global). Look at using 'let' rather
than 'setq' and what the difference is.
Read the section on 'positions' in the elisp reference. In particular, look at
'save-excursion' and 'save-restriction'. Understanding how to define and use
the region is also important.
It isn't clear if your writing this function just as a learning exercise or
not. However, just in case you are doing it because it is something you need to
do rather than just something to learn elisp, be sure to go through the Emacs
manual and index. What you appear to need is a common and fairly well supported
requirement. It can get a little complicated if programming modes are involved
(as opposed to plain text). However, with emacs, if what you need seems like
something which would be a common requirement, you can be fairly confident it is
already there - you just need to find it (which can be a challenge at first).
A common convention is for functions/commands to be defined which act 'in
reverse' when supplied with a negative or universal argument. Any command which
has this ability can also be called as a function in elisp code with the
argument necessary to get that behaviour, so understanding the inter-play
between commands, functions and calling conventions is important.

What is the difference between using "setq" or not to set an Emacs setting?

Very simple question but confuse me for some time:
(setq visible-bell t)
and
(visible-bell t)
both seem work.
But
(desktop-save-mode 1)
works, while
(setq desktop-save-mode 1)
not.
May I ask why is this?
They're different because they're different :)
(setq visible-bell t)
is assigning the value t to a variable named visible-bell.
(visible-bell t)
is calling a function1 named visible-bell (and passing the value t as a parameter).
(Although FYI there is no visible-bell function by default in current versions of Emacs, so it's not obvious to me that this is actually working the way you think? However, assuming for the moment that you do indeed have such a function...)
Emacs Lisp is a 'Lisp-2' meaning it has separate name spaces for variables and functions, and therefore you can -- and commonly do -- have a variable and a function with the same name. Which one is being referred to is always implicit in the context of the code (e.g. setq always refers to a variable).
In short, the two pieces of code are doing very different things. This doesn't mean they couldn't have an equivalent effect (e.g. the function might simply set the value of the variable); but whether or not that's actually the case is entirely up to the definition of the function.
1 In fact the first line of code is also calling a function2: it's calling setq and passing it two parameters visible-bell and t, and setq then sets the value in accordance with its parameters. Hopefully you're now starting to see how lisp syntax works?
2 Strictly speaking, setq is actually a "special form" rather than a function, and special forms are closer to macros than to functions; but these distinctions are not important for this Q&A.
Others have told you the basic points about what setq does and about variables versus functions.
Wrt visible-bell itself:
There is no function visible-bell delivered with Emacs, in any Emacs version I know of, and there never has been. (I've checked back through Emacs 20, and by memory I believe the same was true from the beginning. There is only the variable visible-bell.
So as #phils suggested, is not clear that what you said is true: "both seem to work". Unless some extra code you are loading defines a function of that name (and then there is no way for us to comment on it, not having it to see), evaluating (visible-bell t) raises an undefined (void) function error.
Variable visible-bell is not just a variable. It is a user option, and it has been, again, since at least Emacs 20.
You should not, in general, just use setq to change the value of a user option. In many cases you won't get into trouble if you do that, but sometimes you will, and it is not a good habit to get into.
setq does not perform any special initialization or updating actions that might be appropriate for a given user option. It is not intended for user options. Or rather, user options are not intended for setq - they can be more complex than what setq can offer.
What you should use instead of setq is Customize. Either interactively (M-x customize-option RET visible-bell RET, or C-h v RET visible-bell RET followed by clicking the customize link) or using Lisp code in your init file.
If you use Lisp code then use one of these functions (not setq):
customize-set-variable
customize-set-value
custom-set-variables
Use C-h f followed by each of those function names, to see what (minor) differences there are.
There are 3 issues here.
In Emacs Lisp, the same symbol can be both variable and function.
in the case of desktop-save-mode, it's a function but also a variable.
Because it's a function, so you can call
(desktop-save-mode 1)
Because it's a variable, so you set value to it
(setq desktop-save-mode t)
You can define your own function and also a variable of the same name to test it.
Note: exactly what a function's arguments should be or what the value of a variable makes sense depends on the function or variable.
Now, a second issue. In general, for function (commands) to activate a minor mode, the convention is that a positive integer should mean to turn it on, and otherwise turn off.
Also, for command to activate a minor mode, typically there's a variable of the same name, with value of t or nil, to indicate if the mode is on.
Now, there's third issue. For command to activate the mode, before emacs 24 or so, by convention, if no arg is given, the command toggle current state.
Because all of the above, the issue is confusing. You might see in init things like this:
(desktop-save-mode 1) ; correct. To turn on.
(desktop-save-mode) ; Confusing. Should take value 1 to turn on. Usually works because by default it's off.
(desktop-save-mode t) ; wrong. Take value of positive integer to turn on.
(desktop-save-mode nil) ; Confusing. Value should be integer
(setq desktop-save-mode t) ; wrong. Shoud call function instead
(setq desktop-save-mode nil) ; wrong. Shoud call function instead
(setq desktop-save-mode 1) ; wrong. Shoud call function instead. Besides, only t and nil make sense
So, there's a lot confusion. In emacs 24 (or 23.x), the convention changed so that, if it receives no value, it will turn on, if called in elisp code. (when called interactively as command, it toggles.)
In the end, always call describe-function or describe-variable to read the doc.
Well setq (which is "set" with an auto-quoting feature) is used in assigning a value to a variable. In this example, it's obviously not required because as you mentioned, omitting it works for the first set of examples.
Basically, visible-bell is a variable, and you assign it the value "t" to enable visible bells.
However, desktop-save-mode is an interactive function, so you don't use setq to assign it a value, you call it with parameters.
One good thing to do when you're not sure what something is, is to use the built-in help function:
C-h v visible-bell RET
This will return the information for visible bell -- notice the "v" in the command is because it's a variable. If you wanted to search for information on a function, you would do this:
C-h f desktop-save-mode RET
Incidentally in this case, desktop-save-mode is also a variable, but it's a read-only variable to determine whether or not desktop-save-mode is enabled, so trying to alter it will not work.

Elisp: simple wrapper over a «mouse-set-point» changes a behavior

The «mouse-set-point» is a function that is being called in Emacs with "mouse double-click" on a word to set a region around it and activate. I made a simple wrapper over it, and bound instead of the default one, like this:
(defun mouse-set-point-highlight-occurs (EVENT)
(interactive "e")
(mouse-set-point EVENT))
(global-set-key (kbd "<double-mouse-1>") 'mouse-set-point-highlight-occurs)
As you see it does nothing except for plain transfer of an argument, so the behavior shouldn't be changed. But now with double click the region appears just for a moment, and then fades. What could be wrong with it?
The short answer: you want to call mouse-set-region instead of mouse-set-point.
The longer answer: part of what you're seeing is a long standing misfeature of the way the mouse region selection code works. If you look at the code of mouse-drag-track (which is the workhorse of mouse-drag-region bound to down-mouse-1) you'll see that this function is the one that implements the mouse-set-point behavior in case of double-mouse-1 (i.e. it checks if the binding is mouse-set-point and if it is, it runs its own code instead of mouse-set-point).
In Emacs's trunk (i.e. not what will be released as 24.4 but the next one), this code has been modified to work "more normally". But even in Emacs's trunk, your code won't work right: you'll need to additionally pass a non-nil second argument to mouse-set-point in order to indicate that you don't just want to set point, but to actually set the region.

What's the best way in elisp to trap an error case

I'm trying to augment the etags-select functions so it will fall-back to a normal find-tag if find-tag at point failed. The code I've tried is:
(defun my-etags-find-tag ()
"Find at point or fall back"
(interactive)
(unless (etags-select-find-tag-at-point)
(etags-select-find-tag)))
(global-set-key (kbd "C-f") 'my-etags-find-tag)
However this fails when point is not at a valid tag. Instead I get a error thrown by etags-select-find-tag-at-point:
etags-select-find-tag-at-point: Wrong type argument: char-or-string-p, nil
In this case I just have to repeat the test done by etags-select-find-tag-at-point:
(defun my-etags-find-tag ()
"Find at point or fall back"
(interactive)
(if (find-tag-default)
(etags-select-find-tag-at-point)
(etags-select-find-tag)))
But it does seem a little redundant. Is it possible to trap exceptions and do alternate processing in elisp?
Try ignore-errors; eg,
(unless (ignore-errors (etags-select-find-tag-at-point))
(etags-select-find-tag))
Normally, (ignore-errors body) returns whatever body returns; when there's error, it returns nil.
Also look at condition-case for more general condition handling.
If you have Elisp info manual installed, you can get more details from
C-hSignore-errors.
Edit:
I failed to consider the possibility that the function may return nil on success; so we probably need
(unless (ignore-errors (or (etags-select-find-tag-at-point) t))
(etags-select-find-tag))
Without modifying the original source code of etags-select.el, I see it the more reasonable option, even when it calls twice to find-tag-default. You can cheat the dynamic environment within the call to avoid the repetition of the call by memoizing it with something like:
(defun my-etags-find-tag ()
"Find at point or fall back"
(interactive)
(let ((ftd (find-tag-default)))
(flet ((find-tag-default () ftd))
(if (find-tag-default)
(etags-select-find-tag-at-point)
(etags-select-find-tag)))))
EDIT: OK, as per your request, an explanation of the code. First, note that this code achieves both questions:
It does not fail
It is more efficient than the code you show (the one you say it is redundant).
Why is it more efficient? The problem with your redundant code is that you call find-tag-default to see if it is nil, and, if it is, you call etags-select-find-tag-at-point. This function calls again to find-tag-default to obtain a default value. What my code does is to cache the value of find-tag-default by redefining the function by being just the value you calculated. The flet does that, so when etags-select-find-tag-at-point calls find-tag-default, the calculated value is returned without any further processing.

How to copy to clipboard in Emacs Lisp

I want to copy a string to the clipboard (not a region of any particular buffer, just a plain string). It would be nice if it were also added to the kill-ring. Here's an example:
(copy-to-clipboard "Hello World")
Does this function exist? If so, what is it called and how did you find it? Is there also a paste-from-clipboard function?
I can't seem to find this stuff in the Lisp Reference Manual, so please tell me how you found it.
You're looking for kill-new.
kill-new is a compiled Lisp function in `simple.el'.
(kill-new string &optional replace yank-handler)
Make string the latest kill in the kill ring.
Set `kill-ring-yank-pointer' to point to it.
If `interprogram-cut-function' is non-nil, apply it to string.
Optional second argument replace non-nil means that string will replace
the front of the kill ring, rather than being added to the list.
Optional third arguments yank-handler controls how the string is later
inserted into a buffer; see `insert-for-yank' for details.
When a yank handler is specified, string must be non-empty (the yank
handler, if non-nil, is stored as a `yank-handler' text property on string).
When the yank handler has a non-nil PARAM element, the original string
argument is not used by `insert-for-yank'. However, since Lisp code
may access and use elements from the kill ring directly, the string
argument should still be a "useful" string for such uses.
I do this:
(with-temp-buffer
(insert "Hello World")
(clipboard-kill-region (point-min) (point-max)))
That gets it on the clipboard. If you want it on the kill-ring add a kill-region form also.
The command to put your selection on the window system clipboard is x-select-text. You can give it a block of text to remember. So a (buffer-substring (point) (mark)) or something should give you what you need to pass to it. In Joe's answer, you can see the interprogram-cut-function. Look that up for how to find this.
In my .emacs file, i use this
(global-set-key "\C-V" 'yank)
(global-set-key "\C-cc" 'kill-ring-save)
I could not use Ctrl-C (or System-copy), but this may be enough in case old habits kick in.