Tassilo Horn writes: >> Instead of doing it this way, why not make a font-lock matcher that >> looks at *every* initial sexp atom, calls intern-soft on it, and >> applies a face that depends on properties of the found symbol? This >> way, we'd update fontification not only after load, but also after >> eval-defun, and it'd be easy to make a `declare'-form that provided >> for exceptions from the general rule. > > Also sounds good to me, and even simpler implementation-wise. So I'm > happy to implement it that way if nobody comes up with a reason why > that's not the right way. I've just tried that out in a local branch and it works good. I went with the opt-in variant for now (but I can change that) so that you define macros which should be highlighted like so: --8<---------------cut here---------------start------------->8--- (defmacro if-let (bindings then &rest else) (declare (indent 2) (font-lock-keyword t) ;; <=================== HERE! (debug ((&rest (symbolp form)) form body))) (when (and (<= (length bindings) 2) (not (listp (car bindings)))) ;; Adjust the single binding case (setq bindings (list bindings))) `(let* ,(internal--build-bindings bindings) (if ,(car (internal--listify (car (last bindings)))) ,then ,@else))) --8<---------------cut here---------------end--------------->8--- IMHO, that's better than the regexp variant. However, when a new macro with `font-lock-keyword' declaration gets defined (or the value is changed for some existing macro), we still need to flush existing elisp buffers. Else, the effect won't be visible there. I'm not sure from where I should do that. On a very fine-granular basis, the function handling the `font-lock-keyword' declaration could do that. But that would mean many flushes when a file with many such macros gets loaded. Alternatively, an after-load-function could do that, but that would miss changes manifested with C-c C-e. Bye, Tassilo