0

While there are packages that handle this, I would like to highlight a single word in source code comments, using for example the warning face, when a function call returns t, using the word as input.

How would this be achieved?

4
  • 1
    How is static analysis (the regex kind) supposed to know what a function call returns?
    – wasamasa
    Commented Apr 2, 2020 at 6:48
  • 1
    There are many packages that do similar things, e.g. my doxygen package: github.com/Lindydancer/highlight-doxygen . Can you give an example of how the comment and code looks like? Commented Apr 2, 2020 at 8:47
  • In which programming language is the source code written? What function should return t? An Elisp function that gets some context information and gets called from font-lock or a function from the source code that is called in the program the source code belongs to? Is the program run in a debugger?
    – Tobias
    Commented Apr 2, 2020 at 18:51
  • Misunderstanding, clarifying the question.
    – ideasman42
    Commented Apr 2, 2020 at 23:03

1 Answer 1

2

First study the doc-string of font-lock-keywords. There you have MATCHER which can be a regexp but also can be a function that is called with one arg and should act like re-search-forward.

In the MATCHER function you have the chance to consider other conditions, as that one that your function that should return t.

You can use the form (MATCHER . (SUBEXP FACENAME OVERRIDE)) for the keyword entry and append it to font-lock-keywords with the help of font-lock-add-keywords.

Example:

(defun my-highlight-fixme-p (s)
  "Example predicate function for `my-highlight-mode'."
  (string-equal s "FIXME"))

(defvar my-highlight-regexp (regexp-opt '("FIXME" "TODO") 'words)
  "Regexp matching in comments.")

(defvar my-highlight-predicate #'my-highlight-fixme-p
  "Register your predicate function here.")

(defvar my-highlight-keywords '((my-highlight-highlight
                 .
                 (
                  0 ;; subexpression
                  'warning ;; facename
                  t ;; override syntactic fontification for comments
                  )))
  "One of the possible constructs of keywords in `font-lock-keywords'.
The HIGHLIGHT element of the keyword should always be `my-highlight-highlight'.")

(defun my-highlight-highlight (bound)
  "MATCHER for the font lock keyword in `my-highlight-mode'."
  (let (found)
    (while (and
        (setq found (re-search-forward my-highlight-regexp bound t))
        (null
         (and (nth 4 (syntax-ppss)) ;;  inside comment?
          (funcall my-highlight-predicate (match-string 0))))))
    found))

(define-minor-mode my-highlight-mode
  "Highlight matches for `my-highlight-regexp' in comments
if they also fulfill `my-highlight-predicate'."
  :lighter " κ"
  (if my-highlight-mode
      (font-lock-add-keywords nil my-highlight-keywords 'append) ;; append and override
    (font-lock-remove-keywords nil my-highlight-keywords))
  (font-lock-flush))
3
  • my-highlight-highlight should loop until it finds a suitable match, or reach bound. If not, it will stop after the first occurrence of warning. Commented Apr 3, 2020 at 9:12
  • @Lindydancer Better so?
    – Tobias
    Commented Apr 3, 2020 at 10:03
  • Yes, this looks right! Commented Apr 3, 2020 at 11:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.