Reputation: 31141
I'm trying to write a simple major mode for a lisp dialect. Here's my mode:
(defconst example-font-lock-keywords
(list
`(";.*" . font-lock-comment-face)
`(,(regexp-opt '("function" "macro") 'symbols) . font-lock-builtin-face)
`("\"[^\"]+?\"" . font-lock-string-face))
"Highlighting for Example mode.")
(defvar example-mode-syntax-table
(make-syntax-table))
(define-derived-mode example-mode lisp-mode "Example"
"Major mode for editing Example lisp code."
:syntax-table example-mode-syntax-table
(set (make-local-variable 'font-lock-defaults) '(example-font-lock-keywords)))
Here's my sample program:
; Highlighting tests.
; This is a comment despite "quotes"
(function foo () "bar")
Here's the result I'm seeing:
What am I doing wrong? Why does the string regexp 'win' against the comment regexp?
Upvotes: 2
Views: 505
Reputation: 26094
Emacs highlights a buffer in two phases. The first is the syntactic phase, which is based on information found in the syntax table, which typically highlights strings and comments. The second is the keyword phase.
In your case, the default syntax table sets up double quotes to mean string. The effect is that before your keywords are executed, the strings are already highlighted. By default, a keyword is only applied when there is no highlighting in the matched content, which is the reason why your comment keyword only works on lines without strings. (See the OVERRIDE
flag in the help text of font-lock-keywords
for details on overriding.)
The best solution for you is to update the syntax table so that ; means "comment start", and then drop the comment and string rules from your set of keywords.
Upvotes: 3
Reputation: 30701
Try ("\"[^\"]+?\"" 0 font-lock-string-face keep t)
.
Or reverse the order of the two entries (for font-lock-comment-face
and font-lock-string-face
).
See the Elisp manual, node Search-based Fontification
-- look for OVERRIDE
for an explanation of keep
.
Upvotes: 1