I am defining an Emacs major mode by deriving from prog-mode. Font-locking works except for one thing:
I'd like to highlight a special comment type that contains special linker directives, using a font different from the one used for regular comments. Regular comments start with ";" whereas the linker directives have the form ";<...directive...>". And of course, text in strings should not be misidentified as comments.
What I have so far is:
;; define syntax highlighting
(setq p18-font-lock-defaults
`(
;; strings
("\"\\.\\*\\?" . font-lock-string-face)
;; linker directives
("^ *;<.+>.*$" . font-lock-preprocessor-face)
;; mnemonics
( , p18-mnemonics-regexp . font-lock-keyword-face)
)
)
;; define derived mode
(define-derived-mode p18-mode prog-mode "P18"
"...mode description..."
;; define syntax highlighting
(set (make-local-variable 'font-lock-defaults)
'(p18-font-lock-defaults nil t))
;; comments
(setq comment-start ";")
(setq comment-end "")
;; === works when comments start with "; "
;; (modify-syntax-entry ?; ". 1" p18-mode-syntax-table)
;; (modify-syntax-entry 32 ". 2" p18-mode-syntax-table)
;; (modify-syntax-entry ?\n ">" p18-mode-syntax-table)
;; ugly incomplete hack works for comments with ASCII code of
;; second char ?\;
;; (modify-syntax-entry ?; ". 1" p18-mode-syntax-table)
;; (modify-syntax-entry '(?= . 127) ". 2" p18-mode-syntax-table)
;; (modify-syntax-entry ?\n ">" p18-mode-syntax-table)
)
The problem is that with the syntax-table entry this mechanisms classifies everything that starts with ; as comment. The linker directive regexp therefore is not effective anymore.
How can I achieve the desired behaviour? It seems I'd need a pattern that allows checks the chars that follow. But then using the syntax table for comment detection seems nice because it handles strings correctly.
More generally, I am interested in a document that explains the "architecture" of emacs/elisp (e.g. modes and what sequence of operations work for font-locking. Same for buffer interaction). I have the elisp reference manual which is great but I miss a conceptual intro to these topics. I have read the emacs elisp intro but did not like it because I found it too "tutorial-style", very lengthy and repetitive, and missing systematic coverage. For example, there was not a sentence about backquoting. It also seemed to address people with zero programming experience - but would one start with elisp then?
You want to use font-lock-syntactic-face-function
to distinguish which kind of comment gets which face. E.g. something like
(defun my-font-lock-syntactic-face-function (ppss)
(if (and (nth 8 ppss)
(save-excursion
(goto-char (nth 8 ppss))
(looking-at ";<.+>")))
'font-lock-preprocessor-face
(funcall (default-value 'font-lock-syntactic-face-function) ppss)))
...
(define-derived-mode ...
...
(set (make-local-variable 'font-lock-syntactic-face-function)
#'my-font-lock-syntactic-face-function)
...