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.
(progn ;; python style comment: # ... (set-syntax-table (make-syntax-table)) (progn ;; clear the comment syntax of standard syntax table (modify-syntax-entry ?# ".") (modify-syntax-entry ?\n ".")) (modify-syntax-entry ?# "<") (modify-syntax-entry ?\n ">") (font-lock-fontify-buffer)) (progn ;; C++ style comment // ... (set-syntax-table (make-syntax-table)) (progn ;; clear the comment syntax of standard syntax table (modify-syntax-entry ?# ".") (modify-syntax-entry ?\n ".")) (modify-syntax-entry ?\/ ". 12b") (modify-syntax-entry ?\n "> b") (font-lock-fontify-buffer)) (progn ;; comment style /* ... */ ;; this is the original comment style of C (set-syntax-table (make-syntax-table)) (progn ;; clear the comment syntax of standard syntax table (modify-syntax-entry ?# ".") (modify-syntax-entry ?\n ".")) (modify-syntax-entry ?\/ ". 14") (modify-syntax-entry ?* ". 23") (font-lock-fontify-buffer)) (progn ;; comment style /* ... */ and // ... (set-syntax-table (make-syntax-table)) (progn ;; clear the comment syntax of standard syntax table (modify-syntax-entry ?# ".") (modify-syntax-entry ?\n ".")) (modify-syntax-entry ?\/ ". 124") (modify-syntax-entry ?* ". 23b") (modify-syntax-entry ?\n ">") (font-lock-fontify-buffer)) (progn ;; Wolfram Language style comment (* ... *) ;; can nest (set-syntax-table (make-syntax-table)) (progn ;; clear the comment syntax of standard syntax table (modify-syntax-entry ?# ".") (modify-syntax-entry ?\n ".")) (modify-syntax-entry ?\("()1n") (modify-syntax-entry ?\) ")(4n") (modify-syntax-entry ?* ". 23n") (font-lock-fontify-buffer)) ;; HHHH------------------------------ ;; todo. this does not work correctly (progn ;; PowerShell comment <# ... #> and # comment ;; the block comment cannot nest (set-syntax-table (make-syntax-table)) (progn ;; clear the comment syntax of standard syntax table (modify-syntax-entry ?# ".") (modify-syntax-entry ?\n ".")) ;; comment <# ... #> and #... (modify-syntax-entry ?< ". 1" xsynTable) (modify-syntax-entry ?> ". 4" xsynTable) (modify-syntax-entry ?# "< 23b" xsynTable) (modify-syntax-entry ?\n ">" xsynTable) (font-lock-fontify-buffer))
-*- coding: utf-8; mode: fundamental -*- 2024-11-30 test comment coloring. save this in a file as test.txt close and open it. then, eval emacs lisp code that sets current syntax table to see color changes for comment # python line comment // java line comment /* java block comment */ (* Wolfram language comment. (* can be (* nested *) *) *) <# PowerShell block 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 more complex comment syntax, set up the Text Property for the key 'syntax-table
.
see
- syntax-propertize-function
- Syntax Properties (ELISP Manual)
Emacs Lisp, 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
- Emacs: Command to Search Web 🚀
- Elisp: Create a Hook
- Elisp: Major Mode Names
- Elisp: provide, require, features
- Elisp: load, load-file, autoload
- Elisp: Syntax Table