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 .emacs
:
(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 dns-mode.el
:
(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 dns-mode
first).