I would like to redefine an existing function foo
, but for a specific buffer only.
(defun foo ()
(message "Not done:("))
I was hopping this will do:
(make-local-variable 'foo)
(fset 'foo #'(lambda () (message "Done!")))
But it does not. Any ideas?
[EDIT: Alternatively, because the function is bounded to a key, it would suffice to modify the binding just for the current buffer. But I don't see how to do it. Local keymap is shared by the all buffers in the major mode. Modifying it modifies the bindings in all the buffers with this major mode.
The only ugly solution which I am able to think of, is is to set a keymap text-property for the whole buffer. Is this the only way to proceed?]
Buffers in Emacs editing are objects that have distinct names and hold text that can be edited. Buffers appear to Lisp programs as a special data type. You can think of the contents of a buffer as a string that you can extend; insertions and deletions may occur in any part of the buffer. See Text.
A buffer-local variable has a buffer-local binding associated with a particular buffer. The binding is in effect when that buffer is current; otherwise, it is not in effect. If you set the variable while a buffer-local binding is in effect, the new value goes in that binding, so its other bindings are unchanged.
At startup, the *scratch* buffer contains a short message, in the form of a Lisp comment, that explains what it is for. This message is controlled by the variable initial-scratch-message , which should be either a documentation string, or nil (which means to suppress the message).
To move between the buffers, type C-x b. Emacs shows you a default buffer name. Press Enter if that's the buffer you want, or type the first few characters of the correct buffer name and press Tab. Emacs fills in the rest of the name.
You can make a function which does the overriding for you, something along the lines of this:
(defun override-the-keymap ()
(let ((my-overriding-keymap (make-sparse-keymap)))
(set-keymap-parent my-overriding-keymap (current-local-map))
(use-local-map my-overriding-keymap)
(define-key my-overriding-keymap (kbd "C-M-x")
'(lambda () (interactive) (message "Done!")))))
Obviously customize the key binding appropriately. This has the effect only in the current buffer.
The value and function properties of a given symbol are separate, and so presumably make-local-variable
will only affect the value, whereas fset
operates on the function property.
You are probably better off describing in more detail what it is that you want to do, but one generic solution would be to use "around advice" to wrap the original function with your own code.
(defadvice foo (around my-foo-wrapper)
(if (not (and (boundp 'use-my-foo) 'use-my-foo))
ad-do-it
(message "Not done:(")))
(ad-activate 'foo)
;; in special buffer
(set (make-local-variable 'use-my-foo) t)
EDIT: (regarding the additional key-map comments)
Perhaps then you want to define a minor-mode for use in your special buffer. Minor mode key-maps take precedence over those of the major mode, so you would simply need to define that same binding in the minor mode's map. See define-minor-mode
.
How about writing your symbol-functions to symbol-values, then evaluate them by some other function?
(defvar my-buffer-local-function
(lambda ()
(interactive)
(message "Default message"))
"This variable contains buffer local function")
(make-variable-buffer-local 'my-buffer-local-function)
(defun run-my-buffer-local-function (&rest args)
"This function run buffer-local function"
(interactive)
(if (called-interactively-p 'any) ;To call interactively AND to
;be able to have elisp-calls
(call-interactively my-buffer-local-function)
(apply my-buffer-local-function args)))
(setq my-buffer-local-function
(lambda (&optional arg)
(interactive "sinsert message: ")
(message (concat "Not so default message: " arg))))
The visible bad side, is that it works well if my-buffer-local-function
is interactive. If not, run-my-buffer-local-function
will still be interactive, and visible in M-x
list. I think you cannot make sometimes-interactive functions, because interactive
should be top-level call.
Btw, you can name function and value with the same name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With