I'm trying to highlight
variable-type in custom
let-like form that looks like:
(mylet ((<variable-type> <variable-name> <variable-value>) (...)) <some-forms>)
To do so I wrote
(defun my/highlight-function (bound) (when (re-search-forward (rx (: "mylet" (? "*"))) bound 'noerror) (ignore-errors (let* ((pnt (point)) (begin (+ (match-end 0) 1)) (end (scan-sexps pnt 1))) (when (and end (not (eql pnt end))) (let ((res (map-sorts (buffer-substring-no-properties begin end) begin))) (when res (store-match-data res) t))))))) (font-lock-add-keywords nil '((my/highlight-function . font-lock-type-face)))
that 'returns' (saving with a
store-match-data) a list of pairs of positions (starting and ending) for each variable type to be highlighted.
I am using
store-match-data to store the match results since I haven't found a way to use regular expressions directly for my task.
Matching function (actually, out of scope of this question):
(defun find-sorts (text) (let ((pos 0) (separators '(?\s ?\( ?\))) (depth 0) (first-name nil) (name) (names)) (dolist (sym (coerce text 'list)) (when (member sym separators) (setq first-name nil) (when name (push pos name) (push name names) (setq name nil))) (when (eql sym ?\() (setq first-name t) (incf depth)) (when (eql sym ?\)) (setq first-name t) (decf depth)) (when (and first-name (eql depth 2) (not name) (not (member sym separators))) (push pos name)) (incf pos)) names))
According to source
match-data has following format
'(full-match-start full-match-end group1-start group1-end ...)
find-sorts wrapper (
map-sorts) transforms data to a required format:
(defun map-sorts (text begin) (unless (or (equalp text "()") (equalp text "")) (let ((v (find-sorts text))) (append (list (+ begin (second (first (last v)))) (+ begin (first (first v)))) (reduce #'append (reverse (mapcar (λ (pair) (list (+ begin (second pair)) (+ begin (first pair)))) v)))))))
At this stage, it turns out that the variable names are stored in separate 'regexp' groups
So the question is:
font-lock-add-keywords can highlight all matched groups, not just specified ones or only full matching?
Or is there any other way to highlight a similar structural forms other than with one rule?
Even though this (see code below) works, I'm still hoping to find a more elegant solution...
(font-lock-add-keywords nil '((my/highlight-function (1 font-lock-type-face) (2 font-lock-type-face) .... (8 font-lock-type-face) (9 font-lock-type-face)))
Сouldn't find anything in the documentation about this. Maybe someone else faced such a problem