Elisp: Syntax Color Comments

By Xah Lee. Date: . Last updated: .

Problem

You are writing a major mode for a language. You want comment be syntax colored.

emacs doge comment coloring
coloring of comment and string.

Here's the doge text.

-*- coding: utf-8 -*-
         "Wow"

                   ▄              ▄
 such             ▌▒█           ▄▀▒▌
   simple mode    ▌▒▒█        ▄▀▒▒▒▐
                 ▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐  # comment
               ▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐
             ▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌
            ▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌
            ▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐   # colored
           ▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌
"string"   ▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌
          ▌▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒▐
          ▐▒▒▐▀▐▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌
          ▐▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒▐
           ▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌
           ▐▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▒▄▒▒▐
 #  colored ▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌
              ▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀
     " too      ▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀   too"
                  ▒▒▒▒▒▒▒▒▒▒▀▀     Concern

Solution

The typical way to syntax color comment is via emacs syntax table. Two things you need to do:

  1. Set Syntax Table for the comment characters.
  2. Set font-lock-defaults to non-nil.

Comment and string are then automatically syntax colored, when Font Lock Mode is on.

Let's do a example.

Say our comment syntax is # to the end of line, used by Python .

Here's complete code of a major mode:

(defun my-do-syntax-table ()
  "Set local syntax table, and re-color buffer."
  (interactive)
  (let ((synTable (make-syntax-table)))
    ;; python style comment: #...
    (modify-syntax-entry ?# "<" synTable)
    (modify-syntax-entry ?\n ">" synTable)
    (set-syntax-table synTable)
    (font-lock-default-fontify-syntactically (point-min) (point-max))))

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

Now, open a new buffer, type the following:

some "thing" # wow

Then, M-x my-do-syntax-table, you see that the string and comment are colored.

How Does Syntax Coloring Comment Works

the essential things you need to know are:

Setup Syntax Table for Programing Language Comment

Here's the appropriate syntax table setup for popular language comments syntax.

(defun my-python-syntax-table ()
  "Set local syntax table, and re-color buffer."
  (interactive)
  (let ((synTable (make-syntax-table)))
    ;; python style comment: #...
    (modify-syntax-entry ?# "<" synTable)
    (modify-syntax-entry ?\n ">" synTable)
    (set-syntax-table synTable)
    (font-lock-fontify-buffer)))

(defun my-java-line-syntax-table ()
  "Set local syntax table, and re-color buffer."
  (interactive)
  (let ((synTable (make-syntax-table)))
    ;; C++ style comment // ...
    (modify-syntax-entry ?\/ ". 12b" synTable)
    (modify-syntax-entry ?\n "> b" synTable)
    (set-syntax-table synTable)
    (font-lock-fontify-buffer)))

(defun my-java-block-syntax-table ()
  "Set local syntax table, and re-color buffer."
  (interactive)
  (let ((synTable (make-syntax-table)))
    ;; comment style /* ... */
    (modify-syntax-entry ?\/ ". 14" synTable)
    (modify-syntax-entry ?* ". 23" synTable)
    (set-syntax-table synTable)
    (font-lock-fontify-buffer)))

(defun my-java-syntax-table ()
  "Set local syntax table, and re-color buffer."
  (interactive)
  (let ((synTable (make-syntax-table)))
    ;; comment style /* ... */ and // ...
    (modify-syntax-entry ?\/ ". 124" synTable)
    (modify-syntax-entry ?* ". 23b" synTable)
    (modify-syntax-entry ?\n ">" synTable)
    (set-syntax-table synTable)
    (font-lock-fontify-buffer)))

(defun my-wolfram-syntax-table ()
  "Set local syntax table, and re-color buffer."
  (interactive)
  (let ((synTable (make-syntax-table)))
    ;; Wolfram Language style comment (* ... *)
    (modify-syntax-entry ?\("()1n" synTable)
    (modify-syntax-entry ?\) ")(4n" synTable)
    (modify-syntax-entry ?* ". 23n" synTable)
    (set-syntax-table synTable)
    (font-lock-fontify-buffer)))
test comment coloring

# python

// java line comment

/*
java block comment
*/

(*
Wolfram language, pascal, etc comment.
*)

Syntax Table Supports Limited Comment Syntax

Emacs's syntax table only supports comment syntaxes that are used in mainstream languages.

Emacs Syntax Table Support of Comment Syntax Types
ExampleSyntax Type
# ...\n (Python, Perl, PHP, Bash, shells)
; ...\n (lisp)
' ...\n (Visual Basic)
Start with a char to newline char.
// ... \n (C, C++, C#, Java, JavaScript, PHP)Start with 2 identical chars to newline char.
(* ... *) (Mathematica, Pascal, OCaml, Applescript)
{- ... -} (Haskell)
A matching pair chars with another char.
/* ... */ (C, C++, C#, Java, JavaScript)Two chars used in a ad hoc way as matching pair.

If your language's comment syntax is not one of the above, then emacs syntax table is not able to capture it.

To handle non-mainstream comment syntax, you have 2 ways:

Elisp, font lock, syntax coloring

Emacs lisp, writing a major mode. Essentials