Emacs Lisp: How to Color Comment in Major Mode

By Xah Lee. Date: . Last updated: .

This page shows how to implement comment coloring for writing a major mode.

emacs doge comment coloring
coloring of comment and string. 〔doge.txt

Problem

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

(For how to write a command to comment/uncomment, see: Emacs Lisp: How to Write Comment Command in Major Mode)

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 will then automatically be syntax colored, when font-lock-mode is on. (it is on by default)

Let's do a example.

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

Here's complete code of a major mode:

;; sample mode that does coloring of python style commment syntax

(defvar xpy-mode-syntax-table nil "Syntax table for `xpy-mode'.")

(setq xpy-mode-syntax-table
      (let ( (synTable (make-syntax-table)))
        ;; python style comment: “# …”
        (modify-syntax-entry ?# "<" synTable)
        (modify-syntax-entry ?\n ">" synTable)
        synTable))

(define-derived-mode xpy-mode prog-mode "xpy"
  "xpy-mode is a major mode for editing language xpy."

  (setq font-lock-defaults (list nil nil))

  (set-syntax-table xpy-mode-syntax-table)
  ;; actually no need, because our syntax table name is “xpy-mode” + “-syntax-table”, so define-derived-mode will find it and set it
  )

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

Now, open a new buffer, type the following:

some "thing" # wow

Then, M-x xpy-mode, you see that the string and comment are colored.

How Does Syntax Coloring Works

3 essential things you need to know.

  1. font-lock-mode
  2. font-lock-defaults
  3. syntax table

Font Lock Mode

Emacs Lisp: Font Lock Mode Basics

Syntax Table

Emacs Lisp: Syntax Table Tutorial

Here's the appropriate syntax table setup for popular languages.

C++ Style Comments

Comment style of the form //…

(defvar xcpp-mode-syntax-table nil "Syntax table for `xcpp-mode'.")

(setq xcpp-mode-syntax-table
      (let ( (synTable (make-syntax-table)))
        ;; C++ style comment “// …”
        (modify-syntax-entry ?\/ ". 12b" synTable)
        (modify-syntax-entry ?\n "> b" synTable)
        synTable))

(define-derived-mode xcpp-mode prog-mode "xcpp"
  "xcpp-mode is a major mode for editing language xcpp."
  (setq font-lock-defaults (list nil)))

Java Style Comments

Comment style of the form /*…*/

(defvar xjv-mode-syntax-table nil "Syntax table for `xjv-mode'.")

(setq xjv-mode-syntax-table
      (let ( (synTable (make-syntax-table)))
        ;; comment style “/* … */”
        (modify-syntax-entry ?\/ ". 14" synTable)
        (modify-syntax-entry ?* ". 23" synTable)
        synTable))

(define-derived-mode xjv-mode prog-mode "xjv"
  "xjv-mode is a major mode for editing language xjv."
  (setq font-lock-defaults (list nil)))

Haskell Style Comments

Here's example for comment style of the form

etc.

(defvar xwl-mode-syntax-table nil "Syntax table for `xwl-mode'.")

(setq xwl-mode-syntax-table
      (let ((synTable (make-syntax-table)))
        ;; Wolfram Language style comment “(* … *)”
        (modify-syntax-entry ?\( ". 1" synTable)
        (modify-syntax-entry ?\) ". 4" synTable)
        (modify-syntax-entry ?* ". 23" synTable)
        synTable))

(define-derived-mode xwl-mode prog-mode "xwl"
  "xwl-mode is a major mode for editing language xwl."
  (setq font-lock-defaults (list nil)))

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:

Writing Major Mode Topics

  1. How to Write a Emacs Major Mode for Syntax Coloring
  2. Emacs Lisp: html6-mode
  3. Emacs Lisp: Font Lock Mode Basics
  4. Emacs Lisp: How to Define Face
  5. Emacs Lisp: How to Color Comment in Major Mode
  6. Emacs Lisp: How to Write Comment Command in Major Mode
  7. Emacs Lisp: How to Write Your Own Comment Command from Scratch
  8. Emacs Lisp: How to Write Keyword Completion Command
  9. Emacs Lisp: How to Create Keymap for Major Mode
  10. Emacs Lisp: Create Abbrev and Templates for Major Mode
  11. Emacs Lisp: Overlay Highlighting
  12. Emacs: Lookup Google, Dictionary, Documentation

  1. Emacs Lisp: How to Name Your Major Mode
  2. Emacs Lisp: What's “feature”?
  3. Emacs Lisp: require, load, load-file, autoload, feature, Explained

Syntax Table

  1. Emacs Lisp: Syntax Table Tutorial
  2. Emacs Lisp: How to Find Syntax of a Character?
  3. Emacs Lisp: How to Modify Syntax Table Temporarily
  4. Emacs Lisp: How to Determine If Cursor is Inside String or Comment
  5. Emacs Lisp: Find Matching Bracket Character

Now, continue to Emacs Lisp: How to Write Comment Command in Major Mode

Like it? Buy Xah Emacs Tutorial. Thanks.