6

I'm developing a major mode for a language that has doc comments. They look like this:

(** Foos three bars.
    Better call this as [foo 1 b c].
    Though of course [foo a b 1] works as well. **)
Definition foo a b c := a + b - c.

In that context [ and ] work as sorts of unescapes: anything between them is really code, not comments.

Is there a generic approach this? IOW, is there a way to tell font-lock: in comments, treat anything between [] as code?

I can see a bunch of cool applications for this beyond my major mode: for example doctests in python (where >>> should introduce code), or javadoc, or doxygen, etc.

"""Foos the bars
>>> foo 1 2 3 # should be highlighted as code
0
>>> foo 4 5 6 # should be highlighted as code
3"""

I considered making [ a comment closer, and ] a comment opener, but it looks very brittle: it will confuse navigation commands, and nested comments, and will require a strange comment setup to allow multiple closers per opener; and it won't work outside of comments, either.

Clément
  • 3,924
  • 1
  • 22
  • 37
  • In a way, all font-lock rules apply both to comments and non-comments. The fact that they isn't rendered in a comment because a normal rule don't have an OVERRIDE flag. If you add `prepend` to the rule, it will add it's highlight on top of the comment face. – Lindydancer Feb 17 '16 at 08:52
  • @Lindydancer: Indeed; only I'm not aware of a way to make the flag conditional, i.e. make it `prepend` only in `[]` pairs in comments. – Clément Feb 17 '16 at 14:49
  • You can replace the regexp with a function, in that function you can search for the regexp using `re-search-forward` and skip those cases where the context is wrong. The answer http://emacs.stackexchange.com/questions/20222/part-ii-colorizing-functions-variables-within-comments-in-c-mode/20228#20228 does something similar (the condition in this case is that something should be highlighted in comments only). – Lindydancer Feb 17 '16 at 15:02
  • @Lindydancer: I'm aware of this, but I don't see how it applies here; is your suggestion to duplicate all font-lock keywords and have one copy for code blocks in comments (with `'prepend` and a custom function), and another copy for regular code? – Clément Feb 17 '16 at 16:57
  • There is no need to duplicate the rules, just use the condition that the text either is outside of comments or enclosed in brackets in a comment. – Lindydancer Feb 17 '16 at 17:49
  • @Lindydancer I don't think that works: it will require adding a `prepend` to every rule, which will break rules that already depend on `prepend` and `append`. Won't it? – Clément Feb 17 '16 at 19:25
  • Yes, that's true... I just came up with another approach. You can add a "fake" rule that removes the `font-lock-comment-face` from bracket-enclosed areas. Subsequent rules will highlight normally. – Lindydancer Feb 17 '16 at 20:44
  • ... after giving it some thought I realised that this wasn't a good idea after all. Strings won't be highlighted, for example. OK, back to the drawing boards. What about taking your idea of making `]` a comment ender and `[` a comment start character, but implement this using a `syntax-propertize-function`, that only do this inside comments only? – Lindydancer Feb 18 '16 at 05:37
  • @Lindydancer: That will confuse code that uses `comment-forward` and the like :/ – Clément Feb 18 '16 at 18:25
  • Try doing something like what `lisp-font-lock-syntactic-face-function` does (in `lisp-mode.el`). It font-locks comments using syntactic font-lock, but it recognizes ` ... ' syntax within comments and highlights them with a different face. It sounds like you want to do that, but in your case the second highlighting is for `[...]`. – Drew Aug 15 '16 at 01:00
  • @Drew: This isn't enough: I need full-fledged highlighting, not just uniform highlighting of `[...]` blocks. – Clément Aug 22 '16 at 00:39
  • Perhaps someone else will offer a solution. Maybe @Stefan can help here. – Drew Aug 22 '16 at 00:54

0 Answers0