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 my/highlight-function
:
(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:
whether 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