diff --git a/org/config/emacs.org b/org/config/emacs.org index e4fcb60..1595a84 100644 --- a/org/config/emacs.org +++ b/org/config/emacs.org @@ -510,6 +510,50 @@ This is a wrapper around `eval-after-load' that: (car body)))))) #+end_src +** A better custom variable setter +:PROPERTIES: +:CUSTOM_ID: Basic-Configuration-A-better-custom-variable-setter-56z4ni61lhj0 +:END: +Something people often forget about custom variables in Elisp is they +can have a custom setter that will run some code if we set the +variable properly with ~customize-set-variable~, so ~setq~ shouldn’t be +the user’s choice by default. But repeatedly writing +~customize-set-variable~ can get tiring and boring. So why not take the +best of both world and create ~csetq~, a ~setq~ that uses +~customize-set-variable~ under the hood while it keeps a syntax similar +to the one ~setq~ uses? +#+begin_src emacs-lisp +(defmacro csetq (&rest forms) + "Bind each custom variable FORM to the value of its VAL. + +FORMS is a list of pairs of values [FORM VAL]. + +If FORM has a custom setter, use it to set FORM to VAL. +Otherwise, use `set-default'. + +\(fn [FORM VAL]...)" + (declare (debug (&rest sexp form)) + (indent 1)) + ;; Check if we have an even number of arguments + (when (= (mod (length forms) 2) 1) + (signal 'wrong-number-of-arguments (list 'csetq (1+ (length forms))))) + (let (sexps) + ;; Transform FORMS into a list of pairs (FORM . VALUE) + `(progn ,@(progn + (while forms + (let ((form (pop forms)) + (value (pop forms))) + (push `(customize-set-variable ',form ,value) + sexps))) + (reverse sexps))))) +#+end_src + +I first got inspired by [[https://oremacs.com/2015/01/17/setting-up-ediff/][this blog article]] (archived article, just in +case) but it seems the code snippet no longer works properly, so not +only did I have to modify it to make it work with an arbitrary amount +of arguments (as long as it’s pairs of variables and their value), but +I also had to make the code simply work. + * Custom Elisp :PROPERTIES: :CUSTOM_ID: Custom-Elispksvjel6184j0