Search code examples
emacsfont-lock

function using font lock functions requires restarting font lock mode


I am confused about how font lock mode gets engaged. I do not have a statement that launches font lock mode in my init.el, but apparently it always runs as a minor mode. Furthermore I have the following function:

(defun testregexfunc ()
  (interactive)
  (make-variable-buffer-local 'font-lock-extra-managed-props)
  (add-to-list 'font-lock-extra-managed-props 'invisible)
  (font-lock-add-keywords nil
                          '(("\\(\\[\\)\\([a-zA-Z0-9_]+\\)\\(\\]\\)"
                             (1 '(face nil invisible t))
                             (3 '(face nil invisible t))))))

It uses font-lock specific things. But it only takes effect once I do M-x testregexfunc followed by M-x font-lock-mode twice. First time disables font lock mode second time starts it. But it is not running as a major mode now, as the buffer still displays whatever mode the buffer was in before. Okay, so I guess the function sets some values and only take effect once the mode restarts. I figured maybe I need to add a hook to font lock mode like this:

(add-hook
 'font-lock-mode
 'testregexfunc)

No... does not do anything. What do I need to do to not have to restart font lock mode for the function to work?

I got that function from here and modified it some. I don't understand most of its definition and the documentation on font lock does not really help me much:

https://emacs.stackexchange.com/questions/28154/using-font-lock-regexp-groups


Solution

  • I think the functions you are looking for are font-lock-flush and font-lock-ensure which together declare the buffer's font-locking out-of-date and then refontify it. So, you could alter your function as follows,

    (defun testregexfunc (arg)
      "Fontify buffer with new rules. With prefix arg restore default fontification."
      (interactive "P")
      (if arg
          (font-lock-refresh-defaults)      ;restore the defaults for the buffer
        (make-variable-buffer-local 'font-lock-extra-managed-props)
        (add-to-list 'font-lock-extra-managed-props 'invisible)
        (font-lock-add-keywords nil ;make the "[" and "]" invisible
                                '(("\\(\\[\\)\\([a-zA-Z0-9_]+\\)\\(\\]\\)"
                                   (1 '(face nil invisible t))
                                   (3 '(face nil invisible t)))))
        (font-lock-flush)                   ;declare the fontification out-of-date
        (font-lock-ensure)))                ;fontify the buffer using new rules