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?

  • 1
    How is static analysis (the regex kind) supposed to know what a function call returns? – wasamasa Apr 2 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? – Lindydancer Apr 2 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 Apr 2 at 18:51
  • Misunderstanding, clarifying the question. – ideasman42 Apr 2 at 23:03
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))
| improve this answer | |
  • 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. – Lindydancer Apr 3 at 9:12
  • @Lindydancer Better so? – Tobias Apr 3 at 10:03
  • Yes, this looks right! – Lindydancer Apr 3 at 11:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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