9

In clojure, the comment character is ;. clojure-mode syntax highlighting + color scheme greys comment text out.

I want emacs to color lines that begin with ;-; with a different color.

For example:

;; This is a normal greyed out comment, we use ;; by convention for blocks.
;  This is a typical grey inline comment, we use ; by convention.

;-; This is recognized as a comment and is normally greyed out.
;-; I want emacs to recognize this as something a little different and give
;-; it a different color.

How can I achieve this?

Drew
  • 75,699
  • 9
  • 109
  • 225
deadghost
  • 807
  • 1
  • 7
  • 13

3 Answers3

8

This is what I ended up going with:

(defface special-comment '((t (:foreground "#2aa198"))) "Cyan")

(font-lock-add-keywords
 'clojure-mode '((";-;.*" 0 'special-comment t)))

";-;.*" is regex. 0 matches the entire expression. t overrides existing highlights.

More info on font-lock-add-keywords can be found here: https://www.gnu.org/software/emacs/manual/html_node/elisp/Search_002dbased-Fontification.html. Of note is the (matcher . subexp-highlighter) section.

deadghost
  • 807
  • 1
  • 7
  • 13
  • 3
    The basic approach is sound, however, one problem with this is that it matches `;-;` in any context, including inside a string. If you replace the regexp with a function that perform a search for `;-;` and ignore matches in the wrong context you should have a working solution. – Lindydancer Oct 31 '16 at 20:16
2

You want to customize font-lock-syntactic-face-function.

The function stored in that variable is called for every string and comment to decide which face to use for it. Of course, you'll want to set it buffer-locally. It receives as argument a ppss, i.e. the return value of syntax-ppss at the current position, so you can figure out whether you're inside a string by checking (nth 3 ppss) or inside a comment with (nth 4 ppss) and you get to know where that string or comment started with (nth 8 ppss), so you can go check whether it started with ;-; or something else.

Stefan
  • 26,154
  • 3
  • 46
  • 84
1

You can use overlay for this. You'll need to search for the ;-; to end of line, then put overlay to it.

Here's full code.

(defun my-make-overlay-bold-region (*begin *end)
  "make the region bold, using overlay.
Calls `make-overlay' and `overlay-put'. This:
 (overlay-put (make-overlay *begin *end) 'face 'bold)"
  (interactive "r")
  (progn
    (overlay-put (make-overlay *begin *end) 'face 'bold)
    (setq mark-active nil )))

(defun my-remove-overlays-region (*begin *end)
  "Call `remove-overlays' interactively.
Call (remove-overlays *begin *end)"
  (interactive "r")
  (remove-overlays *begin *end))

(defun my-color-special-comment ()
  "highlight text beging with ;-; to end of line."
  (interactive)
  (let (p1 p2)
    (save-excursion
      (goto-char (point-min))
      (while (search-forward ";-;" )
        (left-char 3)
        (setq p1 (point) p2 (line-end-position))
        (goto-char p2)
        (my-make-overlay-bold-region p1 p2)))))

(add-hook 'clojure-mode-hook 'my-color-special-comment)

politza
  • 3,316
  • 14
  • 16
Xah Lee
  • 1,756
  • 12
  • 11
  • 2
    This isn't the best way: it won't catch new comments of this kind automatically (unless you add it to post-command/after-change hook, but traversing the whole buffer every time could be quite slow for larger files, and being more efficient would require more complexity than the other solutions). Also, it matches `;-;` inside strings too (I think Stefan's suggestion of `syntax-ppss` is the only way around this). – npostavs Oct 31 '16 at 16:26
  • 1
    you are right. It's a poor man's method. @Stefan's answer is proper. I'd hope if he adds code. – Xah Lee Nov 01 '16 at 02:48