Yu Shen discusses a completely different case in the comments. The specified syntax is not parsed by a simple parser (see, for example, syntax-ppss ). You need to define one native font lock handler (preferably jit-lock ).
There is a particular problem in this task. It is necessary to determine when the user has finished entering the character, otherwise each part of the character will be registered in the dictionary and get its own color. The code below checks to see if the point is outside the character. If you enter a space after the character, the character lights up.
The code below is only an approximate implementation of one of the possible solutions. Other, perhaps better solutions exist.
(defvar tag-font-lock-dict (make-hash-table: test 'equal)
"Dictionary that assigns colors to tags.")
(make-variable-buffer-local 'tag-font-lock-dict)
(defvar tag-font-lock-re "# [[: alnum:]] + \\>"
"Regular expression defining tags.")
(defvar tag-font-lock-colors (apply 'vector (cdddr (defined-colors)))
"Vector of available colors. We should be more selective here.")
(defvar tag-font-lock-num-used-colors 0
"Number of used colors.")
(make-variable-buffer-local 'tag-font-lock-num-used-colors)
(require 'cl)
(defun tag-font-lock-next-color ()
"Get the next color for a new tag."
(prog1
(aref tag-font-lock-colors tag-font-lock-num-used-colors)
(setq tag-font-lock-num-used-colors
(mod (1+ tag-font-lock-num-used-colors)
(length tag-font-lock-colors)))))
(defun tag-font-lock-handler (be)
"Colorize tags in region from b to e."
(let (col ol sym (pt (point)))
(save-excursion
(remove-overlays be 'tag-font-lock t) ;; No danger of splitted overlays. We have always full lines.
(goto-char b)
(while (re-search-forward tag-font-lock-re e 'noErr)
(when (or (= pt (match-end 0)))
(setq sym (match-string-no-properties 0)
ol (make-overlay (match-beginning 0) (match-end 0))
col (or (gethash sym tag-font-lock-dict)
(puthash sym (tag-font-lock-next-color) tag-font-lock-dict)))
(overlay-put ol 'face (list (list: foreground col)))
(overlay-put ol 'tag-font-lock t)
)))))
(defun tag-font-lock-clear ()
"Remove color from tags in current buffer."
(interactive)
(remove-overlays 0 (buffer-size) 'tag-font-lock t)
(clrhash tag-font-lock-dict))
(define-minor-mode tag-font-lock-mode
"Highlight tags."
: lighter "TH" ;; stands for tag highlight
(if tag-font-lock-mode
(progn
(setq font-lock-extend-region-functions' font-lock-extend-region-wholelines)
(font-lock-mode 1)
(jit-lock-register 'tag-font-lock-handler))
(jit-lock-unregister 'tag-font-lock-handler)
(tag-font-lock-clear)))
source share