From C-h f add-hook:
HOOK should be a symbol, and FUNCTION may be any valid function. If
HOOK is void, it is first set to nil. If HOOK's value is a single
function, it is changed to a list of functions.
and from the code:
(defun add-hook (hook function &optional append local)
...
(or (boundp hook) (set hook nil))
(or (default-boundp hook) (set-default hook nil))
...
What is this good for? I assume it's somehow useful or else it wouldn't be there... I just can't think of a good use for it...
It allows you to set hook variables before the packages which define them have been loaded.
Related
I have a function in my Emacs init.el file that lets me rebuild and byte-compile it from a literate source file. It consists of a lambda function wrapped by defun and works exactly as I expect. So far, so good.
(defun tangle-init-and-reload ()
"Tangle the code blocks in init.org, byte-compile, and reload."
(lambda ()
(interactive)
;; Don't run hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle-file (concat user-emacs-directory "init.org"))
(byte-compile-file (concat user-emacs-directory "init.el"))
(load-file user-init-file))))
When I read about functions in Elisp, it appears to me that I should be able to simply use defun to define a named function and skip the lambda, so I removed the lambda and otherwise left the function intact, like so:
(defun tangle-init-and-reload ()
"Tangle the code blocks in init.org, byte-compile, and reload."
(interactive)
;; Don't run hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle-file (concat user-emacs-directory "init.org"))
(byte-compile-file (concat user-emacs-directory "init.el"))
(load-file user-init-file)))
Written this way, the function also works as expected -- as long as I call it with M-x tangle-init-and-reload RET. If I assign it a key binding, it executes on startup with one of two different side effects: With some key bindings, it attempts to overwrite init.elc while Emacs still has it open, and with others it successfully overwrites init.elc, but then re-executes on reload, causing an infinite recursion.
I'm perfectly happy to stick with the lambda version, which has no issues with key binding, but I would like to understand what magic lambda is performing and/or what it is about key binding that causes the second version to execute at startup. Can anybody explain?
For whatever it's worth, my key bindings are in a custom minor mode like so:
(defvar custom-map (make-keymap)
"Custom key bindings.")
(define-key custom-map (kbd "C-c C-i") (tangle-init-and-reload))
(define-minor-mode custom-bindings-mode
"Activates custom key bindings."
t nil custom-map)
When you define the key binding, you associate a key to a value, which in your case is:
(tangle-init-and-reload)
This is an expression that is evaluated normally, ie. you call the function when you associate the binding.
In the previous version, evaluating the same function returned a closure, you had one level of indirection, so you established a binding from a key to the function returned by the call to tangle-init-and-reload.
You can simply give the name of the function associated with the binding, by quoting it:
(define-key custom-map (kbd "C-c C-i") 'tangle-init-and-reload)
What is the best way to run a function taking arguments, eg. one that would normally be run with run-hook-with-args, inside a normal hook, eg. after-save-hook.
As a simple example, I want to add some-function to after-save-hook here, but allow it to have an additional argument.
(defun some-function (&optional arg)
(if arg 'do-this 'otherwise-do-this))
;; how to run `some-function' with argument here?
(add-hook 'after-save-hook 'some-function nil 'local)
So you've got something like this (I've changed the function name to make it less confusing).
(add-hook 'after-save-hook 'my-function nil 'local)
But you're asking how you can arrange that when after-save-hook calls my-function it passes an argument to it.
Firstly, you can't do that directly, for the probably-obvious reason that after-save-hook is a normal hook and therefore gets run in a way that doesn't provide any facility for passing arguments.
That means you have to add to the hook a function which actually does what you want.
You could create a function which does what you want like so:
(add-hook 'after-save-hook (apply-partially 'my-function ARG) nil 'local)
But approaches along these lines are really messy when it comes to inspecting and manipulating the hook later, so I recommend not doing anything like this.
Honestly, the cleanest approach is very simply to define a named function which does what you want, and add that to the hook.
(defun my-function-do-this ()
"Do This"
'do-this)
(add-hook 'after-save-hook 'my-function-do-this nil 'local)
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)
I want to define a list of accumulators with Emacs Lisp and write the following code, but I got a error saying that initV is a void variable. It seems initV is not evaluated in the function define-accum. Where is I make a mistake? (I just want to know why although I know there is other ways to reach my target.)
(defun define-accum (name initV)
(defalias name (lambda (v) (+ v initV))))
(setq accums '((myadd1 . 1)
(myadd2 . 2)))
(dolist (a accums)
(define-accum (car a) (cdr a)))
(message "result = %d" (+ (myadd1 1) (myadd2 1)))
You need to use backquotes properly. This would work for you, for instance:
(defun define-accum (name initV)
(defalias name `(lambda (v) (+ v ,initV))))
See here for an explanation
Apart from using backquotes, you can activate lexical binding (if you're using Emacs 24 or newer). For example, if I put your code in a .el file and put this on the first line:
;; -*- lexical-binding: t -*-
then I get the output:
result = 5
This works because the lambda function in define-accum will reference the initV in the environment where it's being defined (thus picking the variable in the argument list), and create a closure over this variable. With dynamic binding (the default), the function would look for initV in the environment where it's being called.
To add a little to what others have said -
If the variable (initV) is never actually used as a variable, so that in fact its value at the time the accumulator is defined is all that is needed, then there is no need for the lexical closure that encapsulates that variable and its value. In that case, the approach described by #juanleon is sufficient: it uses only the value at definition time - the variable does not exist when the function is invoked (as you discovered).
On the other hand, the lexical-closure approach lets the function be byte-compiled. In the backquote approach, the function is simply represented at runtime by a list that represents a lambda form. If the lambda form represents costly code then it can make sense to use the lexical-closure approach, even though (in this case) the variable is not really needed (as a variable).
But you can always explicitly byte-compile the function (e.g. ##NAME## in your define-accum. That will take care of the inefficiency mentioned in #2, above.
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.