Elisp: Syntax Color Comments
Problem
You are writing a major mode for a language. You want comment be syntax colored.
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:
- Set Syntax Table for the comment characters.
- 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.
Example | Syntax 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:
- Use Search-based Fontification of
font-lock-mode
to color comment. See Font Lock Mode (ELISP Manual) - Write your own parser, then use text properties to color them. 〔see Elisp: Text Properties〕
Elisp, font lock, syntax coloring
Emacs lisp, writing a major mode. Essentials
- Elisp: Write a Major Mode for Syntax Coloring
- Elisp: Font Lock Mode
- Elisp: Syntax Color Comments
- Elisp: Write Comment/Uncomment Command
- Elisp: Keyword Completion
- Elisp: Create Keymap (keybinding)
- Elisp: Create Function Templates
- Elisp: Command to Lookup Doc
- Elisp: Create a Hook
- Elisp: Major Mode Names
- Elisp: provide, require, features
- Elisp: load, load-file, autoload
- Elisp: Syntax Table