I have a programming language I want to make a major mode for where both the start and the end characters of a comment are the same. Specifically #.

This is a comment

As you can see it can match either multiple lines as well as single lines. Single lines are no problem, that can be done with this regex in a font-lock-defaults block: "#\\([^#]*?\\)#.

However the problem occurs on multiple line comments. Due to the start and the end being the same Emacs sometimes misjudges which part of the code is actually a comment, especially if one part of the comment is off-screen.

This is a comment and should always be recognized
This isn't a comment but is sometimes recognized if the top is off screen
This is a comment and is always recognized but sometimes isn't if the last block is wrongly detected as a comment

I've also tried this code set as the syntax-propertize-function

(defconst amanatsu-comment-regex
 "\\(#\\([^#]*?\\)#\\)" )
(defun amanatsu-syntax-propertize-function (start end)
    (goto-char start)
    (while (re-search-forward amanatsu-comment-regex end 'noerror)
      (let ((a (match-beginning 1))
            (b (match-end 1))
            (comment-fence (string-to-syntax "!")))
        (put-text-property a (1+ a) 'syntax-table comment-fence)
        (put-text-property (1- b) b 'syntax-table comment-fence)))))

but this occasionally suffers the same off-screen errors.


1 Answer 1


font-lock typically highlights chunks of your buffer at a time. Each line is a couple of lines long.

You can solve this in (at least) two ways:

  1. Expand the region that font-lock highlights by defining your own font-lock-extend-region-functions.

  2. Ensure that your syntax propertize function works even if start and end happens to be in the middle of a comment block.

To visually see how font-lock refontifies a buffer, you can use the package highlight-refontification.

An example of a package that use font-lock-extend-region-functions is highlight-doxygen.

  • I'm sorry I'm quite new to Emacs, how could I implement this? Mar 30, 2022 at 19:22
  • You can bind a function to the variable font-lock-extend-region-function. This function is called whenever font-lock is about to highlight a few lines. It can extend these lines so that a larger area is rehighlighted. It does this by setting font-lock-beg and font-lock-end. For an example, see highlight-doxygen-extend-region-full-comment in the highlight-doxygen package I mentioned in the answer. Mar 30, 2022 at 20:01

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.