Emacs Lisp: Font Lock Mode Basics

By Xah Lee. Date: . Last updated: .

Here's the essential things you need to know about font-lock-mode, for writing a major mode for syntax coloring.

font-lock-mode

font-lock-defaults

font-lock-defaults Value Structure

font-lock-defaults's value should be a list. If it's nil, no coloring will happen, not even syntax table based one.

Emacs will automatically store each element of the list into a buffer local variable.

The first 4 elements of the list are critical. Their variable names and meaning are:

  1. font-lock-keywords → essentially a list of regex for coloring keywords.
  2. font-lock-keywords-only → whether to color comment and string using syntax table.
  3. font-lock-keywords-case-fold-search → whether the regex is case-sensitive.
  4. font-lock-syntax-table → syntax table just for coloring purposes.

Each of them must have particular form. Here's their structure:

font-lock-keywords
It can have many forms, but most commonly, it is list of pairs. For each pair, the first part is a regex, the second part is the face to apply.
font-lock-keywords-only
should be t or nil . If t, the coloring by Syntax Table is not done (they are simply not colored). By default it's nil.
font-lock-keywords-case-fold-search
should be t or nil. t means use case-insensitive regex match when searching for keywords to highlight. By default it's nil.
font-lock-syntax-table
should be either nil or a Association List. Each element is a cons cells of the form (cons char-or-string string). These are used to set up a syntax table for syntactic fontification. If nil, buffer's syntax table is used for this purpose. (it calls syntax-table to get the current syntax table) [see Emacs Lisp: Syntax Table]

The most important is the first element font-lock-keywords. It takes many forms. See elisp manual for detail: Search-based Fontification (ELISP Manual)

Basic Example

Here's a basic example.

Suppose you have a basic language like HTML.

You want to color any string of the form <h1> and </h1>

And you want to color text between the tags. (assume there is no linebreak, and does not contain greater/less characters.)

Save the following in a file.

;; a simple major mode, my-mode

(defvar my-highlights nil "first element for `font-lock-defaults'")

(setq my-highlights
      '(("<h1>\\|</h1>" . 'font-lock-function-name-face)
        ("<h1>\\([^<]+?\\)</h1>" . (1 'font-lock-constant-face))))

(define-derived-mode my-mode fundamental-mode "my"
  "major mode for editing my language code."
  (setq font-lock-defaults '(my-highlights)))

Now, copy and paste the above code into a buffer, then Alt+x eval-buffer.

Now, type following code into a buffer:

<h1>something</h1>

Now, M-x myhtml-mode, you see words colored.

elisp font lock mode 2021-09-13
elisp font lock mode example 2021-09-13

[see Emacs Lisp: How to Define Face]

[see Emacs Lisp: Syntax Table]