Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I set buffer-local value for a variable defined by defcustom?

Tags:

emacs

elisp

In emacs, we can define customizable user option variable.

defcustom - Programming in Emacs Lisp http://www.gnu.org/software/emacs/manual/html_node/eintr/defcustom.html

And we can make variable to have buffer-local binding.

Creating Buffer-Local - GNU Emacs Lisp Reference Manual http://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Buffer_002dLocal.html#Creating-Buffer_002dLocal

If I want to make non-customizable variable, I can use make-local-variable or setq-local.

But I can't find any ways how to make customizable variable to have buffer-local binding.

Even if I call make-local-variable for variable defined by defcustom, custom-set-variables set to global-value.

If I call setq-local, value is set to local-variable. It is better. But I don't think this is best practice.

Is there any valid ways how to set buffer-local value for a variable defined by defcustom?

like image 547
kumar8600 Avatar asked Feb 20 '14 18:02

kumar8600


3 Answers

The answer is: You can't, at least not using the Customize UI.

What you can do is add a sexp that sets the buffer-local value of the variable to your init file.

Do one of the following:

  • Make it always buffer-local, no matter what the buffer is:

    (make-variable-buffer-local 'the-variable)

    You can put this anywher in your init file.

  • Make it buffer-local only for the current buffer, i.e., for some buffer after you select it:

    (make-local-variable 'the-variable)

    For that, you need to put the sexp in a sexp that selects the buffer you want. That could be, for example:

    (with-current-buffer (get-buffer-create "the-buffer-name") (make-local-variable 'the-variable))

    That assumes that the buffer can be reasonably created or already exists. If you do this, do it after your custom-file has been loaded. That is, in your init file, either after loading custom-file (which I recommend) or, if you do not use custom-file, after any code generated automatically by Customize (e.g., custom-set-variables).

    You can alternatively put the make-local-variable sexp on a mode hook, so whenever you are in a buffer that has a particular mode, it is executed.

All of that said, I submitted an enhancement request to Emacs Dev in 2012, requesting that user's be able to use the Customize UI to set (and possibly save) buffer-local values of user options. It sleeps in category "wishlist", so far.

like image 78
Drew Avatar answered Oct 22 '22 16:10

Drew


After defcustom form write

(make-variable-buffer-local 'my-var)

Now, if you change the value in some buffer, other buffers will keep resp. deliver the old customized one.

like image 30
Andreas Röhler Avatar answered Oct 22 '22 15:10

Andreas Röhler


The problem is that Customize is mostly designed for persistent configuration, i.e. configuration that is saved in the config file so it also applies to future Emacs sessions. But buffers are not persistent: when you restart Emacs you get a new buffer object.
So persistent customization "per-buffer" is not a clearly defined concept. We could/should add Customize support for settings that are specific to some major modes (i.e. "per-mode" settings), on the other hand.

like image 1
Stefan Avatar answered Oct 22 '22 17:10

Stefan