I'm trying to edit a mode's
font-lock-keywords variable to use
defcustom instead of
defconst (which it was using previously). Obviously, this is because I want to be able to easily customize the mode's font lock keywords.
Currently it's using a backquote construct to evaluate the list, like so:
(defcustom v-font-lock-keywords `( ;; builtin (,v-builtin-keywords-regexp . font-lock-builtin-face) ;; careful (,v-careful-keywords-regexp . font-lock-warning-face) ;; @ # $ ;; ("#\\(?:include\\|flag\\)" . 'font-lock-builtin-face) ("[@#$][A-Za-z_]*[A-Z-a-z0-9_]*" . 'font-lock-warning-face) ;; declaration (,v-declaration-keywords-regexp . font-lock-keyword-face) ;; ... more of the same ;; variable references ("\\($?_?[a-z]+[a-z_0-9]*\\)" 1 'font-lock-variable-name-face)) "An alist mapping regexes to font-lock faces." :type '(repeat sexp) :group 'v-mode)
The problem is, if I use this backquote / comma structure as it currently exists, I can't properly use the
customize interface to change the variable.
For example, when I customize one element of the list to have a different face, now the evaluated value for
,v-builtin-keywords-regexp gets hardcoded into my
(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. ... '(v-font-lock-keywords (quote (("\\<\\(any\\(?:_\\(?:\\(?:floa\\|in\\)t\\)\\)?\\|b\\(?:ool\\|yte\\(?:ptr\\)?\\)\\|charptr\\|f\\(?:32\\|64\\)\\|i\\(?:1\\(?:28\\|6\\)\\|64\\|nt\\|[8t]\\)\\|rune\\|s\\(?:ize_t\\|tring\\)\\|u\\(?:1\\(?:28\\|6\\)\\|32\\|64\\)\\|voidptr\\)\\>" . font-lock-builtin-face) ("\\<\\(C\\|__global\\|as\\(?:sert\\)?\\|break\\|continue\\|defer\\|error\\|go\\(?:to\\)?\\|i\\(?:mport\\|nline\\|[ns]\\)\\|live\\|mut\\|or\\|panic\\|unsafe\\)\\>" . font-lock-warning-face) ("[@#$][A-Za-z_]*[A-Z-a-z0-9_]*" quote font-lock-warning-face) ("\\<\\(enum\\|fn\\|interface\\|return\\|struct\\|type\\)\\>" . font-lock-keyword-face) ...))))
I don't want the current values to get hardcoded into there; I just want it to keep using the backquote instead. Or somehow dynamically embed the variable reference there. But I don't see a way to do this.
Is this even doable with
customize? Perhaps I merely need to use
defvar to modify the variable instead of
defcustom and simply edit it in raw Elisp, just eschewing the
customize interface altogether?
For reference, there is some similar code in the Emacs trunk for
(defcustom dns-mode-font-lock-keywords `((,(concat "^$" (regexp-opt dns-mode-control-entities)) 0 ,dns-mode-control-entity-face) ("^$[a-z0-9A-Z]+" 0 ,dns-mode-bad-control-entity-face) (,(regexp-opt dns-mode-classes) 0 ,dns-mode-class-face) (,(regexp-opt dns-mode-types) 0 ,dns-mode-type-face)) "Font lock keywords used to highlight text in DNS master file mode." :version "26.1" :type 'sexp :group 'dns-mode)
This variable has the exact same problem which you'll see if you try to edit it in the customize interface via
M-x customize-variable dns-mode-font-lock-keywords (you'll have to load