1

I would like to have an interface in customize for a package I'm writing. Whenever I set the values it should update an external config file, too. So the values should be saved in the emacs custom file and in an additonal external file.

For the external file the values set by the user have to be transformed to a slightly different format.

In turn when the external file was manipulated manually the customization interface should reflect this changes and load the current values of this external file.

Is this possible and if so can anyone give me some pointers how I could approach this?

2

Yes. See the doc for defcustom. What you want, in particular, is :set, which you specify as a function that does two things:

  1. Sets the value. Just use the standard function for this.

  2. Does whatever else you want to do -- in this case, mirror the new setting, transforming it first, in your external file.

You can do those two things in either order, i.e., whichever order is most useful for you.

:set
  VALUE should be a function to set the value of the symbol
  when using the Customize user interface.  It takes two arguments,
  the symbol to set and the value to give it.  The function should
  not modify its value argument destructively.  The default choice
  of function is `set-default'.

See also :initialize, if you need to do something special when initializing the value.

:initialize
  VALUE should be a function used to initialize the
  variable.  It takes two arguments, the symbol and value
  given in the `defcustom' call.  The default is
  `custom-initialize-reset'.

For more information, see the Elisp manual, node Variable Definitions.


Update to respond to your comment --

You can use :initialize to initialize the variable without the :set function being called. It sounds like that's what your workaround is trying to accomplish. Again, see the Elisp manual, node Variable Definitions.

Here is an example. You will not see @@@@@@@@@@@@@@@@@@@@@@@@@@ in buffer Messages when the value is initialized (e.g., when the file with the defcustom is loaded). You will see it each time you use Customize to set the value.

(defcustom titi 42
 "jjjjjjjjjj"
  :type 'integer
  :initialize (lambda (sym defs)
                (custom-initialize-default sym defs))
  :set (lambda (sym defs)
         (custom-set-default sym defs)
         (message "@@@@@@@@@@@@@@@@@@@@@@@@@@")(sleep-for 4)))
  • Thanks, I'm making progress but I still have some issues. My approach would be to save the time of the last customization through the customize interface and compare this to the file modification time. For this I need the time of the last customization. How can I get this? The :set function gets not only called when the user sets a value but also when the package is required, so I think I can't use it so save the time? – clemera Sep 30 '15 at 19:54
  • I worked around this by introducing a dummy variable at the end of the package and check if it is bound in the :set function. Now I can exclude the case where the package is required. I will accept your answer now but if you want add some more pointers how to sync the modifications, that would be great because I had so much trouble finding it. Maybe you know a better way then what I described in this comments. – clemera Sep 30 '15 at 20:47
  • The :set function is not used for initialization, if :initialize is present. – Drew Sep 30 '15 at 21:46
  • Ah, thanks I missed this sentence in the docs: custom-initialize-default: Like custom-initialize-set, but use the function set-default to set the variable, instead of the variable’s :set function. Would upvote again if I could ;) – clemera Sep 30 '15 at 22:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.