1

I heard it’s better to use Customize to define variables/settings instead of just some setq inside .emacs.d… because it autoloads when loading packages, because it’s more consistent, more checked/restricted, better updated, etc. I heard the only case where it could be better not to use Customize is setting programmatically variables. Like depending upon context or other variables with functions, etc.

But is it really always the case or is there even with Customize some way of doing it? Especially, is there a way to define a variable within Customize, that would depend upon another? like org-agenda-files depending on org-directory ((setq org-agenda-files (concat org-directory "agenda.org")))? Because I’d like it to being updated wether I update org-directory. And I’d like for consistency being able to set everything within setq or Customize, and I don’t know how to do it programmatically within Customize.

EDIT : also, if that’s not possible, I’d like to know at least how to make setq acts after the definition of a variable by customize. To take again the previous example: org-directory get defined only when org is loaded, so I can’t define org-agenda-files before in my .emacs.d: what’s the proper solution? (eval-after-load 'org […])?

galex-713
  • 245
  • 2
  • 8
  • 1
    You could instead require that the value is a function, so that any time a program uses the value, it'd have to call the function (and the function would check for update). I doubt there is a mechanism for tracking updates to any variables, customized or not (this would require something on the order of triggers in a SQL database, which is a very complicated issue). – wvxvw Mar 20 '16 at 10:32
  • @wvxvw Well… ok… So could it be better to keep that within `setq`? – galex-713 Mar 20 '16 at 14:15
  • It's not clear to me what you are asking. Why not provide some Lisp pseudo code, leaving `____` for parts you would like to be able to fill in? Or in some other way make clear what you are looking for. – Drew Mar 20 '16 at 15:58
  • Using your example: `(defcustom get-org-directory 'get-org-directory-func ...)` then `(defun get-org-directory-func () "~/org")`. And then whoever uses `org-agenda-files` would have to do it via `(expand-file-name "agenda.org" (funcall get-org-directory))`. – wvxvw Mar 20 '16 at 16:47

2 Answers2

1

Take a look at the keywords for defcustom:

In particular, :set allows you to specify a function for setting the value of a variable. This means you can set the value of a variable based on that of another variable, etc.

:set-after is also available for making sure that other variables are set before this one.

Tianxiang Xiong
  • 3,848
  • 16
  • 27
  • How do you do this through Custom UI? – galex-713 Jan 26 '18 at 10:04
  • You don't. Put it in your init file. – Tianxiang Xiong Jan 26 '18 at 18:46
  • you mean like I redefine the custom variable with defcustom in my init file my copying its defcustom definition from its original definition in source code and then I add a :set-after? – galex-713 Jan 27 '18 at 19:40
  • If the customizable variable already has a `:set-after`, you can just use `customize-set-variable` to set the value to what you want. `customize-set-variable` will then apply the `:set-after` for you. – Tianxiang Xiong Jan 28 '18 at 03:12
  • of course, but for instance, `gnus-directory`, or even my initial example, `org-agenda-files`, don’t: so should I redo the defcustom in my init file or my custom file? would that be enough? – galex-713 Mar 19 '18 at 10:10
0

Ok, I found the solution: actually custom-set-variables does eval the setting values just before to set them, and you just have to modify by-hand the code within custom-file: you unquote the value and put your programmatically computed value. It just works. Although you need not to open the customize parameter, change it a bit, and save it again, because it will overwrite the programmed computation and will just save the constant raw precomputed value (so most of time the “clean” solution would be, in the packages code, to either make the setting accepts a function as value, or if it’s a filename and you actually just need to concat, make this file name relative by default to the directory you want).

galex-713
  • 245
  • 2
  • 8