Skip to main content
5 of 11
edited tags
Drew
  • 79.1k
  • 10
  • 123
  • 257

init.el and trampling of custom-set-variables

My new init.el uses require to load various settings that I have organised into directories and files. This is an attempt to tame what was a very large and messy init.el and custom.el file. Also I ultimately hope to use org files to better document each setting.

I'm trying (and largely failing) to make this setup play nicely with customize.

My old init.el has grown over a few years and makes liberal use of setq.

But reading this: Advantages of setting variables with setq instead of custom.el?

And these: https://www.reddit.com/r/emacs/comments/b1jzno/need_help_making_my_initel_file_look_cleaner_its/

https://www.reddit.com/r/emacs/comments/9rrhy8/emacsers_with_beautiful_initel_files_what_about/

I decided to try replacing setq with custom-set-variables for custom variables.

The problem I have is that despite the fact that I've explicitly set variables using custom-set-variables, customize appears to take all my explicit settings and appends them to the end of my init.el or in a separate file if custom-file is set. This duplicates the settings needlessly, and create more, not less mess.

What's worse is that complicated expressions seems to get rendered incorrectly when trampled, the below:

(let* ((default-directory temporary-file-directory)
       (emacs-temp (expand-file-name current-user "emacs-saves")))
  (custom-set-variables '(backup-directory-alist (`(("." . ,emacs-temp))))
            '(auto-save-file-name-transforms (`(("." ,emacs-temp t))))))

Is trampled with custom.el containing an out of scope emacs-temp. No such issues are seen using setq:

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(auto-save-file-name-transforms ((\` (("." (\, emacs-temp) t)))))
 '(backup-by-copying t)
 '(backup-directory-alist ((\` (("." \, emacs-temp))))))

It appears I can prevent customize writing anything out by using:

(setq custom-file null-device)

But this is problematic because customize settings made outside of my init.el and it's require statements, will then never be recorded. Apart from my own (very occasional) use of customize, other packages may try to write to the custom file - eg package-selected-packages.

The way I see it - customize should only be writing out settings that are not already explicitly set in init.el, etc. This will avoid trampling of any settings I've explicitly made.

Any other settings made within customize (or elsewhere) that would not trample anything explicitly set in init.el, could then be appended to init.el, or directed elsewhere by custom-file.

The closest behaviour to this seems to be the use of setq not custom-set-variables which seems to be ignored by customize. However I take the points that use of defcustom keywords means that setq use can be problematic.

My question is - how do I correctly and safely initialize custom values in my initialization script(s), such that they are not then trampled by customize saving these values back down to a file, and without preventing other customize values from being saved to file?

Will use-package help me? Can I make setq use safe without interleaving setup before and after initialization?

Phil
  • 545
  • 5
  • 18